@itwin/core-backend 4.1.0-dev.3 → 4.1.0-dev.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"CodeService.js","sourceRoot":"","sources":["../../src/CodeService.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAE/F,sDAAoG;AAyCpG,aAAa;AACb,IAAiB,WAAW,CA2d3B;AA3dD,WAAiB,WAAW;IA+H1B,gBAAgB;IAChB,MAAM,aAAa,GAAG,IAAI,GAAG,EAAwB,CAAC;IAKtD,8EAA8E;IAC9E,SAAgB,gBAAgB,CAAC,GAAiB;QAChD,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;IAC3C,CAAC;IAFe,4BAAgB,mBAE/B,CAAA;IAED;;OAEG;IACH,SAAgB,WAAW,CAAC,IAAY;QACtC,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG;YACN,MAAM,IAAI,KAAK,CAAC,kBAAkB,EAAE,CAAC,CAAC,EAAE,iBAAiB,IAAI,YAAY,CAAC,CAAC;QAC7E,OAAO,GAAG,CAAC;IACb,CAAC;IALe,uBAAW,cAK1B,CAAA;IAED;;;;;OAKG;IACH,SAAgB,gBAAgB,CAAC,MAAgB,EAAE,IAAe;QAChE,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAC,cAAc,CAAC;QAC/G,IAAI,SAAS,KAAK,SAAS;YACzB,MAAM,IAAI,WAAW,CAAC,KAAK,CAAC,aAAa,EAAE,2BAAY,CAAC,WAAW,EAAE,0CAA0C,CAAC,CAAC;QAEnH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3E,CAAC;IANe,4BAAgB,mBAM/B,CAAA;IAED;;OAEG;IACH,SAAgB,gBAAgB,CAAC,GAAqC;QACpE,OAAO;YACL,GAAG,GAAG,CAAC,KAAK;YACZ,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK;YACrB,GAAG,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC;SAC1C,CAAC;IACJ,CAAC;IANe,4BAAgB,mBAM/B,CAAA;IAoQD,uDAAuD;IACvD,MAAa,KAAM,SAAQ,2BAAY;QAMrC,gBAAgB;QAChB,YAAY,OAAgB,EAAE,MAAc,EAAE,OAAe,EAAE,QAA6C;YAC1G,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;YACvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC3B,CAAC;KACF;IAZY,iBAAK,QAYjB,CAAA;AA+BH,CAAC,EA3dgB,WAAW,GAAX,mBAAW,KAAX,mBAAW,QA2d3B","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { BentleyError, GuidString, IModelStatus, MarkRequired, Mutable } from \"@itwin/core-bentley\";\r\nimport { CodeProps, FontId, FontType } from \"@itwin/core-common\";\r\nimport { CloudSqlite } from \"./CloudSqlite\";\r\nimport { IModelDb } from \"./IModelDb\";\r\nimport { SettingObject } from \"./workspace/Settings\";\r\nimport { VersionedSqliteDb } from \"./SQLiteDb\";\r\n\r\n/**\r\n * The services for querying, reserving, updating, and deleting codes for a BriefcaseDb (available via `BriefcaseDb.codeService`) whenever it is opened for write access.\r\n * See [CodeService]($docs/learning/backend/CodeService).\r\n * @alpha\r\n */\r\nexport interface CodeService {\r\n /** @internal */\r\n close: () => void;\r\n\r\n initialize(iModel: IModelDb): Promise<void>;\r\n\r\n /** the index for external Codes for this CodeService */\r\n readonly externalCodes?: CloudSqlite.DbAccess<CodeService.CodesDb, CodeService.ReadMethods, CodeService.WriteMethods>;\r\n\r\n /** the index for internal Codes for this CodeService */\r\n readonly internalCodes?: CloudSqlite.DbAccess<CodeService.InternalCodes, CodeService.InternalReadMethods, CodeService.InternalWriteMethods>;\r\n\r\n /**\r\n * Application-supplied parameters for reserving new codes.\r\n */\r\n readonly appParams: CodeService.AuthorAndOrigin;\r\n\r\n /**\r\n * Verify that the Code of a to-be-inserted or to-be-updated Element:\r\n * 1. has already been reserved,\r\n * 2. if the element has a `federationGuid`, it must match the reserved value. If the federationGuid is undefined,\r\n * the value from the code index is returned.\r\n *\r\n * If not, throw an exception. Elements with no CodeValue are ignored.\r\n * @note this method is automatically called whenever elements are added or updated by a BriefcaseDb with a CodeService.\r\n */\r\n verifyCode(props: CodeService.ElementCodeProps): void;\r\n}\r\n\r\n/** @alpha */\r\nexport namespace CodeService {\r\n\r\n export interface WriteMethods {\r\n /** Add a new code spec to this code service.\r\n */\r\n addCodeSpec(val: CodeService.NameAndJson): Promise<void>;\r\n\r\n /**\r\n * Add all of the codes and code specs from this CodeService's BriefcaseDb into the code index.\r\n * @returns the number of codes actually added.\r\n * @note It is not necessary to call this method unless the BriefcaseDb somehow becomes out of sync with its CodeService,\r\n * for example when migrating iModels to a new code service. It is safe (but relatively expensive) to call this method multiple times, since\r\n * any codes or code specs that are already in the index are ignored.\r\n */\r\n addAllCodes(iModel: IModelDb): Promise<number>;\r\n\r\n /**\r\n * Attempt to reserve a single proposed code.\r\n * @throws `CodeService.Error` if the proposed code cannot be reserved.\r\n */\r\n reserveCode(code: CodeService.ProposedCode): Promise<void>;\r\n\r\n /**\r\n * Attempt to reserve an array of proposed codes.\r\n * @returns number of codes actually reserved.\r\n * @see the `problems` member of the `CodeService.Error` exception\r\n * @note If you have a set of codes to reserve, it is considerably more efficient to do them as an array rather than one at a time.\r\n * @throws `CodeService.Error` if any of the proposed code cannot be reserved. The details for each failed code are in the `problems` member.\r\n */\r\n reserveCodes(arg: CodeService.ReserveCodesArgs): Promise<number>;\r\n\r\n /**\r\n * Attempt to reserve the next available code for a code sequence and scope.\r\n */\r\n reserveNextAvailableCode(arg: CodeService.ReserveNextArgs): Promise<void>;\r\n\r\n /**\r\n * Attempt to reserve an array of the next available codes for a code sequence and scope.\r\n * The length of the array determines the number of codes requested. The values for the new codes are returned\r\n * in the array, so they can be associated with the supplied GUIDs.\r\n * @returns number of codes actually reserved.\r\n */\r\n reserveNextAvailableCodes(arg: CodeService.ReserveNextArrayArgs): Promise<number>;\r\n\r\n /**\r\n * Update the properties of a single code.\r\n */\r\n updateCode(props: CodeService.UpdatedCode): Promise<void>;\r\n\r\n /**\r\n * Update the properties of an array codes.\r\n * @note If you have a set of codes to update, it is considerably more efficient to do them as an array rather than one at a time.\r\n * @returns number of codes actually updated.\r\n */\r\n updateCodes(arg: CodeService.UpdateCodesArgs): Promise<number>;\r\n\r\n /** Delete an array of codes by their guids. */\r\n deleteCodes(guid: CodeService.CodeGuid[]): Promise<void>;\r\n }\r\n\r\n export interface ReadMethods {\r\n /**\r\n * Find the next available value for the supplied `SequenceScope`.\r\n * If the sequence is full (there are no available values), this will throw an exception with `errorId=\"SequenceFull\"`\r\n * @param from the sequence and scope to search\r\n * @returns the next available CodeValue in the sequence.\r\n */\r\n findNextAvailable(from: CodeService.SequenceScope): CodeService.CodeValue;\r\n\r\n /**\r\n * Find the highest currently used value for the supplied `SequenceScope`\r\n * @param from the sequence and scope to search\r\n * @returns the highest used value, or undefined if no values have been used.\r\n */\r\n findHighestUsed(from: CodeService.SequenceScope): CodeService.CodeValue | undefined;\r\n\r\n /** Determine whether a code is present in this CodeIndex by its Guid. */\r\n isCodePresent(guid: CodeService.CodeGuid): boolean;\r\n\r\n /** Get the data for a code in this CodeIndex by its Guid.\r\n * @returns the data for the code or undefined if no code is present for the supplied Guid.\r\n */\r\n getCode(guid: CodeService.CodeGuid): CodeService.CodeEntry | undefined;\r\n\r\n /** Look up a code by its Scope, Spec, and Value.\r\n * @returns the Guid of the code, or undefined if not present.\r\n */\r\n findCode(code: CodeService.ScopeSpecAndValue): CodeService.CodeGuid | undefined;\r\n\r\n /** Look up a code spec by its name\r\n * @throws if the spec is not present.\r\n */\r\n getCodeSpec(props: CodeService.CodeSpecName): CodeService.NameAndJson;\r\n\r\n /** Call a `CodeIteration` function for all codes in this index, optionally filtered by a `CodeFilter ` */\r\n forAllCodes(iter: CodeService.CodeIteration, filter?: CodeService.CodeFilter): void;\r\n\r\n /** Call an iteration function for all code specs in this index, optionally filtered by a `ValueFilter ` */\r\n forAllCodeSpecs(iter: CodeService.NameAndJsonIteration, filter?: CodeService.ValueFilter): void;\r\n\r\n /**\r\n * Verify that the Code of a to-be-inserted or to-be-updated Element:\r\n * 1. has already been reserved,\r\n * 2. if the element has a `federationGuid`, it must match the reserved value. If the federationGuid is undefined,\r\n * the value from the code index is returned.\r\n *\r\n * If not, throw an exception. Elements with no CodeValue are ignored.\r\n * @note this method is automatically called whenever elements are added or updated by a BriefcaseDb with a CodeService.\r\n */\r\n verifyCode(specName: string, arg: CodeService.ElementCodeProps): void;\r\n }\r\n\r\n export type CodesDb = VersionedSqliteDb & WriteMethods & ReadMethods;\r\n\r\n export interface InternalWriteMethods extends WriteMethods {\r\n /** @internal */\r\n reserveFontId(props: CodeService.FontIndexProps): Promise<FontId>;\r\n /** @internal */\r\n reserveBisCodeSpecs(specs: CodeService.BisCodeSpecIndexProps[]): Promise<void>;\r\n }\r\n export interface InternalReadMethods extends ReadMethods {\r\n /** @internal */\r\n verifyBisCodeSpec(spec: CodeService.BisCodeSpecIndexProps): void;\r\n }\r\n\r\n export type InternalCodes = CodesDb & InternalWriteMethods & InternalReadMethods;\r\n\r\n /** @internal */\r\n const codeSequences = new Map<string, CodeSequence>();\r\n\r\n /** @internal */\r\n export let createForIModel: ((db: IModelDb) => Promise<CodeService>) | undefined;\r\n\r\n /** Register an instance of a`CodeSequence` so it can be looked up by name. */\r\n export function registerSequence(seq: CodeSequence) {\r\n codeSequences.set(seq.sequenceName, seq);\r\n }\r\n\r\n /** Get a previously registered `CodeSequence` by its name.\r\n * @throws if no sequence by that name was registered.\r\n */\r\n export function getSequence(name: string): CodeSequence {\r\n const seq = codeSequences.get(name);\r\n if (!seq)\r\n throw new Error(\"SequenceNotFound\", -1, `code sequence ${name} not found`);\r\n return seq;\r\n }\r\n\r\n /**\r\n * Turn a `CodePops` for the briefcase of this CodeService into a `ScopeAndSpec` object for use with a CodeService.\r\n * This is necessary because the `spec` member of `CodeProps` refers to the id of a code spec in the iModel, and\r\n * the `scope` member refers to the element Id of the scope element in the iModel. This helper function\r\n * converts the spec Id to the spec name and looks up the `FederationGuid` of the scope element.\r\n */\r\n export function makeScopeAndSpec(iModel: IModelDb, code: CodeProps): CodeService.ScopeAndSpec {\r\n const scopeGuid = iModel.elements.getElementProps({ id: code.scope, onlyBaseProperties: true }).federationGuid;\r\n if (undefined === scopeGuid)\r\n throw new CodeService.Error(\"MissingGuid\", IModelStatus.InvalidCode, \"code scope element has no federationGuid\");\r\n\r\n return { scopeGuid, specName: iModel.codeSpecs.getById(code.spec).name };\r\n }\r\n\r\n /** Turn a `CodeProps` and `ProposedCodeProps` into a `ProposedCode` for use with a CodeService.\r\n * @see [[makeScopeAndSpec]] for explanation of why this is necessary.\r\n */\r\n export function makeProposedCode(arg: CodeService.MakeProposedCodeArgs): CodeService.ProposedCode {\r\n return {\r\n ...arg.props,\r\n value: arg.code.value,\r\n ...makeScopeAndSpec(arg.iModel, arg.code),\r\n };\r\n }\r\n\r\n /** The name of a code spec */\r\n export type CodeSpecName = string;\r\n\r\n /**\r\n * The name that identifies the \"originator\" of a code. Usually this is the Guid of the iModel from which a code was added,\r\n * but can also be used to identify a system or type from an external code service.\r\n */\r\n export type CodeOriginName = string;\r\n\r\n /** The name that identifies the \"author\" of a code. Generally, this is intended to be the name of a person or group that helps identify the purpose of the code. */\r\n export type AuthorName = string;\r\n\r\n /** The value for a code. */\r\n export type CodeValue = string;\r\n\r\n /** The guid for a code. This identifies the real-world entity associated with the code. */\r\n export type CodeGuid = GuidString;\r\n\r\n /** The guid of the scope for a code. This identifies the real-world entity that provides the uniqueness scope for code values. */\r\n export type ScopeGuid = GuidString;\r\n\r\n /** An optional number associated with a code that may be used for \"status\" information. Values must be defined by applications. */\r\n export type CodeState = number;\r\n\r\n /** The return status of an iteration function. The value \"stop\" causes the iteration to terminate. */\r\n export type IterationReturn = void | \"stop\";\r\n\r\n /** An iteration function over codes in a code index. It is called with the Guid of a each code. */\r\n export type CodeIteration = (guid: GuidString) => IterationReturn;\r\n\r\n /** An iteration function over code specs in a code index. It is called with the name and json of a each code spec. */\r\n export type NameAndJsonIteration = (nameAndJson: NameAndJson) => IterationReturn;\r\n\r\n /** Argument for reserving an array of new codes. */\r\n export interface ReserveCodesArgs {\r\n /** an array of proposed codes to reserve.\r\n * @note the guid of each proposed code must be supplied by the caller.\r\n */\r\n readonly codes: CodeService.ProposedCode[];\r\n /** If true, unless all codes are available, don't reserve any codes. Otherwise reserve all available codes. */\r\n readonly allOrNothing?: true;\r\n }\r\n\r\n /** Argument for reserving a code from a code sequence. */\r\n export interface ReserveNextArgs {\r\n /** the properties of the new code */\r\n readonly code: CodeService.ProposedCodeProps;\r\n /** The code sequence and scope for the new code. */\r\n readonly from: SequenceScope;\r\n }\r\n\r\n /** Argument for reserving an array of codes from a code sequence. */\r\n export interface ReserveNextArrayArgs {\r\n /** an array of proposed codes to reserve. */\r\n readonly codes: CodeService.ProposedCodeProps[];\r\n /** The code sequence and scope for the new codes. */\r\n readonly from: CodeService.SequenceScope;\r\n /** If true, and in the event that the code sequence does not have enough available codes to fulfill all the entries in `codes`,\r\n * return as many as possible. Otherwise no codes are reserved. The `problems` member of the exception can be used to determine how many codes were available.\r\n * @note if `asManyAsPossible` is true, no error is thrown if the sequence becomes full. You must check the return value to see how many\r\n * were actually available. The `value` member will be undefined for any proposed codes that were not reserved.\r\n */\r\n readonly asManyAsPossible?: true;\r\n }\r\n\r\n /** Argument for updating an array of codes. */\r\n export interface UpdateCodesArgs {\r\n /** Properties of the codes to update */\r\n readonly props: CodeService.UpdatedCode[];\r\n /** If true, unless all codes are updated, don't update any codes. Otherwise update all possible codes. */\r\n readonly allOrNothing?: true;\r\n }\r\n\r\n /** Arguments for CodeService.makeProposedCode */\r\n export interface MakeProposedCodeArgs {\r\n readonly iModel: IModelDb;\r\n readonly code: Required<CodeProps>;\r\n readonly props: CodeService.CodeGuidStateJson;\r\n }\r\n\r\n /** The properties of an Element to be checked against the code index.\r\n * @see CodeService.verifyCode\r\n */\r\n export interface ElementCodeProps {\r\n /** iModel from which the code is being inserted/updated. */\r\n readonly iModel: IModelDb;\r\n /** Properties of the code */\r\n readonly props: {\r\n /** The imodel-specific code properties. */\r\n readonly code: CodeProps;\r\n /**\r\n * The federationGuid of the element being inserted or updated.\r\n * If federationGuid is defined, it is must match the value in the code index or an error is thrown.\r\n * If it is undefined, the value from the code index is returned here.\r\n */\r\n federationGuid?: GuidString;\r\n };\r\n }\r\n\r\n /** a name and a json object. Used for code specs, authors and origins. */\r\n export interface NameAndJson {\r\n readonly name: string;\r\n readonly json?: SettingObject;\r\n }\r\n\r\n /** A code Scope guid, and code spec name. */\r\n export interface ScopeAndSpec {\r\n readonly specName: CodeSpecName;\r\n readonly scopeGuid: ScopeGuid;\r\n }\r\n\r\n /** A code Scope guid, code spec, and code value. */\r\n export interface ScopeSpecAndValue extends ScopeAndSpec {\r\n readonly value: CodeValue;\r\n }\r\n\r\n /** The data held in a code index for a single code. */\r\n export interface CodeEntry {\r\n /** The name of the code spec for this code. */\r\n readonly specName: CodeSpecName;\r\n /** The guid of the entity that provides the scope for this code. */\r\n readonly scopeGuid: ScopeGuid;\r\n /** The value of this code. */\r\n readonly value: CodeValue;\r\n /** The guid of the entity this code identifies. */\r\n readonly guid: CodeGuid;\r\n /** the state of the code. May be undefined. */\r\n readonly state?: CodeState;\r\n /** The name of the originating source of this code (usually an iModel Guid). May be undefined. */\r\n readonly origin: CodeOriginName;\r\n /** The name of the author of this code. May be undefined. */\r\n readonly author?: AuthorName;\r\n /** Option json properties associated with this code. May be undefined. */\r\n readonly json?: SettingObject;\r\n }\r\n\r\n /** A filter used to limit and/or sort the values returned by an iteration. */\r\n export interface ValueFilter {\r\n /** A value filter. May include wild cards when used with `GLOB` or `LIKE` */\r\n readonly value?: string;\r\n /** The comparison operator for `value`. Default is `=` */\r\n readonly valueCompare?: \"GLOB\" | \"LIKE\" | \"NOT GLOB\" | \"NOT LIKE\" | \"=\" | \"<\" | \">\";\r\n /** Order results ascending or descending. If not supplied, the results are unordered (random). */\r\n readonly orderBy?: \"ASC\" | \"DESC\";\r\n /** An SQL expression to further filter results. This string is appended to the `WHERE` clause with an `AND` (that should not be part of the sqlExpression) */\r\n readonly sqlExpression?: string;\r\n }\r\n\r\n /** A filter to limit and/or sort the values for the [[CodeIndex.forAllCodes]] iteration. */\r\n export interface CodeFilter extends ValueFilter {\r\n /** If supplied, limit results to only those with this spec */\r\n readonly specName?: CodeSpecName;\r\n /** If supplied, limit results to only those with this scope Guid */\r\n readonly scopeGuid?: ScopeGuid;\r\n /** If supplied, limit results to only those with this origin */\r\n readonly origin?: CodeOriginName;\r\n }\r\n\r\n /** Author and origin information supplied when codes are reserved. */\r\n export interface AuthorAndOrigin {\r\n /** The name of the individual or group for whom the code was reserved. */\r\n readonly author: Mutable<NameAndJson>;\r\n /** The identity of the \"originator\" of the code. This is usually a guid of an iModel, but can be any unique string. */\r\n readonly origin: Mutable<NameAndJson>;\r\n }\r\n\r\n /** The Guid, state, and json properties of a code. */\r\n export interface CodeGuidStateJson {\r\n /** The Guid of the new code. This must be always be supplied by the application. */\r\n readonly guid: CodeGuid;\r\n /** An optional value for the state of the code. */\r\n readonly state?: CodeState;\r\n /** An optional json object to be stored with the code. */\r\n readonly json?: SettingObject;\r\n }\r\n\r\n /** Properties of a \"proposed\" new code to be reserved.\r\n * @note the Guid of the entity identified by this code *must* be supplied, but `value` is optional, since\r\n * this may be used to reserve codes from a sequence where the value is generated.\r\n */\r\n export interface ProposedCodeProps extends CodeGuidStateJson {\r\n /** The value for the proposed code.\r\n * @note For code sequence operations, this value is ignored on input and is set with a new value from the sequence on successful return.\r\n */\r\n value?: CodeValue;\r\n }\r\n\r\n /** Properties of a proposed new code that is not from a code sequence (its `value` is required). */\r\n export type ProposedCode = ProposedCodeProps & ScopeSpecAndValue;\r\n\r\n /** Properties that describe a code sequence and a scope and spec for a proposed code or array of codes from a sequence. */\r\n export interface SequenceScope extends ScopeAndSpec {\r\n /** The code sequence. */\r\n readonly seq: CodeSequence;\r\n /** A valid current value. If supplied, the returned value will always be later in the sequence than this. */\r\n readonly start?: CodeValue;\r\n }\r\n\r\n /** Properties of a code to be updated.\r\n * @note The `guid` member identifies the code to be updated and is required.\r\n * All other properties are optional - if `undefined`, its value is not changed.\r\n */\r\n export type UpdatedCode = MarkRequired<Partial<ProposedCode>, \"guid\">;\r\n\r\n /** A proposed code that could not be reserved due to some error. */\r\n export interface ReserveProblem {\r\n /** the proposed code that failed. */\r\n readonly code: ProposedCode;\r\n /** the reason for the failure */\r\n readonly errorId: ErrorId;\r\n /** the error message from the exception for this proposed code. */\r\n readonly message: string;\r\n }\r\n\r\n /** A update to a code that failed for some error. */\r\n export interface UpdateProblem {\r\n /** The properties of the code that was to be updated */\r\n readonly prop: UpdatedCode;\r\n /** the reason for the failure */\r\n readonly errorId: ErrorId;\r\n /** the error message from the exception for the update request. */\r\n readonly message: string;\r\n }\r\n\r\n /**\r\n * A sequence of code values following a increasing pattern. Valid code sequences must have a first value, a last value, and\r\n * a way to get the next valid value from an existing valid value.\r\n * Code sequences have a `sequenceName` so they can be registered using `CodeService.registerSequence`.\r\n */\r\n export interface CodeSequence {\r\n /** the name of this CodeSequence. */\r\n get sequenceName(): string;\r\n /** Get the first valid value for this CodeSequence */\r\n getFirstValue(): CodeValue;\r\n /** Get the last valid value for this CodeSequence */\r\n getLastValue(): CodeValue;\r\n /** Get the next valid value for this CodeSequence from the supplied value.\r\n * If the sequence is full (that is, the next value is greater than the last value, this method should throw with errorId=\"SequenceFull\".\r\n * @return the next valid value according to the rules of this CodeSequence.\r\n */\r\n getNextValue(code: CodeValue): CodeValue;\r\n /** Determine whether this supplied value is valid for this sequence. */\r\n isValidCode(code: CodeValue): boolean;\r\n }\r\n\r\n /** @internal */\r\n export interface FontIndexProps {\r\n id?: number;\r\n fontType: FontType;\r\n fontName: string;\r\n }\r\n /** @internal */\r\n export interface BisCodeSpecIndexProps {\r\n id?: number;\r\n name: string;\r\n props: string;\r\n }\r\n\r\n /** Exception class thrown by `CodeService` methods. */\r\n export class Error extends BentleyError {\r\n /** A string that indicates the type of problem that caused the exception. */\r\n public readonly errorId: ErrorId;\r\n /** For [[CodeService.reserveCodes]] and [[CodeService.updateCodes]], a list of the problem details. */\r\n public readonly problems?: ReserveProblem[] | UpdateProblem[];\r\n\r\n /** @internal */\r\n constructor(errorId: ErrorId, errNum: number, message: string, problems?: ReserveProblem[] | UpdateProblem[]) {\r\n super(errNum, message);\r\n this.errorId = errorId;\r\n this.problems = problems;\r\n }\r\n }\r\n\r\n /** Identifiers for exceptions thrown by `CodeService` methods.\r\n * @see [[CodeService.Error.errorId]]\r\n */\r\n export type ErrorId =\r\n \"BadIndexProps\" |\r\n \"CorruptIModel\" |\r\n \"CorruptIndex\" |\r\n \"DuplicateValue\" |\r\n \"GuidIsInUse\" |\r\n \"GuidMismatch\" |\r\n \"IllegalValue\" |\r\n \"InconsistentIModels\" |\r\n \"IndexReadonly\" |\r\n \"InvalidCodeScope\" |\r\n \"InvalidGuid\" |\r\n \"InvalidSequence\" |\r\n \"MissingCode\" |\r\n \"MissingGuid\" |\r\n \"MissingInput\" |\r\n \"MissingSpec\" |\r\n \"NoCodeIndex\" |\r\n \"SequenceFull\" |\r\n \"ReserveErrors\" |\r\n \"SequenceNotFound\" |\r\n \"SqlLogicError\" |\r\n \"UpdateErrors\" |\r\n \"ValueIsInUse\" |\r\n \"WrongVersion\";\r\n\r\n}\r\n"]}
1
+ {"version":3,"file":"CodeService.js","sourceRoot":"","sources":["../../src/CodeService.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAE/F,sDAAoG;AAyCpG,aAAa;AACb,IAAiB,WAAW,CA4d3B;AA5dD,WAAiB,WAAW;IA+H1B,gBAAgB;IAChB,MAAM,aAAa,GAAG,IAAI,GAAG,EAAwB,CAAC;IAKtD,8EAA8E;IAC9E,SAAgB,gBAAgB,CAAC,GAAiB;QAChD,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;IAC3C,CAAC;IAFe,4BAAgB,mBAE/B,CAAA;IAED;;OAEG;IACH,SAAgB,WAAW,CAAC,IAAY;QACtC,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG;YACN,MAAM,IAAI,KAAK,CAAC,kBAAkB,EAAE,CAAC,CAAC,EAAE,iBAAiB,IAAI,YAAY,CAAC,CAAC;QAC7E,OAAO,GAAG,CAAC;IACb,CAAC;IALe,uBAAW,cAK1B,CAAA;IAED;;;;;OAKG;IACH,SAAgB,gBAAgB,CAAC,MAAgB,EAAE,IAAe;QAChE,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAC,cAAc,CAAC;QAC/G,IAAI,SAAS,KAAK,SAAS;YACzB,MAAM,IAAI,WAAW,CAAC,KAAK,CAAC,aAAa,EAAE,2BAAY,CAAC,WAAW,EAAE,0CAA0C,CAAC,CAAC;QAEnH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3E,CAAC;IANe,4BAAgB,mBAM/B,CAAA;IAED;;OAEG;IACH,SAAgB,gBAAgB,CAAC,GAAqC;QACpE,OAAO;YACL,GAAG,GAAG,CAAC,KAAK;YACZ,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK;YACrB,GAAG,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC;SAC1C,CAAC;IACJ,CAAC;IANe,4BAAgB,mBAM/B,CAAA;IAoQD,uDAAuD;IACvD,MAAa,KAAM,SAAQ,2BAAY;QAMrC,gBAAgB;QAChB,YAAY,OAAgB,EAAE,MAAc,EAAE,OAAe,EAAE,QAA6C;YAC1G,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;YACvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC3B,CAAC;KACF;IAZY,iBAAK,QAYjB,CAAA;AAgCH,CAAC,EA5dgB,WAAW,GAAX,mBAAW,KAAX,mBAAW,QA4d3B","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { BentleyError, GuidString, IModelStatus, MarkRequired, Mutable } from \"@itwin/core-bentley\";\r\nimport { CodeProps, FontId, FontType } from \"@itwin/core-common\";\r\nimport { CloudSqlite } from \"./CloudSqlite\";\r\nimport { IModelDb } from \"./IModelDb\";\r\nimport { SettingObject } from \"./workspace/Settings\";\r\nimport { VersionedSqliteDb } from \"./SQLiteDb\";\r\n\r\n/**\r\n * The services for querying, reserving, updating, and deleting codes for a BriefcaseDb (available via `BriefcaseDb.codeService`) whenever it is opened for write access.\r\n * See [CodeService]($docs/learning/backend/CodeService).\r\n * @alpha\r\n */\r\nexport interface CodeService {\r\n /** @internal */\r\n close: () => void;\r\n\r\n initialize(iModel: IModelDb): Promise<void>;\r\n\r\n /** the index for external Codes for this CodeService */\r\n readonly externalCodes?: CloudSqlite.DbAccess<CodeService.CodesDb, CodeService.ReadMethods, CodeService.WriteMethods>;\r\n\r\n /** the index for internal Codes for this CodeService */\r\n readonly internalCodes?: CloudSqlite.DbAccess<CodeService.InternalCodes, CodeService.InternalReadMethods, CodeService.InternalWriteMethods>;\r\n\r\n /**\r\n * Application-supplied parameters for reserving new codes.\r\n */\r\n readonly appParams: CodeService.AuthorAndOrigin;\r\n\r\n /**\r\n * Verify that the Code of a to-be-inserted or to-be-updated Element:\r\n * 1. has already been reserved,\r\n * 2. if the element has a `federationGuid`, it must match the reserved value. If the federationGuid is undefined,\r\n * the value from the code index is returned.\r\n *\r\n * If not, throw an exception. Elements with no CodeValue are ignored.\r\n * @note this method is automatically called whenever elements are added or updated by a BriefcaseDb with a CodeService.\r\n */\r\n verifyCode(props: CodeService.ElementCodeProps): void;\r\n}\r\n\r\n/** @alpha */\r\nexport namespace CodeService {\r\n\r\n export interface WriteMethods {\r\n /** Add a new code spec to this code service.\r\n */\r\n addCodeSpec(val: CodeService.NameAndJson): Promise<void>;\r\n\r\n /**\r\n * Add all of the codes and code specs from this CodeService's BriefcaseDb into the code index.\r\n * @returns the number of codes actually added.\r\n * @note It is not necessary to call this method unless the BriefcaseDb somehow becomes out of sync with its CodeService,\r\n * for example when migrating iModels to a new code service. It is safe (but relatively expensive) to call this method multiple times, since\r\n * any codes or code specs that are already in the index are ignored.\r\n */\r\n addAllCodes(iModel: IModelDb): Promise<number>;\r\n\r\n /**\r\n * Attempt to reserve a single proposed code.\r\n * @throws `CodeService.Error` if the proposed code cannot be reserved.\r\n */\r\n reserveCode(code: CodeService.ProposedCode): Promise<void>;\r\n\r\n /**\r\n * Attempt to reserve an array of proposed codes.\r\n * @returns number of codes actually reserved.\r\n * @see the `problems` member of the `CodeService.Error` exception\r\n * @note If you have a set of codes to reserve, it is considerably more efficient to do them as an array rather than one at a time.\r\n * @throws `CodeService.Error` if any of the proposed code cannot be reserved. The details for each failed code are in the `problems` member.\r\n */\r\n reserveCodes(arg: CodeService.ReserveCodesArgs): Promise<number>;\r\n\r\n /**\r\n * Attempt to reserve the next available code for a code sequence and scope.\r\n */\r\n reserveNextAvailableCode(arg: CodeService.ReserveNextArgs): Promise<void>;\r\n\r\n /**\r\n * Attempt to reserve an array of the next available codes for a code sequence and scope.\r\n * The length of the array determines the number of codes requested. The values for the new codes are returned\r\n * in the array, so they can be associated with the supplied GUIDs.\r\n * @returns number of codes actually reserved.\r\n */\r\n reserveNextAvailableCodes(arg: CodeService.ReserveNextArrayArgs): Promise<number>;\r\n\r\n /**\r\n * Update the properties of a single code.\r\n */\r\n updateCode(props: CodeService.UpdatedCode): Promise<void>;\r\n\r\n /**\r\n * Update the properties of an array codes.\r\n * @note If you have a set of codes to update, it is considerably more efficient to do them as an array rather than one at a time.\r\n * @returns number of codes actually updated.\r\n */\r\n updateCodes(arg: CodeService.UpdateCodesArgs): Promise<number>;\r\n\r\n /** Delete an array of codes by their guids. */\r\n deleteCodes(guid: CodeService.CodeGuid[]): Promise<void>;\r\n }\r\n\r\n export interface ReadMethods {\r\n /**\r\n * Find the next available value for the supplied `SequenceScope`.\r\n * If the sequence is full (there are no available values), this will throw an exception with `errorId=\"SequenceFull\"`\r\n * @param from the sequence and scope to search\r\n * @returns the next available CodeValue in the sequence.\r\n */\r\n findNextAvailable(from: CodeService.SequenceScope): CodeService.CodeValue;\r\n\r\n /**\r\n * Find the highest currently used value for the supplied `SequenceScope`\r\n * @param from the sequence and scope to search\r\n * @returns the highest used value, or undefined if no values have been used.\r\n */\r\n findHighestUsed(from: CodeService.SequenceScope): CodeService.CodeValue | undefined;\r\n\r\n /** Determine whether a code is present in this CodeIndex by its Guid. */\r\n isCodePresent(guid: CodeService.CodeGuid): boolean;\r\n\r\n /** Get the data for a code in this CodeIndex by its Guid.\r\n * @returns the data for the code or undefined if no code is present for the supplied Guid.\r\n */\r\n getCode(guid: CodeService.CodeGuid): CodeService.CodeEntry | undefined;\r\n\r\n /** Look up a code by its Scope, Spec, and Value.\r\n * @returns the Guid of the code, or undefined if not present.\r\n */\r\n findCode(code: CodeService.ScopeSpecAndValue): CodeService.CodeGuid | undefined;\r\n\r\n /** Look up a code spec by its name\r\n * @throws if the spec is not present.\r\n */\r\n getCodeSpec(props: CodeService.CodeSpecName): CodeService.NameAndJson;\r\n\r\n /** Call a `CodeIteration` function for all codes in this index, optionally filtered by a `CodeFilter ` */\r\n forAllCodes(iter: CodeService.CodeIteration, filter?: CodeService.CodeFilter): void;\r\n\r\n /** Call an iteration function for all code specs in this index, optionally filtered by a `ValueFilter ` */\r\n forAllCodeSpecs(iter: CodeService.NameAndJsonIteration, filter?: CodeService.ValueFilter): void;\r\n\r\n /**\r\n * Verify that the Code of a to-be-inserted or to-be-updated Element:\r\n * 1. has already been reserved,\r\n * 2. if the element has a `federationGuid`, it must match the reserved value. If the federationGuid is undefined,\r\n * the value from the code index is returned.\r\n *\r\n * If not, throw an exception. Elements with no CodeValue are ignored.\r\n * @note this method is automatically called whenever elements are added or updated by a BriefcaseDb with a CodeService.\r\n */\r\n verifyCode(specName: string, arg: CodeService.ElementCodeProps): void;\r\n }\r\n\r\n export type CodesDb = VersionedSqliteDb & WriteMethods & ReadMethods;\r\n\r\n export interface InternalWriteMethods extends WriteMethods {\r\n /** @internal */\r\n reserveFontId(props: CodeService.FontIndexProps): Promise<FontId>;\r\n /** @internal */\r\n reserveBisCodeSpecs(specs: CodeService.BisCodeSpecIndexProps[]): Promise<void>;\r\n }\r\n export interface InternalReadMethods extends ReadMethods {\r\n /** @internal */\r\n verifyBisCodeSpec(spec: CodeService.BisCodeSpecIndexProps): void;\r\n }\r\n\r\n export type InternalCodes = CodesDb & InternalWriteMethods & InternalReadMethods;\r\n\r\n /** @internal */\r\n const codeSequences = new Map<string, CodeSequence>();\r\n\r\n /** @internal */\r\n export let createForIModel: ((db: IModelDb) => Promise<CodeService>) | undefined;\r\n\r\n /** Register an instance of a`CodeSequence` so it can be looked up by name. */\r\n export function registerSequence(seq: CodeSequence) {\r\n codeSequences.set(seq.sequenceName, seq);\r\n }\r\n\r\n /** Get a previously registered `CodeSequence` by its name.\r\n * @throws if no sequence by that name was registered.\r\n */\r\n export function getSequence(name: string): CodeSequence {\r\n const seq = codeSequences.get(name);\r\n if (!seq)\r\n throw new Error(\"SequenceNotFound\", -1, `code sequence ${name} not found`);\r\n return seq;\r\n }\r\n\r\n /**\r\n * Turn a `CodePops` for the briefcase of this CodeService into a `ScopeAndSpec` object for use with a CodeService.\r\n * This is necessary because the `spec` member of `CodeProps` refers to the id of a code spec in the iModel, and\r\n * the `scope` member refers to the element Id of the scope element in the iModel. This helper function\r\n * converts the spec Id to the spec name and looks up the `FederationGuid` of the scope element.\r\n */\r\n export function makeScopeAndSpec(iModel: IModelDb, code: CodeProps): CodeService.ScopeAndSpec {\r\n const scopeGuid = iModel.elements.getElementProps({ id: code.scope, onlyBaseProperties: true }).federationGuid;\r\n if (undefined === scopeGuid)\r\n throw new CodeService.Error(\"MissingGuid\", IModelStatus.InvalidCode, \"code scope element has no federationGuid\");\r\n\r\n return { scopeGuid, specName: iModel.codeSpecs.getById(code.spec).name };\r\n }\r\n\r\n /** Turn a `CodeProps` and `ProposedCodeProps` into a `ProposedCode` for use with a CodeService.\r\n * @see [[makeScopeAndSpec]] for explanation of why this is necessary.\r\n */\r\n export function makeProposedCode(arg: CodeService.MakeProposedCodeArgs): CodeService.ProposedCode {\r\n return {\r\n ...arg.props,\r\n value: arg.code.value,\r\n ...makeScopeAndSpec(arg.iModel, arg.code),\r\n };\r\n }\r\n\r\n /** The name of a code spec */\r\n export type CodeSpecName = string;\r\n\r\n /**\r\n * The name that identifies the \"originator\" of a code. Usually this is the Guid of the iModel from which a code was added,\r\n * but can also be used to identify a system or type from an external code service.\r\n */\r\n export type CodeOriginName = string;\r\n\r\n /** The name that identifies the \"author\" of a code. Generally, this is intended to be the name of a person or group that helps identify the purpose of the code. */\r\n export type AuthorName = string;\r\n\r\n /** The value for a code. */\r\n export type CodeValue = string;\r\n\r\n /** The guid for a code. This identifies the real-world entity associated with the code. */\r\n export type CodeGuid = GuidString;\r\n\r\n /** The guid of the scope for a code. This identifies the real-world entity that provides the uniqueness scope for code values. */\r\n export type ScopeGuid = GuidString;\r\n\r\n /** An optional number associated with a code that may be used for \"status\" information. Values must be defined by applications. */\r\n export type CodeState = number;\r\n\r\n /** The return status of an iteration function. The value \"stop\" causes the iteration to terminate. */\r\n export type IterationReturn = void | \"stop\";\r\n\r\n /** An iteration function over codes in a code index. It is called with the Guid of a each code. */\r\n export type CodeIteration = (guid: GuidString) => IterationReturn;\r\n\r\n /** An iteration function over code specs in a code index. It is called with the name and json of a each code spec. */\r\n export type NameAndJsonIteration = (nameAndJson: NameAndJson) => IterationReturn;\r\n\r\n /** Argument for reserving an array of new codes. */\r\n export interface ReserveCodesArgs {\r\n /** an array of proposed codes to reserve.\r\n * @note the guid of each proposed code must be supplied by the caller.\r\n */\r\n readonly codes: CodeService.ProposedCode[];\r\n /** If true, unless all codes are available, don't reserve any codes. Otherwise reserve all available codes. */\r\n readonly allOrNothing?: true;\r\n }\r\n\r\n /** Argument for reserving a code from a code sequence. */\r\n export interface ReserveNextArgs {\r\n /** the properties of the new code */\r\n readonly code: CodeService.ProposedCodeProps;\r\n /** The code sequence and scope for the new code. */\r\n readonly from: SequenceScope;\r\n }\r\n\r\n /** Argument for reserving an array of codes from a code sequence. */\r\n export interface ReserveNextArrayArgs {\r\n /** an array of proposed codes to reserve. */\r\n readonly codes: CodeService.ProposedCodeProps[];\r\n /** The code sequence and scope for the new codes. */\r\n readonly from: CodeService.SequenceScope;\r\n /** If true, and in the event that the code sequence does not have enough available codes to fulfill all the entries in `codes`,\r\n * return as many as possible. Otherwise no codes are reserved. The `problems` member of the exception can be used to determine how many codes were available.\r\n * @note if `asManyAsPossible` is true, no error is thrown if the sequence becomes full. You must check the return value to see how many\r\n * were actually available. The `value` member will be undefined for any proposed codes that were not reserved.\r\n */\r\n readonly asManyAsPossible?: true;\r\n }\r\n\r\n /** Argument for updating an array of codes. */\r\n export interface UpdateCodesArgs {\r\n /** Properties of the codes to update */\r\n readonly props: CodeService.UpdatedCode[];\r\n /** If true, unless all codes are updated, don't update any codes. Otherwise update all possible codes. */\r\n readonly allOrNothing?: true;\r\n }\r\n\r\n /** Arguments for CodeService.makeProposedCode */\r\n export interface MakeProposedCodeArgs {\r\n readonly iModel: IModelDb;\r\n readonly code: Required<CodeProps>;\r\n readonly props: CodeService.CodeGuidStateJson;\r\n }\r\n\r\n /** The properties of an Element to be checked against the code index.\r\n * @see CodeService.verifyCode\r\n */\r\n export interface ElementCodeProps {\r\n /** iModel from which the code is being inserted/updated. */\r\n readonly iModel: IModelDb;\r\n /** Properties of the code */\r\n readonly props: {\r\n /** The imodel-specific code properties. */\r\n readonly code: CodeProps;\r\n /**\r\n * The federationGuid of the element being inserted or updated.\r\n * If federationGuid is defined, it is must match the value in the code index or an error is thrown.\r\n * If it is undefined, the value from the code index is returned here.\r\n */\r\n federationGuid?: GuidString;\r\n };\r\n }\r\n\r\n /** a name and a json object. Used for code specs, authors and origins. */\r\n export interface NameAndJson {\r\n readonly name: string;\r\n readonly json?: SettingObject;\r\n }\r\n\r\n /** A code Scope guid, and code spec name. */\r\n export interface ScopeAndSpec {\r\n readonly specName: CodeSpecName;\r\n readonly scopeGuid: ScopeGuid;\r\n }\r\n\r\n /** A code Scope guid, code spec, and code value. */\r\n export interface ScopeSpecAndValue extends ScopeAndSpec {\r\n readonly value: CodeValue;\r\n }\r\n\r\n /** The data held in a code index for a single code. */\r\n export interface CodeEntry {\r\n /** The name of the code spec for this code. */\r\n readonly specName: CodeSpecName;\r\n /** The guid of the entity that provides the scope for this code. */\r\n readonly scopeGuid: ScopeGuid;\r\n /** The value of this code. */\r\n readonly value: CodeValue;\r\n /** The guid of the entity this code identifies. */\r\n readonly guid: CodeGuid;\r\n /** the state of the code. May be undefined. */\r\n readonly state?: CodeState;\r\n /** The name of the originating source of this code (usually an iModel Guid). May be undefined. */\r\n readonly origin: CodeOriginName;\r\n /** The name of the author of this code. May be undefined. */\r\n readonly author?: AuthorName;\r\n /** Option json properties associated with this code. May be undefined. */\r\n readonly json?: SettingObject;\r\n }\r\n\r\n /** A filter used to limit and/or sort the values returned by an iteration. */\r\n export interface ValueFilter {\r\n /** A value filter. May include wild cards when used with `GLOB` or `LIKE` */\r\n readonly value?: string;\r\n /** The comparison operator for `value`. Default is `=` */\r\n readonly valueCompare?: \"GLOB\" | \"LIKE\" | \"NOT GLOB\" | \"NOT LIKE\" | \"=\" | \"<\" | \">\";\r\n /** Order results ascending or descending. If not supplied, the results are unordered (random). */\r\n readonly orderBy?: \"ASC\" | \"DESC\";\r\n /** An SQL expression to further filter results. This string is appended to the `WHERE` clause with an `AND` (that should not be part of the sqlExpression) */\r\n readonly sqlExpression?: string;\r\n }\r\n\r\n /** A filter to limit and/or sort the values for the [[CodeIndex.forAllCodes]] iteration. */\r\n export interface CodeFilter extends ValueFilter {\r\n /** If supplied, limit results to only those with this spec */\r\n readonly specName?: CodeSpecName;\r\n /** If supplied, limit results to only those with this scope Guid */\r\n readonly scopeGuid?: ScopeGuid;\r\n /** If supplied, limit results to only those with this origin */\r\n readonly origin?: CodeOriginName;\r\n }\r\n\r\n /** Author and origin information supplied when codes are reserved. */\r\n export interface AuthorAndOrigin {\r\n /** The name of the individual or group for whom the code was reserved. */\r\n readonly author: Mutable<NameAndJson>;\r\n /** The identity of the \"originator\" of the code. This is usually a guid of an iModel, but can be any unique string. */\r\n readonly origin: Mutable<NameAndJson>;\r\n }\r\n\r\n /** The Guid, state, and json properties of a code. */\r\n export interface CodeGuidStateJson {\r\n /** The Guid of the new code. This must be always be supplied by the application. */\r\n readonly guid: CodeGuid;\r\n /** An optional value for the state of the code. */\r\n readonly state?: CodeState;\r\n /** An optional json object to be stored with the code. */\r\n readonly json?: SettingObject;\r\n }\r\n\r\n /** Properties of a \"proposed\" new code to be reserved.\r\n * @note the Guid of the entity identified by this code *must* be supplied, but `value` is optional, since\r\n * this may be used to reserve codes from a sequence where the value is generated.\r\n */\r\n export interface ProposedCodeProps extends CodeGuidStateJson {\r\n /** The value for the proposed code.\r\n * @note For code sequence operations, this value is ignored on input and is set with a new value from the sequence on successful return.\r\n */\r\n value?: CodeValue;\r\n }\r\n\r\n /** Properties of a proposed new code that is not from a code sequence (its `value` is required). */\r\n export type ProposedCode = ProposedCodeProps & ScopeSpecAndValue;\r\n\r\n /** Properties that describe a code sequence and a scope and spec for a proposed code or array of codes from a sequence. */\r\n export interface SequenceScope extends ScopeAndSpec {\r\n /** The code sequence. */\r\n readonly seq: CodeSequence;\r\n /** A valid current value. If supplied, the returned value will always be later in the sequence than this. */\r\n readonly start?: CodeValue;\r\n }\r\n\r\n /** Properties of a code to be updated.\r\n * @note The `guid` member identifies the code to be updated and is required.\r\n * All other properties are optional - if `undefined`, its value is not changed.\r\n */\r\n export type UpdatedCode = MarkRequired<Partial<ProposedCode>, \"guid\">;\r\n\r\n /** A proposed code that could not be reserved due to some error. */\r\n export interface ReserveProblem {\r\n /** the proposed code that failed. */\r\n readonly code: ProposedCode;\r\n /** the reason for the failure */\r\n readonly errorId: ErrorId;\r\n /** the error message from the exception for this proposed code. */\r\n readonly message: string;\r\n }\r\n\r\n /** A update to a code that failed for some error. */\r\n export interface UpdateProblem {\r\n /** The properties of the code that was to be updated */\r\n readonly prop: UpdatedCode;\r\n /** the reason for the failure */\r\n readonly errorId: ErrorId;\r\n /** the error message from the exception for the update request. */\r\n readonly message: string;\r\n }\r\n\r\n /**\r\n * A sequence of code values following a increasing pattern. Valid code sequences must have a first value, a last value, and\r\n * a way to get the next valid value from an existing valid value.\r\n * Code sequences have a `sequenceName` so they can be registered using `CodeService.registerSequence`.\r\n */\r\n export interface CodeSequence {\r\n /** the name of this CodeSequence. */\r\n get sequenceName(): string;\r\n /** Get the first valid value for this CodeSequence */\r\n getFirstValue(): CodeValue;\r\n /** Get the last valid value for this CodeSequence */\r\n getLastValue(): CodeValue;\r\n /** Get the next valid value for this CodeSequence from the supplied value.\r\n * If the sequence is full (that is, the next value is greater than the last value, this method should throw with errorId=\"SequenceFull\".\r\n * @return the next valid value according to the rules of this CodeSequence.\r\n */\r\n getNextValue(code: CodeValue): CodeValue;\r\n /** Determine whether this supplied value is valid for this sequence. */\r\n isValidCode(code: CodeValue): boolean;\r\n }\r\n\r\n /** @internal */\r\n export interface FontIndexProps {\r\n id?: number;\r\n fontType: FontType;\r\n fontName: string;\r\n }\r\n /** @internal */\r\n export interface BisCodeSpecIndexProps {\r\n id?: number;\r\n name: string;\r\n props: string;\r\n }\r\n\r\n /** Exception class thrown by `CodeService` methods. */\r\n export class Error extends BentleyError {\r\n /** A string that indicates the type of problem that caused the exception. */\r\n public readonly errorId: ErrorId;\r\n /** For [[CodeService.reserveCodes]] and [[CodeService.updateCodes]], a list of the problem details. */\r\n public readonly problems?: ReserveProblem[] | UpdateProblem[];\r\n\r\n /** @internal */\r\n constructor(errorId: ErrorId, errNum: number, message: string, problems?: ReserveProblem[] | UpdateProblem[]) {\r\n super(errNum, message);\r\n this.errorId = errorId;\r\n this.problems = problems;\r\n }\r\n }\r\n\r\n /** Identifiers for exceptions thrown by `CodeService` methods.\r\n * @see [[CodeService.Error.errorId]]\r\n */\r\n export type ErrorId =\r\n \"BadIndexProps\" |\r\n \"CorruptIModel\" |\r\n \"CorruptIndex\" |\r\n \"DuplicateValue\" |\r\n \"GuidIsInUse\" |\r\n \"GuidMismatch\" |\r\n \"IllegalValue\" |\r\n \"InconsistentIModels\" |\r\n \"IndexReadonly\" |\r\n \"InvalidCodeScope\" |\r\n \"InvalidGuid\" |\r\n \"InvalidSequence\" |\r\n \"MissingCode\" |\r\n \"MissingGuid\" |\r\n \"MissingInput\" |\r\n \"MissingSpec\" |\r\n \"NoCodeIndex\" |\r\n \"NotAuthorized\" |\r\n \"SequenceFull\" |\r\n \"ReserveErrors\" |\r\n \"SequenceNotFound\" |\r\n \"SqlLogicError\" |\r\n \"UpdateErrors\" |\r\n \"ValueIsInUse\" |\r\n \"WrongVersion\";\r\n\r\n}\r\n"]}
package/lib/cjs/ECDb.d.ts CHANGED
@@ -147,7 +147,7 @@ export declare class ECDb implements IDisposable {
147
147
  *
148
148
  * See also:
149
149
  * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)
150
- * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)
150
+ * - [Code Examples]($docs/learning/ECSQLCodeExamples)
151
151
  *
152
152
  * @param ecsql The ECSQL statement to execute
153
153
  * @param params The values to bind to the parameters (if the ECSQL has any).
@@ -162,7 +162,7 @@ export declare class ECDb implements IDisposable {
162
162
  *
163
163
  * See also:
164
164
  * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)
165
- * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)
165
+ * - [Code Examples]($docs/learning/ECSQLCodeExamples)
166
166
  *
167
167
  * @param ecsql The ECSQL statement to execute
168
168
  * @param params The values to bind to the parameters (if the ECSQL has any).
@@ -178,7 +178,7 @@ export declare class ECDb implements IDisposable {
178
178
  *
179
179
  * See also:
180
180
  * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)
181
- * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)
181
+ * - [Code Examples]($docs/learning/ECSQLCodeExamples)
182
182
  *
183
183
  * @param ecsql The ECSQL statement to execute
184
184
  * @param token None empty restart token. The previous query with same token would be cancelled. This would cause
package/lib/cjs/ECDb.js CHANGED
@@ -289,7 +289,7 @@ class ECDb {
289
289
  *
290
290
  * See also:
291
291
  * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)
292
- * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)
292
+ * - [Code Examples]($docs/learning/ECSQLCodeExamples)
293
293
  *
294
294
  * @param ecsql The ECSQL statement to execute
295
295
  * @param params The values to bind to the parameters (if the ECSQL has any).
@@ -309,7 +309,7 @@ class ECDb {
309
309
  *
310
310
  * See also:
311
311
  * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)
312
- * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)
312
+ * - [Code Examples]($docs/learning/ECSQLCodeExamples)
313
313
  *
314
314
  * @param ecsql The ECSQL statement to execute
315
315
  * @param params The values to bind to the parameters (if the ECSQL has any).
@@ -330,7 +330,7 @@ class ECDb {
330
330
  *
331
331
  * See also:
332
332
  * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)
333
- * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)
333
+ * - [Code Examples]($docs/learning/ECSQLCodeExamples)
334
334
  *
335
335
  * @param ecsql The ECSQL statement to execute
336
336
  * @param token None empty restart token. The previous query with same token would be cancelled. This would cause
@@ -1 +1 @@
1
- {"version":3,"file":"ECDb.js","sourceRoot":"","sources":["../../src/ECDb.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module ECDb\r\n */\r\nimport { assert, DbResult, IDisposable, Logger, OpenMode } from \"@itwin/core-bentley\";\r\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\r\nimport { DbQueryRequest, ECSqlReader, IModelError, QueryBinder, QueryOptions, QueryOptionsBuilder } from \"@itwin/core-common\";\r\nimport { BackendLoggerCategory } from \"./BackendLoggerCategory\";\r\nimport { ConcurrentQuery } from \"./ConcurrentQuery\";\r\nimport { ECSqlStatement } from \"./ECSqlStatement\";\r\nimport { IModelHost } from \"./IModelHost\";\r\nimport { SqliteStatement, StatementCache } from \"./SqliteStatement\";\r\n\r\nconst loggerCategory: string = BackendLoggerCategory.ECDb;\r\n\r\n/** Modes for how to open [ECDb]($backend) files.\r\n * @public\r\n */\r\nexport enum ECDbOpenMode {\r\n Readonly,\r\n ReadWrite,\r\n /** Opens the file read-write and upgrades the file if necessary to the latest file format version. */\r\n FileUpgrade,\r\n}\r\n\r\n/** An ECDb file\r\n * @public\r\n */\r\nexport class ECDb implements IDisposable {\r\n private _nativeDb?: IModelJsNative.ECDb;\r\n private readonly _statementCache = new StatementCache<ECSqlStatement>();\r\n private _sqliteStatementCache = new StatementCache<SqliteStatement>();\r\n\r\n /** only for tests\r\n * @internal\r\n */\r\n public resetSqliteCache(size: number) {\r\n this._sqliteStatementCache.clear();\r\n this._sqliteStatementCache = new StatementCache<SqliteStatement>(size);\r\n }\r\n\r\n constructor() {\r\n this._nativeDb = new IModelHost.platform.ECDb();\r\n }\r\n /** Call this function when finished with this ECDb object. This releases the native resources held by the\r\n * ECDb object.\r\n */\r\n public dispose(): void {\r\n if (!this._nativeDb)\r\n return;\r\n\r\n this.closeDb();\r\n this._nativeDb.dispose();\r\n this._nativeDb = undefined;\r\n }\r\n\r\n /** Create an ECDb\r\n * @param pathName The path to the ECDb file to create.\r\n * @throws [IModelError]($common) if the operation failed.\r\n */\r\n public createDb(pathName: string): void {\r\n const status: DbResult = this.nativeDb.createDb(pathName);\r\n if (status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(status, \"Failed to created ECDb\");\r\n }\r\n\r\n /** Open the ECDb.\r\n * @param pathName The path to the ECDb file to open\r\n * @param openMode Open mode\r\n * @throws [IModelError]($common) if the operation failed.\r\n */\r\n public openDb(pathName: string, openMode: ECDbOpenMode = ECDbOpenMode.Readonly): void {\r\n const nativeOpenMode: OpenMode = openMode === ECDbOpenMode.Readonly ? OpenMode.Readonly : OpenMode.ReadWrite;\r\n const tryUpgrade: boolean = openMode === ECDbOpenMode.FileUpgrade;\r\n const status: DbResult = this.nativeDb.openDb(pathName, nativeOpenMode, tryUpgrade);\r\n if (status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(status, \"Failed to open ECDb\");\r\n }\r\n\r\n /** Returns true if the ECDb is open */\r\n public get isOpen(): boolean { return this.nativeDb.isOpen(); }\r\n\r\n /** Close the Db after saving any uncommitted changes.\r\n * @throws [IModelError]($common) if the database is not open.\r\n */\r\n public closeDb(): void {\r\n this._statementCache.clear();\r\n this._sqliteStatementCache.clear();\r\n this.nativeDb.closeDb();\r\n }\r\n\r\n /** @internal use to test statement caching */\r\n public clearStatementCache() {\r\n this._statementCache.clear();\r\n }\r\n\r\n /** @internal use to test statement caching */\r\n public getCachedStatementCount() {\r\n return this._statementCache.size;\r\n }\r\n\r\n /** Commit the outermost transaction, writing changes to the file. Then, restart the transaction.\r\n * @param changesetName The name of the operation that generated these changes.\r\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\r\n */\r\n public saveChanges(changesetName?: string): void {\r\n const status: DbResult = this.nativeDb.saveChanges(changesetName);\r\n if (status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(status, \"Failed to save changes\");\r\n }\r\n\r\n /** Abandon (cancel) the outermost transaction, discarding all changes since last save. Then, restart the transaction.\r\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\r\n */\r\n public abandonChanges(): void {\r\n const status: DbResult = this.nativeDb.abandonChanges();\r\n if (status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(status, \"Failed to abandon changes\");\r\n }\r\n\r\n /** Import a schema.\r\n *\r\n * If the import was successful, the database is automatically saved to disk.\r\n * @param pathName Path to ECSchema XML file to import.\r\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\r\n */\r\n public importSchema(pathName: string): void {\r\n const status: DbResult = this.nativeDb.importSchema(pathName);\r\n if (status !== DbResult.BE_SQLITE_OK) {\r\n Logger.logError(loggerCategory, `Failed to import schema from '${pathName}'.`);\r\n throw new IModelError(status, `Failed to import schema from '${pathName}'.`);\r\n }\r\n }\r\n\r\n /**\r\n * Use a prepared ECSQL statement, potentially from the statement cache. If the requested statement doesn't exist\r\n * in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved\r\n * in the statement cache so it can be reused in the future. Use this method for ECSQL statements that will be\r\n * reused often and are expensive to prepare. The statement cache holds the most recently used statements, discarding\r\n * the oldest statements as it fills. For statements you don't intend to reuse, instead use [[withStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @see [[withStatement]]\r\n * @public\r\n */\r\n public withPreparedStatement<T>(ecsql: string, callback: (stmt: ECSqlStatement) => T, logErrors = true): T {\r\n const stmt = this._statementCache.findAndRemove(ecsql) ?? this.prepareStatement(ecsql, logErrors);\r\n const release = () => this._statementCache.addOrDispose(stmt);\r\n try {\r\n const val = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n\r\n /**\r\n * Prepared and execute a callback on an ECSQL statement. After the callback completes the statement is disposed.\r\n * Use this method for ECSQL statements are either not expected to be reused, or are not expensive to prepare.\r\n * For statements that will be reused often, instead use [[withPreparedStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @see [[withPreparedStatement]]\r\n * @public\r\n */\r\n public withStatement<T>(ecsql: string, callback: (stmt: ECSqlStatement) => T, logErrors = true): T {\r\n const stmt = this.prepareStatement(ecsql, logErrors);\r\n const release = () => stmt.dispose();\r\n try {\r\n const val = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n\r\n /** Prepare an ECSQL statement.\r\n * @param ecsql The ECSQL statement to prepare\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @throws [IModelError]($common) if there is a problem preparing the statement.\r\n */\r\n public prepareStatement(ecsql: string, logErrors = true): ECSqlStatement {\r\n const stmt = new ECSqlStatement();\r\n stmt.prepare(this.nativeDb, ecsql, logErrors);\r\n return stmt;\r\n }\r\n\r\n /**\r\n * Use a prepared SQL statement, potentially from the statement cache. If the requested statement doesn't exist\r\n * in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved\r\n * in the statement cache so it can be reused in the future. Use this method for SQL statements that will be\r\n * reused often and are expensive to prepare. The statement cache holds the most recently used statements, discarding\r\n * the oldest statements as it fills. For statements you don't intend to reuse, instead use [[withSqliteStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @see [[withPreparedStatement]]\r\n * @public\r\n */\r\n public withPreparedSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T, logErrors = true): T {\r\n const stmt = this._sqliteStatementCache.findAndRemove(sql) ?? this.prepareSqliteStatement(sql, logErrors);\r\n const release = () => this._sqliteStatementCache.addOrDispose(stmt);\r\n try {\r\n const val: T = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n\r\n /**\r\n * Prepared and execute a callback on a SQL statement. After the callback completes the statement is disposed.\r\n * Use this method for SQL statements are either not expected to be reused, or are not expensive to prepare.\r\n * For statements that will be reused often, instead use [[withPreparedSqliteStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @public\r\n */\r\n public withSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T, logErrors = true): T {\r\n const stmt = this.prepareSqliteStatement(sql, logErrors);\r\n const release = () => stmt.dispose();\r\n try {\r\n const val: T = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n\r\n /** Prepare an SQL statement.\r\n * @param sql The SQLite SQL statement to prepare\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @throws [IModelError]($common) if there is a problem preparing the statement.\r\n * @internal\r\n */\r\n public prepareSqliteStatement(sql: string, logErrors = true): SqliteStatement {\r\n const stmt = new SqliteStatement(sql);\r\n stmt.prepare(this.nativeDb, logErrors);\r\n return stmt;\r\n }\r\n\r\n /** @internal */\r\n public get nativeDb(): IModelJsNative.ECDb {\r\n assert(undefined !== this._nativeDb);\r\n return this._nativeDb;\r\n }\r\n\r\n /** Allow to execute query and read results along with meta data. The result are streamed.\r\n * @param params The values to bind to the parameters (if the ECSQL has any).\r\n * @param config Allow to specify certain flags which control how query is executed.\r\n * @returns Returns an [ECSqlReader]($common) which helps iterate over the result set and also give access to metadata.\r\n * @beta\r\n * */\r\n public createQueryReader(ecsql: string, params?: QueryBinder, config?: QueryOptions): ECSqlReader {\r\n if (!this._nativeDb || !this._nativeDb.isOpen()) {\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"db not open\");\r\n }\r\n const executor = {\r\n execute: async (request: DbQueryRequest) => {\r\n return ConcurrentQuery.executeQueryRequest(this.nativeDb, request);\r\n },\r\n };\r\n return new ECSqlReader(executor, ecsql, params, config);\r\n }\r\n\r\n /** Execute a query and stream its results\r\n * The result of the query is async iterator over the rows. The iterator will get next page automatically once rows in current page has been read.\r\n * [ECSQL row]($docs/learning/ECSQLRowFormat).\r\n *\r\n * See also:\r\n * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)\r\n * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)\r\n *\r\n * @param ecsql The ECSQL statement to execute\r\n * @param params The values to bind to the parameters (if the ECSQL has any).\r\n * @param options Allow to specify certain flags which control how query is executed.\r\n * @returns Returns the query result as an *AsyncIterableIterator<any>* which lazy load result as needed. The row format is determined by *rowFormat* parameter.\r\n * See [ECSQL row format]($docs/learning/ECSQLRowFormat) for details about the format of the returned rows.\r\n * @throws [IModelError]($common) If there was any error while submitting, preparing or stepping into query\r\n * @deprecated in 3.7. Use [[createQueryReader]] instead; it accepts the same parameters.\r\n */\r\n public async * query(ecsql: string, params?: QueryBinder, options?: QueryOptions): AsyncIterableIterator<any> {\r\n const builder = new QueryOptionsBuilder(options);\r\n const reader = this.createQueryReader(ecsql, params, builder.getOptions());\r\n while (await reader.step())\r\n yield reader.formatCurrentRow();\r\n }\r\n /** Compute number of rows that would be returned by the ECSQL.\r\n *\r\n * See also:\r\n * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)\r\n * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)\r\n *\r\n * @param ecsql The ECSQL statement to execute\r\n * @param params The values to bind to the parameters (if the ECSQL has any).\r\n * See \"[iTwin.js Types used in ECSQL Parameter Bindings]($docs/learning/ECSQLParameterTypes)\" for details.\r\n * @returns Return row count.\r\n * @throws [IModelError]($common) If the statement is invalid\r\n * @deprecated in 3.7. Count the number of results using `count(*)` where the original query is a subquery instead. E.g., `SELECT count(*) FROM (<query-whose-rows-to-count>)`.\r\n */\r\n public async queryRowCount(ecsql: string, params?: QueryBinder): Promise<number> {\r\n for await (const row of this.createQueryReader(`SELECT count(*) FROM (${ecsql})`, params)) {\r\n return row[0] as number;\r\n }\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Failed to get row count\");\r\n }\r\n\r\n /** Cancel any previous query with same token and run execute the current specified query.\r\n * The result of the query is async iterator over the rows. The iterator will get next page automatically once rows in current page has been read.\r\n * [ECSQL row]($docs/learning/ECSQLRowFormat).\r\n *\r\n * See also:\r\n * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)\r\n * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)\r\n *\r\n * @param ecsql The ECSQL statement to execute\r\n * @param token None empty restart token. The previous query with same token would be cancelled. This would cause\r\n * exception which user code must handle.\r\n * @param params The values to bind to the parameters (if the ECSQL has any).\r\n * @param options Allow to specify certain flags which control how query is executed.\r\n * @returns Returns the query result as an *AsyncIterableIterator<any>* which lazy load result as needed. The row format is determined by *rowFormat* parameter.\r\n * See [ECSQL row format]($docs/learning/ECSQLRowFormat) for details about the format of the returned rows.\r\n * @throws [IModelError]($common) If there was any error while submitting, preparing or stepping into query\r\n * @deprecated in 3.7. Use [[createQueryReader]] instead. Pass in the restart token as part of the `config` argument; e.g., `{ restartToken: myToken }` or `new QueryOptionsBuilder().setRestartToken(myToken).getOptions()`.\r\n */\r\n public async * restartQuery(token: string, ecsql: string, params?: QueryBinder, options?: QueryOptions): AsyncIterableIterator<any> {\r\n for await (const row of this.createQueryReader(ecsql, params, new QueryOptionsBuilder(options).setRestartToken(token).getOptions())) {\r\n yield row;\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"ECDb.js","sourceRoot":"","sources":["../../src/ECDb.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module ECDb\r\n */\r\nimport { assert, DbResult, IDisposable, Logger, OpenMode } from \"@itwin/core-bentley\";\r\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\r\nimport { DbQueryRequest, ECSqlReader, IModelError, QueryBinder, QueryOptions, QueryOptionsBuilder } from \"@itwin/core-common\";\r\nimport { BackendLoggerCategory } from \"./BackendLoggerCategory\";\r\nimport { ConcurrentQuery } from \"./ConcurrentQuery\";\r\nimport { ECSqlStatement } from \"./ECSqlStatement\";\r\nimport { IModelHost } from \"./IModelHost\";\r\nimport { SqliteStatement, StatementCache } from \"./SqliteStatement\";\r\n\r\nconst loggerCategory: string = BackendLoggerCategory.ECDb;\r\n\r\n/** Modes for how to open [ECDb]($backend) files.\r\n * @public\r\n */\r\nexport enum ECDbOpenMode {\r\n Readonly,\r\n ReadWrite,\r\n /** Opens the file read-write and upgrades the file if necessary to the latest file format version. */\r\n FileUpgrade,\r\n}\r\n\r\n/** An ECDb file\r\n * @public\r\n */\r\nexport class ECDb implements IDisposable {\r\n private _nativeDb?: IModelJsNative.ECDb;\r\n private readonly _statementCache = new StatementCache<ECSqlStatement>();\r\n private _sqliteStatementCache = new StatementCache<SqliteStatement>();\r\n\r\n /** only for tests\r\n * @internal\r\n */\r\n public resetSqliteCache(size: number) {\r\n this._sqliteStatementCache.clear();\r\n this._sqliteStatementCache = new StatementCache<SqliteStatement>(size);\r\n }\r\n\r\n constructor() {\r\n this._nativeDb = new IModelHost.platform.ECDb();\r\n }\r\n /** Call this function when finished with this ECDb object. This releases the native resources held by the\r\n * ECDb object.\r\n */\r\n public dispose(): void {\r\n if (!this._nativeDb)\r\n return;\r\n\r\n this.closeDb();\r\n this._nativeDb.dispose();\r\n this._nativeDb = undefined;\r\n }\r\n\r\n /** Create an ECDb\r\n * @param pathName The path to the ECDb file to create.\r\n * @throws [IModelError]($common) if the operation failed.\r\n */\r\n public createDb(pathName: string): void {\r\n const status: DbResult = this.nativeDb.createDb(pathName);\r\n if (status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(status, \"Failed to created ECDb\");\r\n }\r\n\r\n /** Open the ECDb.\r\n * @param pathName The path to the ECDb file to open\r\n * @param openMode Open mode\r\n * @throws [IModelError]($common) if the operation failed.\r\n */\r\n public openDb(pathName: string, openMode: ECDbOpenMode = ECDbOpenMode.Readonly): void {\r\n const nativeOpenMode: OpenMode = openMode === ECDbOpenMode.Readonly ? OpenMode.Readonly : OpenMode.ReadWrite;\r\n const tryUpgrade: boolean = openMode === ECDbOpenMode.FileUpgrade;\r\n const status: DbResult = this.nativeDb.openDb(pathName, nativeOpenMode, tryUpgrade);\r\n if (status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(status, \"Failed to open ECDb\");\r\n }\r\n\r\n /** Returns true if the ECDb is open */\r\n public get isOpen(): boolean { return this.nativeDb.isOpen(); }\r\n\r\n /** Close the Db after saving any uncommitted changes.\r\n * @throws [IModelError]($common) if the database is not open.\r\n */\r\n public closeDb(): void {\r\n this._statementCache.clear();\r\n this._sqliteStatementCache.clear();\r\n this.nativeDb.closeDb();\r\n }\r\n\r\n /** @internal use to test statement caching */\r\n public clearStatementCache() {\r\n this._statementCache.clear();\r\n }\r\n\r\n /** @internal use to test statement caching */\r\n public getCachedStatementCount() {\r\n return this._statementCache.size;\r\n }\r\n\r\n /** Commit the outermost transaction, writing changes to the file. Then, restart the transaction.\r\n * @param changesetName The name of the operation that generated these changes.\r\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\r\n */\r\n public saveChanges(changesetName?: string): void {\r\n const status: DbResult = this.nativeDb.saveChanges(changesetName);\r\n if (status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(status, \"Failed to save changes\");\r\n }\r\n\r\n /** Abandon (cancel) the outermost transaction, discarding all changes since last save. Then, restart the transaction.\r\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\r\n */\r\n public abandonChanges(): void {\r\n const status: DbResult = this.nativeDb.abandonChanges();\r\n if (status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(status, \"Failed to abandon changes\");\r\n }\r\n\r\n /** Import a schema.\r\n *\r\n * If the import was successful, the database is automatically saved to disk.\r\n * @param pathName Path to ECSchema XML file to import.\r\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\r\n */\r\n public importSchema(pathName: string): void {\r\n const status: DbResult = this.nativeDb.importSchema(pathName);\r\n if (status !== DbResult.BE_SQLITE_OK) {\r\n Logger.logError(loggerCategory, `Failed to import schema from '${pathName}'.`);\r\n throw new IModelError(status, `Failed to import schema from '${pathName}'.`);\r\n }\r\n }\r\n\r\n /**\r\n * Use a prepared ECSQL statement, potentially from the statement cache. If the requested statement doesn't exist\r\n * in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved\r\n * in the statement cache so it can be reused in the future. Use this method for ECSQL statements that will be\r\n * reused often and are expensive to prepare. The statement cache holds the most recently used statements, discarding\r\n * the oldest statements as it fills. For statements you don't intend to reuse, instead use [[withStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @see [[withStatement]]\r\n * @public\r\n */\r\n public withPreparedStatement<T>(ecsql: string, callback: (stmt: ECSqlStatement) => T, logErrors = true): T {\r\n const stmt = this._statementCache.findAndRemove(ecsql) ?? this.prepareStatement(ecsql, logErrors);\r\n const release = () => this._statementCache.addOrDispose(stmt);\r\n try {\r\n const val = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n\r\n /**\r\n * Prepared and execute a callback on an ECSQL statement. After the callback completes the statement is disposed.\r\n * Use this method for ECSQL statements are either not expected to be reused, or are not expensive to prepare.\r\n * For statements that will be reused often, instead use [[withPreparedStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @see [[withPreparedStatement]]\r\n * @public\r\n */\r\n public withStatement<T>(ecsql: string, callback: (stmt: ECSqlStatement) => T, logErrors = true): T {\r\n const stmt = this.prepareStatement(ecsql, logErrors);\r\n const release = () => stmt.dispose();\r\n try {\r\n const val = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n\r\n /** Prepare an ECSQL statement.\r\n * @param ecsql The ECSQL statement to prepare\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @throws [IModelError]($common) if there is a problem preparing the statement.\r\n */\r\n public prepareStatement(ecsql: string, logErrors = true): ECSqlStatement {\r\n const stmt = new ECSqlStatement();\r\n stmt.prepare(this.nativeDb, ecsql, logErrors);\r\n return stmt;\r\n }\r\n\r\n /**\r\n * Use a prepared SQL statement, potentially from the statement cache. If the requested statement doesn't exist\r\n * in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved\r\n * in the statement cache so it can be reused in the future. Use this method for SQL statements that will be\r\n * reused often and are expensive to prepare. The statement cache holds the most recently used statements, discarding\r\n * the oldest statements as it fills. For statements you don't intend to reuse, instead use [[withSqliteStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @see [[withPreparedStatement]]\r\n * @public\r\n */\r\n public withPreparedSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T, logErrors = true): T {\r\n const stmt = this._sqliteStatementCache.findAndRemove(sql) ?? this.prepareSqliteStatement(sql, logErrors);\r\n const release = () => this._sqliteStatementCache.addOrDispose(stmt);\r\n try {\r\n const val: T = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n\r\n /**\r\n * Prepared and execute a callback on a SQL statement. After the callback completes the statement is disposed.\r\n * Use this method for SQL statements are either not expected to be reused, or are not expensive to prepare.\r\n * For statements that will be reused often, instead use [[withPreparedSqliteStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @public\r\n */\r\n public withSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T, logErrors = true): T {\r\n const stmt = this.prepareSqliteStatement(sql, logErrors);\r\n const release = () => stmt.dispose();\r\n try {\r\n const val: T = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n\r\n /** Prepare an SQL statement.\r\n * @param sql The SQLite SQL statement to prepare\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @throws [IModelError]($common) if there is a problem preparing the statement.\r\n * @internal\r\n */\r\n public prepareSqliteStatement(sql: string, logErrors = true): SqliteStatement {\r\n const stmt = new SqliteStatement(sql);\r\n stmt.prepare(this.nativeDb, logErrors);\r\n return stmt;\r\n }\r\n\r\n /** @internal */\r\n public get nativeDb(): IModelJsNative.ECDb {\r\n assert(undefined !== this._nativeDb);\r\n return this._nativeDb;\r\n }\r\n\r\n /** Allow to execute query and read results along with meta data. The result are streamed.\r\n * @param params The values to bind to the parameters (if the ECSQL has any).\r\n * @param config Allow to specify certain flags which control how query is executed.\r\n * @returns Returns an [ECSqlReader]($common) which helps iterate over the result set and also give access to metadata.\r\n * @beta\r\n * */\r\n public createQueryReader(ecsql: string, params?: QueryBinder, config?: QueryOptions): ECSqlReader {\r\n if (!this._nativeDb || !this._nativeDb.isOpen()) {\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"db not open\");\r\n }\r\n const executor = {\r\n execute: async (request: DbQueryRequest) => {\r\n return ConcurrentQuery.executeQueryRequest(this.nativeDb, request);\r\n },\r\n };\r\n return new ECSqlReader(executor, ecsql, params, config);\r\n }\r\n\r\n /** Execute a query and stream its results\r\n * The result of the query is async iterator over the rows. The iterator will get next page automatically once rows in current page has been read.\r\n * [ECSQL row]($docs/learning/ECSQLRowFormat).\r\n *\r\n * See also:\r\n * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)\r\n * - [Code Examples]($docs/learning/ECSQLCodeExamples)\r\n *\r\n * @param ecsql The ECSQL statement to execute\r\n * @param params The values to bind to the parameters (if the ECSQL has any).\r\n * @param options Allow to specify certain flags which control how query is executed.\r\n * @returns Returns the query result as an *AsyncIterableIterator<any>* which lazy load result as needed. The row format is determined by *rowFormat* parameter.\r\n * See [ECSQL row format]($docs/learning/ECSQLRowFormat) for details about the format of the returned rows.\r\n * @throws [IModelError]($common) If there was any error while submitting, preparing or stepping into query\r\n * @deprecated in 3.7. Use [[createQueryReader]] instead; it accepts the same parameters.\r\n */\r\n public async * query(ecsql: string, params?: QueryBinder, options?: QueryOptions): AsyncIterableIterator<any> {\r\n const builder = new QueryOptionsBuilder(options);\r\n const reader = this.createQueryReader(ecsql, params, builder.getOptions());\r\n while (await reader.step())\r\n yield reader.formatCurrentRow();\r\n }\r\n /** Compute number of rows that would be returned by the ECSQL.\r\n *\r\n * See also:\r\n * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)\r\n * - [Code Examples]($docs/learning/ECSQLCodeExamples)\r\n *\r\n * @param ecsql The ECSQL statement to execute\r\n * @param params The values to bind to the parameters (if the ECSQL has any).\r\n * See \"[iTwin.js Types used in ECSQL Parameter Bindings]($docs/learning/ECSQLParameterTypes)\" for details.\r\n * @returns Return row count.\r\n * @throws [IModelError]($common) If the statement is invalid\r\n * @deprecated in 3.7. Count the number of results using `count(*)` where the original query is a subquery instead. E.g., `SELECT count(*) FROM (<query-whose-rows-to-count>)`.\r\n */\r\n public async queryRowCount(ecsql: string, params?: QueryBinder): Promise<number> {\r\n for await (const row of this.createQueryReader(`SELECT count(*) FROM (${ecsql})`, params)) {\r\n return row[0] as number;\r\n }\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Failed to get row count\");\r\n }\r\n\r\n /** Cancel any previous query with same token and run execute the current specified query.\r\n * The result of the query is async iterator over the rows. The iterator will get next page automatically once rows in current page has been read.\r\n * [ECSQL row]($docs/learning/ECSQLRowFormat).\r\n *\r\n * See also:\r\n * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)\r\n * - [Code Examples]($docs/learning/ECSQLCodeExamples)\r\n *\r\n * @param ecsql The ECSQL statement to execute\r\n * @param token None empty restart token. The previous query with same token would be cancelled. This would cause\r\n * exception which user code must handle.\r\n * @param params The values to bind to the parameters (if the ECSQL has any).\r\n * @param options Allow to specify certain flags which control how query is executed.\r\n * @returns Returns the query result as an *AsyncIterableIterator<any>* which lazy load result as needed. The row format is determined by *rowFormat* parameter.\r\n * See [ECSQL row format]($docs/learning/ECSQLRowFormat) for details about the format of the returned rows.\r\n * @throws [IModelError]($common) If there was any error while submitting, preparing or stepping into query\r\n * @deprecated in 3.7. Use [[createQueryReader]] instead. Pass in the restart token as part of the `config` argument; e.g., `{ restartToken: myToken }` or `new QueryOptionsBuilder().setRestartToken(myToken).getOptions()`.\r\n */\r\n public async * restartQuery(token: string, ecsql: string, params?: QueryBinder, options?: QueryOptions): AsyncIterableIterator<any> {\r\n for await (const row of this.createQueryReader(ecsql, params, new QueryOptionsBuilder(options).setRestartToken(token).getOptions())) {\r\n yield row;\r\n }\r\n }\r\n}\r\n"]}
@@ -291,7 +291,7 @@ export declare abstract class IModelDb extends IModel {
291
291
  *
292
292
  * See also:
293
293
  * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)
294
- * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)
294
+ * - [Code Examples]($docs/learning/ECSQLCodeExamples)
295
295
  *
296
296
  * @param ecsql The ECSQL statement to execute
297
297
  * @param params The values to bind to the parameters (if the ECSQL has any).
@@ -306,7 +306,7 @@ export declare abstract class IModelDb extends IModel {
306
306
  *
307
307
  * See also:
308
308
  * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)
309
- * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)
309
+ * - [Code Examples]($docs/learning/ECSQLCodeExamples)
310
310
  *
311
311
  * @param ecsql The ECSQL statement to execute
312
312
  * @param params The values to bind to the parameters (if the ECSQL has any).
@@ -322,7 +322,7 @@ export declare abstract class IModelDb extends IModel {
322
322
  *
323
323
  * See also:
324
324
  * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)
325
- * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)
325
+ * - [Code Examples]($docs/learning/ECSQLCodeExamples)
326
326
  *
327
327
  * @param ecsql The ECSQL statement to execute
328
328
  * @param token None empty restart token. The previous query with same token would be cancelled. This would cause
@@ -340,7 +340,7 @@ class IModelDb extends core_common_1.IModel {
340
340
  *
341
341
  * See also:
342
342
  * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)
343
- * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)
343
+ * - [Code Examples]($docs/learning/ECSQLCodeExamples)
344
344
  *
345
345
  * @param ecsql The ECSQL statement to execute
346
346
  * @param params The values to bind to the parameters (if the ECSQL has any).
@@ -360,7 +360,7 @@ class IModelDb extends core_common_1.IModel {
360
360
  *
361
361
  * See also:
362
362
  * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)
363
- * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)
363
+ * - [Code Examples]($docs/learning/ECSQLCodeExamples)
364
364
  *
365
365
  * @param ecsql The ECSQL statement to execute
366
366
  * @param params The values to bind to the parameters (if the ECSQL has any).
@@ -381,7 +381,7 @@ class IModelDb extends core_common_1.IModel {
381
381
  *
382
382
  * See also:
383
383
  * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)
384
- * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)
384
+ * - [Code Examples]($docs/learning/ECSQLCodeExamples)
385
385
  *
386
386
  * @param ecsql The ECSQL statement to execute
387
387
  * @param token None empty restart token. The previous query with same token would be cancelled. This would cause