UNPKG

@itwin/core-backend

Version:
144 lines 6.27 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 Schema */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Schemas = exports.SchemaMap = exports.Schema = void 0; const core_bentley_1 = require("@itwin/core-bentley"); const core_common_1 = require("@itwin/core-common"); const ClassRegistry_1 = require("./ClassRegistry"); const ecschema_metadata_1 = require("@itwin/ecschema-metadata"); /** Base class for all schema classes - see [working with schemas and elements in TypeScript]($docs/learning/backend/SchemasAndElementsInTypeScript.md). * * When subclassing from Schema, it is good practice to follow this pattern: * * ```typescript * class MyCustomSchema extends Schema { * public static override get schemaName(): string { return "MyCustomSchema"; } * public static get classes(): typeof Entity[] { * return [MyOwnECClass, AnotherECClass]; * } * public static registerSchema() { * if (this !== Schemas.getRegisteredSchema(this.schemaName)) { * Schemas.unregisterSchema(this.schemaName); * Schemas.registerSchema(this); * for (const ecClass of this.classes) { * ClassRegistry.register(ecClass, this); * } * } * } * * public static unregisterSchema() { * Schemas.unregisterSchema(this.schemaName); * } * } * ``` * * @public */ class Schema { /** The name of the BIS schema handled by this Schema. * @note Every subclass of Schema ** MUST ** override this method to identify its BIS schema. * Failure to do so will ordinarily result in an error when the schema is registered, since there may only * be one JavaScript class for a given BIS schema (usually the errant schema will collide with its superclass.) */ static get schemaName() { throw new Error(`you must override static schemaName in ${this.name}`); } /** Unique identifier for this schema, typed variant of [[schemaName]]. * @internal */ static get schemaKey() { // We cannot cache this here because the schemaName may be overridden without this being overridden return new ecschema_metadata_1.SchemaKey(this.schemaName, ecschema_metadata_1.ECVersion.NO_VERSION); // backend cares little for versions right now, as only one version can exist in an imodel } /** if true, this Schema is a proxy for a missing Domain marked with the `BisCore.SchemaHasBehavior` customAttribute. * Classes generated for this Schema will disallow protected operations. * @internal */ static get missingRequiredBehavior() { return false; } /** Get a semver-compatible string from a padded version string. * works on unpadded version strings as well * if there is no write version, it will be added * @example Schema.toSemverString("1.02.03") === "1.2.3" * @example Schema.toSemverString("1.01") === "1.0.1" // write version was added * @beta */ static toSemverString(paddedVersion) { const tuple = paddedVersion.split(".").map(Number); const noWriteVersion = tuple.length === 2; if (noWriteVersion) tuple.splice(1, 0, 0); // insert 0 before the second element return tuple.join("."); } /** Schemas may not be instantiated. The method is not private only because that precludes subclassing. It throws an * error if it is ever called. * @internal */ constructor() { throw new Error(`cannot create an instance of a Schema ${this.constructor.name}`); } } exports.Schema = Schema; /** * Holds a map of registered schemas. * @public */ class SchemaMap { _schemas = new Map(); /** @internal */ get(schemaName) { return this._schemas.get(schemaName.toLowerCase()); } /** @internal */ set(schemaName, schema) { this._schemas.set(schemaName.toLowerCase(), schema); } /** @internal */ delete(schemaName) { return this._schemas.delete(schemaName.toLowerCase()); } /** Register a schema prior to using it. * @throws [[IModelError]] if a schema of the same name is already registered. * @public */ registerSchema(schema) { const key = schema.schemaName.toLowerCase(); if (this.get(key)) throw new core_common_1.IModelError(core_bentley_1.IModelStatus.DuplicateName, `Schema "${schema.schemaName}" is already registered`); this.set(key, schema); } } exports.SchemaMap = SchemaMap; /** Manages registered schemas * @public */ class Schemas { static _globalSchemas = new SchemaMap(); constructor() { } // this is a singleton /** Register a schema prior to using it. * This method registers the schema globally, to register a schema within the scope of a single iModel, use `IModelDb.schemaMap`. * @throws [[IModelError]] if a schema of the same name is already registered. */ static registerSchema(schema) { this._globalSchemas.registerSchema(schema); } /** Unregister a schema, by name, if one is already registered. * This function is not normally needed, but is useful for cases where a generated *proxy* schema needs to be replaced by the *real* schema. * @param schemaName Name of the schema to unregister * @return true if the schema was unregistered */ static unregisterSchema(schemaName) { const schema = this.getRegisteredSchema(schemaName); if (undefined !== schema) ClassRegistry_1.ClassRegistry.unregisterClassesFrom(schema); return this._globalSchemas.delete(schemaName.toLowerCase()); } /** Look up a previously registered schema * @param schemaName The name of the schema * @returns the previously registered schema or undefined if not registered. */ static getRegisteredSchema(schemaName) { return this._globalSchemas.get(schemaName.toLowerCase()); } } exports.Schemas = Schemas; //# sourceMappingURL=Schema.js.map