UNPKG

@itwin/core-backend

Version:
213 lines • 10.9 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module ElementAspects */ Object.defineProperty(exports, "__esModule", { value: true }); exports.ExternalSourceAspect = exports.ChannelRootAspect = exports.ElementMultiAspect = exports.ElementUniqueAspect = exports.ElementAspect = void 0; const core_common_1 = require("@itwin/core-common"); const Entity_1 = require("./Entity"); const core_bentley_1 = require("@itwin/core-bentley"); const Symbols_1 = require("./internal/Symbols"); /** An Element Aspect is a class that defines a set of properties that are related to (and owned by) a single element. * Semantically, an ElementAspect can be considered part of the Element. Thus, an ElementAspect is deleted if its owning Element is deleted. * BIS Guideline: Subclass ElementUniqueAspect or ElementMultiAspect rather than subclassing ElementAspect directly. * @public @preview */ class ElementAspect extends Entity_1.Entity { static get className() { return "ElementAspect"; } element; /** Construct an aspect from its JSON representation and its containing iModel. */ constructor(props, iModel) { super(props, iModel); this.element = core_common_1.RelatedElement.fromJSON(props.element); // eslint-disable-line @typescript-eslint/no-non-null-assertion } toJSON() { const val = super.toJSON(); val.element = this.element; return val; } /** Called before a new ElementAspect is inserted. * @note throw an exception to disallow the insert * @note If you override this method, you must call super. * @beta */ static onInsert(arg) { const { props, iModel } = arg; iModel.channels[Symbols_1._verifyChannel](arg.model); iModel.locks.checkExclusiveLock(props.element.id, "element", "insert aspect"); } /** Called after a new ElementAspect was inserted. * @note If you override this method, you must call super. * @beta */ static onInserted(_arg) { } /** Called before an ElementAspect is updated. * @note throw an exception to disallow the update * @note If you override this method, you must call super. * @beta */ static onUpdate(arg) { const { props, iModel } = arg; iModel.channels[Symbols_1._verifyChannel](arg.model); iModel.locks.checkExclusiveLock(props.element.id, "element", "update aspect"); } /** Called after an ElementAspect was updated. * @note If you override this method, you must call super. * @beta */ static onUpdated(_arg) { } /** Called before an ElementAspect is deleted. * @note throw an exception to disallow the delete * @note If you override this method, you must call super. * @beta */ static onDelete(arg) { const { aspectId, iModel } = arg; iModel.channels[Symbols_1._verifyChannel](arg.model); const { element } = iModel.elements.getAspect(aspectId); iModel.locks.checkExclusiveLock(element.id, "element", "delete aspect"); } /** Called after an ElementAspect was deleted. * @note If you override this method, you must call super. * @beta */ static onDeleted(_arg) { } } exports.ElementAspect = ElementAspect; /** An Element Unique Aspect is an ElementAspect where there can be only zero or one instance of the Element Aspect class per Element. * @public @preview */ class ElementUniqueAspect extends ElementAspect { static get className() { return "ElementUniqueAspect"; } } exports.ElementUniqueAspect = ElementUniqueAspect; /** An Element Multi-Aspect is an ElementAspect where there can be **n** instances of the Element Aspect class per Element. * @public @preview */ class ElementMultiAspect extends ElementAspect { static get className() { return "ElementMultiAspect"; } } exports.ElementMultiAspect = ElementMultiAspect; /** * @public @preview */ class ChannelRootAspect extends ElementUniqueAspect { static get className() { return "ChannelRootAspect"; } /** Insert a ChannelRootAspect on the specified element. * @deprecated in 4.0 - will not be removed until after 2026-06-13. Use [[ChannelControl.makeChannelRoot]]. This method does not enforce the rule that channels may not nest and is therefore dangerous. */ static insert(iModel, ownerId, channelName) { const props = { classFullName: this.classFullName, element: { id: ownerId }, owner: channelName }; iModel.elements.insertAspect(props); } } exports.ChannelRootAspect = ChannelRootAspect; /** An ElementMultiAspect that stores synchronization information for an Element originating from an external source. * @note The associated ECClass was added to the BisCore schema in version 1.0.2 * @public @preview */ class ExternalSourceAspect extends ElementMultiAspect { static get className() { return "ExternalSourceAspect"; } /** An element that scopes the combination of `kind` and `identifier` to uniquely identify the object from the external source. * @note Warning: in a future major release the `scope` property will be optional, since the scope is intended to be potentially invalid. * all references should treat it as potentially undefined, but we cannot change the type yet since that is a breaking change. */ scope; /** The identifier of the object in the source repository. */ identifier; /** The kind of object within the source repository. */ kind; /** The cryptographic hash (any algorithm) of the source object's content. If defined, it must be guaranteed to change when the source object's content changes. */ checksum; /** An optional value that is typically a version number or a pseudo version number like last modified time. * It will be used by the synchronization process to detect that a source object is unchanged so that computing a cryptographic hash can be avoided. * If present, this value must be guaranteed to change when any of the source object's content changes. */ version; /** A place where additional JSON properties can be stored. For example, provenance information or properties relating to the synchronization process. * @note Warning: in a future major release, the type of `jsonProperties` will be changed to object, and itwin.js will automatically stringify it when writing to the iModel. * This will be a breaking change, since application code will have to change from supplying a string to supplying an object. */ jsonProperties; /** The source of the imported/synchronized object. Should point to an instance of [ExternalSource]($backend). */ source; /** Construct an aspect from its JSON representation and its containing iModel. */ constructor(props, iModel) { super(props, iModel); this.scope = core_common_1.RelatedElement.fromJSON(props.scope); // eslint-disable-line @typescript-eslint/no-non-null-assertion this.source = core_common_1.RelatedElement.fromJSON(props.source); this.identifier = props.identifier; this.kind = props.kind; this.checksum = props.checksum; this.version = props.version; this.jsonProperties = props.jsonProperties; } /** Look up the elements that contain one or more ExternalSourceAspect with the specified Scope, Kind, and Identifier. * The result of this function is an array of all of the ExternalSourceAspects that were found, each associated with the owning element. * A given element could have more than one ExternalSourceAspect with the given scope, kind, and identifier. * Also, many elements could have ExternalSourceAspect with the same scope, kind, and identifier. * Therefore, the result array could have more than one entry with the same elementId. * Aspects are never shared. Each aspect has its own unique ECInstanceId. * @param iModelDb The iModel to query * @param scope The scope of the ExternalSourceAspects to find * @param kind The kind of the ExternalSourceAspects to find * @param identifier The identifier of the ExternalSourceAspects to find * @returns the query results */ static findAllBySource(iModelDb, scope, kind, identifier) { const sql = `SELECT Element.Id, ECInstanceId FROM ${ExternalSourceAspect.classFullName} WHERE (Scope.Id=:scope AND Kind=:kind AND Identifier=:identifier)`; const found = []; // eslint-disable-next-line @typescript-eslint/no-deprecated iModelDb.withPreparedStatement(sql, (statement) => { statement.bindId("scope", scope); statement.bindString("kind", kind); statement.bindString("identifier", identifier); while (core_bentley_1.DbResult.BE_SQLITE_ROW === statement.step()) { found.push({ elementId: statement.getValue(0).getId(), aspectId: statement.getValue(1).getId() }); } }); return found; } toJSON() { const val = super.toJSON(); val.scope = this.scope; val.source = this.source; val.identifier = this.identifier; val.kind = this.kind; val.checksum = this.checksum; val.version = this.version; val.jsonProperties = this.jsonProperties; return val; } collectReferenceIds(referenceIds) { super.collectReferenceIds(referenceIds); if (this.scope) referenceIds.addElement(this.scope.id); referenceIds.addElement(this.element.id); if (this.source) referenceIds.addElement(this.source.id); } } exports.ExternalSourceAspect = ExternalSourceAspect; /** @public @preview */ (function (ExternalSourceAspect) { /** Standard values for the `Kind` property of `ExternalSourceAspect`. * @public @preview */ let Kind; (function (Kind) { /** Indicates that the [[ExternalSourceAspect]] is storing [[Element]] provenance */ Kind["Element"] = "Element"; /** Indicates that the [[ExternalSourceAspect]] is storing [[Relationship]] provenance */ Kind["Relationship"] = "Relationship"; /** Indicates that the [[ExternalSourceAspect]] is storing *scope* provenance * @see [[ExternalSourceAspect.scope]] */ Kind["Scope"] = "Scope"; })(Kind = ExternalSourceAspect.Kind || (ExternalSourceAspect.Kind = {})); })(ExternalSourceAspect || (exports.ExternalSourceAspect = ExternalSourceAspect = {})); //# sourceMappingURL=ElementAspect.js.map