@itwin/core-backend 5.13.0-dev.8 → 5.13.0
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.
- package/CHANGELOG.md +53 -1
- package/lib/cjs/BriefcaseManager.d.ts.map +1 -1
- package/lib/cjs/BriefcaseManager.js +11 -5
- package/lib/cjs/BriefcaseManager.js.map +1 -1
- package/lib/cjs/Category.d.ts +4 -4
- package/lib/cjs/Category.js.map +1 -1
- package/lib/cjs/ChangesetECAdaptor.d.ts +5 -0
- package/lib/cjs/ChangesetECAdaptor.d.ts.map +1 -1
- package/lib/cjs/ChangesetECAdaptor.js +13 -3
- package/lib/cjs/ChangesetECAdaptor.js.map +1 -1
- package/lib/cjs/CloudSqlite.d.ts.map +1 -1
- package/lib/cjs/CloudSqlite.js +9 -2
- package/lib/cjs/CloudSqlite.js.map +1 -1
- package/lib/cjs/CodeSpecs.d.ts +3 -3
- package/lib/cjs/CodeSpecs.js.map +1 -1
- package/lib/cjs/DisplayStyle.d.ts +2 -2
- package/lib/cjs/DisplayStyle.js.map +1 -1
- package/lib/cjs/ECDb.d.ts.map +1 -1
- package/lib/cjs/ECDb.js +1 -0
- package/lib/cjs/ECDb.js.map +1 -1
- package/lib/cjs/EditTxn.d.ts.map +1 -1
- package/lib/cjs/EditTxn.js +1 -0
- package/lib/cjs/EditTxn.js.map +1 -1
- package/lib/cjs/Element.d.ts +48 -12
- package/lib/cjs/Element.d.ts.map +1 -1
- package/lib/cjs/Element.js +120 -24
- package/lib/cjs/Element.js.map +1 -1
- package/lib/cjs/IModelDb.d.ts +72 -22
- package/lib/cjs/IModelDb.d.ts.map +1 -1
- package/lib/cjs/IModelDb.js +226 -89
- package/lib/cjs/IModelDb.js.map +1 -1
- package/lib/cjs/Model.d.ts +5 -5
- package/lib/cjs/Model.d.ts.map +1 -1
- package/lib/cjs/Model.js.map +1 -1
- package/lib/cjs/PropertyStore.js +1 -1
- package/lib/cjs/PropertyStore.js.map +1 -1
- package/lib/cjs/SchemaSync.d.ts +158 -22
- package/lib/cjs/SchemaSync.d.ts.map +1 -1
- package/lib/cjs/SchemaSync.js +417 -76
- package/lib/cjs/SchemaSync.js.map +1 -1
- package/lib/cjs/SynchronousChannel.d.ts +72 -0
- package/lib/cjs/SynchronousChannel.d.ts.map +1 -0
- package/lib/cjs/SynchronousChannel.js +11 -0
- package/lib/cjs/SynchronousChannel.js.map +1 -0
- package/lib/cjs/Texture.d.ts +1 -1
- package/lib/cjs/Texture.js.map +1 -1
- package/lib/cjs/TxnManager.d.ts +44 -4
- package/lib/cjs/TxnManager.d.ts.map +1 -1
- package/lib/cjs/TxnManager.js +80 -19
- package/lib/cjs/TxnManager.js.map +1 -1
- package/lib/cjs/ViewDefinition.d.ts +6 -6
- package/lib/cjs/ViewDefinition.d.ts.map +1 -1
- package/lib/cjs/ViewDefinition.js.map +1 -1
- package/lib/cjs/annotations/LeaderGeometry.d.ts +22 -7
- package/lib/cjs/annotations/LeaderGeometry.d.ts.map +1 -1
- package/lib/cjs/annotations/LeaderGeometry.js +104 -36
- package/lib/cjs/annotations/LeaderGeometry.js.map +1 -1
- package/lib/cjs/annotations/TextAnnotationElement.d.ts +1 -1
- package/lib/cjs/annotations/TextAnnotationElement.d.ts.map +1 -1
- package/lib/cjs/annotations/TextAnnotationElement.js +25 -10
- package/lib/cjs/annotations/TextAnnotationElement.js.map +1 -1
- package/lib/cjs/core-backend.d.ts +1 -0
- package/lib/cjs/core-backend.d.ts.map +1 -1
- package/lib/cjs/core-backend.js +1 -0
- package/lib/cjs/core-backend.js.map +1 -1
- package/lib/cjs/internal/IntegrityCheck.d.ts +22 -0
- package/lib/cjs/internal/IntegrityCheck.d.ts.map +1 -1
- package/lib/cjs/internal/IntegrityCheck.js +13 -0
- package/lib/cjs/internal/IntegrityCheck.js.map +1 -1
- package/lib/cjs/internal/NoReservations.d.ts +6 -0
- package/lib/cjs/internal/NoReservations.d.ts.map +1 -0
- package/lib/cjs/internal/NoReservations.js +21 -0
- package/lib/cjs/internal/NoReservations.js.map +1 -0
- package/lib/cjs/internal/SchemaSyncReservations.d.ts +4 -0
- package/lib/cjs/internal/SchemaSyncReservations.d.ts.map +1 -0
- package/lib/cjs/internal/SchemaSyncReservations.js +128 -0
- package/lib/cjs/internal/SchemaSyncReservations.js.map +1 -0
- package/lib/cjs/internal/Symbols.d.ts +1 -0
- package/lib/cjs/internal/Symbols.d.ts.map +1 -1
- package/lib/cjs/internal/Symbols.js +2 -1
- package/lib/cjs/internal/Symbols.js.map +1 -1
- package/lib/esm/BriefcaseManager.d.ts.map +1 -1
- package/lib/esm/BriefcaseManager.js +11 -5
- package/lib/esm/BriefcaseManager.js.map +1 -1
- package/lib/esm/Category.d.ts +4 -4
- package/lib/esm/Category.js.map +1 -1
- package/lib/esm/ChangesetECAdaptor.d.ts +5 -0
- package/lib/esm/ChangesetECAdaptor.d.ts.map +1 -1
- package/lib/esm/ChangesetECAdaptor.js +13 -3
- package/lib/esm/ChangesetECAdaptor.js.map +1 -1
- package/lib/esm/CloudSqlite.d.ts.map +1 -1
- package/lib/esm/CloudSqlite.js +10 -3
- package/lib/esm/CloudSqlite.js.map +1 -1
- package/lib/esm/CodeSpecs.d.ts +3 -3
- package/lib/esm/CodeSpecs.js.map +1 -1
- package/lib/esm/DisplayStyle.d.ts +2 -2
- package/lib/esm/DisplayStyle.js.map +1 -1
- package/lib/esm/ECDb.d.ts.map +1 -1
- package/lib/esm/ECDb.js +1 -0
- package/lib/esm/ECDb.js.map +1 -1
- package/lib/esm/EditTxn.d.ts.map +1 -1
- package/lib/esm/EditTxn.js +1 -0
- package/lib/esm/EditTxn.js.map +1 -1
- package/lib/esm/Element.d.ts +48 -12
- package/lib/esm/Element.d.ts.map +1 -1
- package/lib/esm/Element.js +121 -25
- package/lib/esm/Element.js.map +1 -1
- package/lib/esm/IModelDb.d.ts +72 -22
- package/lib/esm/IModelDb.d.ts.map +1 -1
- package/lib/esm/IModelDb.js +227 -90
- package/lib/esm/IModelDb.js.map +1 -1
- package/lib/esm/Model.d.ts +5 -5
- package/lib/esm/Model.d.ts.map +1 -1
- package/lib/esm/Model.js.map +1 -1
- package/lib/esm/PropertyStore.js +1 -1
- package/lib/esm/PropertyStore.js.map +1 -1
- package/lib/esm/SchemaSync.d.ts +158 -22
- package/lib/esm/SchemaSync.d.ts.map +1 -1
- package/lib/esm/SchemaSync.js +419 -78
- package/lib/esm/SchemaSync.js.map +1 -1
- package/lib/esm/SynchronousChannel.d.ts +72 -0
- package/lib/esm/SynchronousChannel.d.ts.map +1 -0
- package/lib/esm/SynchronousChannel.js +9 -0
- package/lib/esm/SynchronousChannel.js.map +1 -0
- package/lib/esm/Texture.d.ts +1 -1
- package/lib/esm/Texture.js.map +1 -1
- package/lib/esm/TxnManager.d.ts +44 -4
- package/lib/esm/TxnManager.d.ts.map +1 -1
- package/lib/esm/TxnManager.js +81 -20
- package/lib/esm/TxnManager.js.map +1 -1
- package/lib/esm/ViewDefinition.d.ts +6 -6
- package/lib/esm/ViewDefinition.d.ts.map +1 -1
- package/lib/esm/ViewDefinition.js.map +1 -1
- package/lib/esm/annotations/LeaderGeometry.d.ts +22 -7
- package/lib/esm/annotations/LeaderGeometry.d.ts.map +1 -1
- package/lib/esm/annotations/LeaderGeometry.js +104 -36
- package/lib/esm/annotations/LeaderGeometry.js.map +1 -1
- package/lib/esm/annotations/TextAnnotationElement.d.ts +1 -1
- package/lib/esm/annotations/TextAnnotationElement.d.ts.map +1 -1
- package/lib/esm/annotations/TextAnnotationElement.js +25 -10
- package/lib/esm/annotations/TextAnnotationElement.js.map +1 -1
- package/lib/esm/core-backend.d.ts +1 -0
- package/lib/esm/core-backend.d.ts.map +1 -1
- package/lib/esm/core-backend.js +1 -0
- package/lib/esm/core-backend.js.map +1 -1
- package/lib/esm/internal/IntegrityCheck.d.ts +22 -0
- package/lib/esm/internal/IntegrityCheck.d.ts.map +1 -1
- package/lib/esm/internal/IntegrityCheck.js +13 -0
- package/lib/esm/internal/IntegrityCheck.js.map +1 -1
- package/lib/esm/internal/NoReservations.d.ts +6 -0
- package/lib/esm/internal/NoReservations.d.ts.map +1 -0
- package/lib/esm/internal/NoReservations.js +18 -0
- package/lib/esm/internal/NoReservations.js.map +1 -0
- package/lib/esm/internal/SchemaSyncReservations.d.ts +4 -0
- package/lib/esm/internal/SchemaSyncReservations.d.ts.map +1 -0
- package/lib/esm/internal/SchemaSyncReservations.js +125 -0
- package/lib/esm/internal/SchemaSyncReservations.js.map +1 -0
- package/lib/esm/internal/Symbols.d.ts +1 -0
- package/lib/esm/internal/Symbols.d.ts.map +1 -1
- package/lib/esm/internal/Symbols.js +1 -0
- package/lib/esm/internal/Symbols.js.map +1 -1
- package/lib/esm/test/IModelTestUtils.d.ts +1 -1
- package/lib/esm/test/IModelTestUtils.d.ts.map +1 -1
- package/lib/esm/test/IModelTestUtils.js +8 -3
- package/lib/esm/test/IModelTestUtils.js.map +1 -1
- package/lib/esm/test/annotations/LeaderGeometry.test.js +178 -2
- package/lib/esm/test/annotations/LeaderGeometry.test.js.map +1 -1
- package/lib/esm/test/annotations/TextAnnotation.test.js +48 -18
- package/lib/esm/test/annotations/TextAnnotation.test.js.map +1 -1
- package/lib/esm/test/ecdb/ECSqlStatement.test.js +177 -0
- package/lib/esm/test/ecdb/ECSqlStatement.test.js.map +1 -1
- package/lib/esm/test/ecdb/QueryReaders.test.js +2 -16
- package/lib/esm/test/ecdb/QueryReaders.test.js.map +1 -1
- package/lib/esm/test/ecsql/src/ECSqlTestRunner.test.js +2 -2
- package/lib/esm/test/ecsql/src/ECSqlTestRunner.test.js.map +1 -1
- package/lib/esm/test/element/ElementRoundTrip.test.js +80 -2
- package/lib/esm/test/element/ElementRoundTrip.test.js.map +1 -1
- package/lib/esm/test/hubaccess/Rebase.test.js +3 -1
- package/lib/esm/test/hubaccess/Rebase.test.js.map +1 -1
- package/lib/esm/test/hubaccess/SemanticRebase.test.js +29 -28
- package/lib/esm/test/hubaccess/SemanticRebase.test.js.map +1 -1
- package/lib/esm/test/hubaccess/SemanticRebaseTestUtils.d.ts +3 -0
- package/lib/esm/test/hubaccess/SemanticRebaseTestUtils.d.ts.map +1 -0
- package/lib/esm/test/hubaccess/SemanticRebaseTestUtils.js +15 -0
- package/lib/esm/test/hubaccess/SemanticRebaseTestUtils.js.map +1 -0
- package/lib/esm/test/imodel/IModelECSql.test.d.ts +2 -0
- package/lib/esm/test/imodel/IModelECSql.test.d.ts.map +1 -0
- package/lib/esm/test/imodel/IModelECSql.test.js +367 -0
- package/lib/esm/test/imodel/IModelECSql.test.js.map +1 -0
- package/lib/esm/test/imodel/IModelElements.test.d.ts +2 -0
- package/lib/esm/test/imodel/IModelElements.test.d.ts.map +1 -0
- package/lib/esm/test/imodel/IModelElements.test.js +969 -0
- package/lib/esm/test/imodel/IModelElements.test.js.map +1 -0
- package/lib/esm/test/imodel/IModelGeolocation.test.d.ts +2 -0
- package/lib/esm/test/imodel/IModelGeolocation.test.d.ts.map +1 -0
- package/lib/esm/test/imodel/IModelGeolocation.test.js +539 -0
- package/lib/esm/test/imodel/IModelGeolocation.test.js.map +1 -0
- package/lib/esm/test/imodel/IModelLifecycle.test.d.ts +2 -0
- package/lib/esm/test/imodel/IModelLifecycle.test.d.ts.map +1 -0
- package/lib/esm/test/imodel/IModelLifecycle.test.js +499 -0
- package/lib/esm/test/imodel/IModelLifecycle.test.js.map +1 -0
- package/lib/esm/test/imodel/IModelMetadata.test.d.ts +2 -0
- package/lib/esm/test/imodel/IModelMetadata.test.d.ts.map +1 -0
- package/lib/esm/test/imodel/IModelMetadata.test.js +274 -0
- package/lib/esm/test/imodel/IModelMetadata.test.js.map +1 -0
- package/lib/esm/test/imodel/IModelModels.test.d.ts +2 -0
- package/lib/esm/test/imodel/IModelModels.test.d.ts.map +1 -0
- package/lib/esm/test/imodel/IModelModels.test.js +357 -0
- package/lib/esm/test/imodel/IModelModels.test.js.map +1 -0
- package/lib/esm/test/imodel/IModelRelationships.test.d.ts +2 -0
- package/lib/esm/test/imodel/IModelRelationships.test.d.ts.map +1 -0
- package/lib/esm/test/imodel/IModelRelationships.test.js +407 -0
- package/lib/esm/test/imodel/IModelRelationships.test.js.map +1 -0
- package/lib/esm/test/imodel/IModelTestFixtures.d.ts +53 -0
- package/lib/esm/test/imodel/IModelTestFixtures.d.ts.map +1 -0
- package/lib/esm/test/imodel/IModelTestFixtures.js +107 -0
- package/lib/esm/test/imodel/IModelTestFixtures.js.map +1 -0
- package/lib/esm/test/imodel/IModelViews.test.d.ts +2 -0
- package/lib/esm/test/imodel/IModelViews.test.d.ts.map +1 -0
- package/lib/esm/test/imodel/IModelViews.test.js +199 -0
- package/lib/esm/test/imodel/IModelViews.test.js.map +1 -0
- package/lib/esm/test/index.d.ts +0 -1
- package/lib/esm/test/index.d.ts.map +1 -1
- package/lib/esm/test/index.js +0 -1
- package/lib/esm/test/index.js.map +1 -1
- package/lib/esm/test/standalone/ChangesetReader.test.js +8 -26
- package/lib/esm/test/standalone/ChangesetReader.test.js.map +1 -1
- package/lib/esm/test/standalone/DgnDomainMergeConflict.test.d.ts +2 -0
- package/lib/esm/test/standalone/DgnDomainMergeConflict.test.d.ts.map +1 -0
- package/lib/esm/test/standalone/DgnDomainMergeConflict.test.js +263 -0
- package/lib/esm/test/standalone/DgnDomainMergeConflict.test.js.map +1 -0
- package/lib/esm/test/standalone/GeometryStream.test.js +1 -3
- package/lib/esm/test/standalone/GeometryStream.test.js.map +1 -1
- package/lib/esm/test/standalone/IModelWrite.test.d.ts.map +1 -1
- package/lib/esm/test/standalone/IModelWrite.test.js +78 -1
- package/lib/esm/test/standalone/IModelWrite.test.js.map +1 -1
- package/lib/esm/test/standalone/IntegrityCheck.test.js +29 -10
- package/lib/esm/test/standalone/IntegrityCheck.test.js.map +1 -1
- package/lib/esm/test/standalone/SQliteChangesetReaderAndChangesetECAdaptor.test.js +23 -0
- package/lib/esm/test/standalone/SQliteChangesetReaderAndChangesetECAdaptor.test.js.map +1 -1
- package/lib/esm/test/standalone/SchemaSyncDb.test.d.ts +2 -0
- package/lib/esm/test/standalone/SchemaSyncDb.test.d.ts.map +1 -0
- package/lib/esm/test/standalone/SchemaSyncDb.test.js +201 -0
- package/lib/esm/test/standalone/SchemaSyncDb.test.js.map +1 -0
- package/lib/esm/test/standalone/SchemaSyncElementReservation.test.d.ts +2 -0
- package/lib/esm/test/standalone/SchemaSyncElementReservation.test.d.ts.map +1 -0
- package/lib/esm/test/standalone/SchemaSyncElementReservation.test.js +460 -0
- package/lib/esm/test/standalone/SchemaSyncElementReservation.test.js.map +1 -0
- package/lib/esm/test/standalone/SnapshotDb.test.js +1 -0
- package/lib/esm/test/standalone/SnapshotDb.test.js.map +1 -1
- package/lib/esm/test/standalone/TxnManager.test.js +108 -8
- package/lib/esm/test/standalone/TxnManager.test.js.map +1 -1
- package/package.json +14 -17
- package/lib/esm/test/RevisionUtility.d.ts +0 -33
- package/lib/esm/test/RevisionUtility.d.ts.map +0 -1
- package/lib/esm/test/RevisionUtility.js +0 -52
- package/lib/esm/test/RevisionUtility.js.map +0 -1
- package/lib/esm/test/imodel/IModel.test.d.ts +0 -2
- package/lib/esm/test/imodel/IModel.test.d.ts.map +0 -1
- package/lib/esm/test/imodel/IModel.test.js +0 -3277
- package/lib/esm/test/imodel/IModel.test.js.map +0 -1
package/lib/esm/IModelDb.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import * as fs from "fs";
|
|
9
9
|
import { join } from "path";
|
|
10
10
|
import * as touch from "touch";
|
|
11
|
-
import { assert, BeEvent, BentleyStatus, ChangeSetStatus, DbChangeStage, DbConflictCause, DbConflictResolution, DbResult, Guid, Id64, IModelStatus, JsonUtils, Logger, LogLevel, LRUMap, OpenMode } from "@itwin/core-bentley";
|
|
11
|
+
import { assert, BeEvent, BentleyStatus, ChangeSetStatus, DbChangeStage, DbConflictCause, DbConflictResolution, DbOpcode, DbResult, Guid, Id64, IModelStatus, JsonUtils, Logger, LogLevel, LRUMap, OpenMode } from "@itwin/core-bentley";
|
|
12
12
|
import { Base64EncodedString, BriefcaseIdValue, Code, DomainOptions, ECJsNames, ECSqlReader, EditTxnError, EntityMetaData, FontMap, IModel, IModelError, IModelNotFoundResponse, ProfileOptions, QueryBinder, QueryRowFormat, resolveNavPropId, SchemaState, ViewStoreError, ViewStoreRpc } from "@itwin/core-common";
|
|
13
13
|
import { Range2d, Range3d } from "@itwin/core-geometry";
|
|
14
14
|
import { BackendLoggerCategory } from "./BackendLoggerCategory";
|
|
@@ -45,7 +45,9 @@ import { constructWorkspace, throwWorkspaceDbLoadErrors } from "./internal/works
|
|
|
45
45
|
import { SettingsImpl } from "./internal/workspace/SettingsImpl";
|
|
46
46
|
import { IModelNative } from "./internal/NativePlatform";
|
|
47
47
|
import { createNoOpLockControl } from "./internal/NoLocks";
|
|
48
|
+
import { createNoOpReservations } from "./internal/NoReservations";
|
|
48
49
|
import { createIModelDbFonts } from "./internal/IModelDbFontsImpl";
|
|
50
|
+
import { createSchemaSyncReservations } from "./internal/SchemaSyncReservations";
|
|
49
51
|
import { _activeTxn, _cache, _close, _hubAccess, _implicitTxn, _instanceKeyCache, _nativeDb, _releaseAllLocks, _resetIModelDb } from "./internal/Symbols";
|
|
50
52
|
import { ECVersion, SchemaContext, SchemaJsonLocater, SchemaManifest, SchemaViewManager } from "@itwin/ecschema-metadata";
|
|
51
53
|
import { SchemaMap } from "./Schema";
|
|
@@ -175,6 +177,8 @@ export class IModelDb extends IModel {
|
|
|
175
177
|
/** @internal */
|
|
176
178
|
_locks = createNoOpLockControl();
|
|
177
179
|
/** @internal */
|
|
180
|
+
_reservations = createNoOpReservations();
|
|
181
|
+
/** @internal */
|
|
178
182
|
_codeService;
|
|
179
183
|
/**
|
|
180
184
|
* The always-available implicit transaction for this iModel.
|
|
@@ -203,6 +207,16 @@ export class IModelDb extends IModel {
|
|
|
203
207
|
get codeService() { return this._codeService; }
|
|
204
208
|
/** The [[LockControl]] that orchestrates [concurrent editing]($docs/learning/backend/ConcurrencyControl.md) of this iModel. */
|
|
205
209
|
get locks() { return this._locks; } // eslint-disable-line @typescript-eslint/no-non-null-assertion
|
|
210
|
+
/** @beta The [[SynchronousChannel.Reservations]] that orchestrates [concurrent editing]($docs/learning/backend/ConcurrencyControl.md) of this iModel. */
|
|
211
|
+
get reservations() { return this._reservations; } // eslint-disable-line @typescript-eslint/no-non-null-assertion
|
|
212
|
+
/** @internal */
|
|
213
|
+
async initializeSharedElementReservations() {
|
|
214
|
+
this._reservations?.[_close]();
|
|
215
|
+
if (SchemaSync.isEnabled(this))
|
|
216
|
+
this._reservations = await createSchemaSyncReservations(this);
|
|
217
|
+
else
|
|
218
|
+
this._reservations = createNoOpReservations();
|
|
219
|
+
}
|
|
206
220
|
/** Provides methods for interacting with [font-related information]($docs/learning/backend/Fonts.md) stored in this iModel.
|
|
207
221
|
* @beta
|
|
208
222
|
*/
|
|
@@ -303,7 +317,9 @@ export class IModelDb extends IModel {
|
|
|
303
317
|
db[_nativeDb].abandonChanges();
|
|
304
318
|
db.close();
|
|
305
319
|
}
|
|
306
|
-
catch {
|
|
320
|
+
catch {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
307
323
|
});
|
|
308
324
|
});
|
|
309
325
|
}
|
|
@@ -363,16 +379,26 @@ export class IModelDb extends IModel {
|
|
|
363
379
|
this.views[_close]();
|
|
364
380
|
this.locks[_close]();
|
|
365
381
|
this._locks = undefined;
|
|
382
|
+
this.reservations[_close]();
|
|
383
|
+
this._reservations = undefined;
|
|
366
384
|
this._codeService?.close();
|
|
367
385
|
this._codeService = undefined;
|
|
368
386
|
this[_nativeDb].closeFile();
|
|
369
387
|
}
|
|
388
|
+
/**
|
|
389
|
+
* Save any unsaved schema changes in this iModel.
|
|
390
|
+
* @internal
|
|
391
|
+
*/
|
|
370
392
|
saveSchemaChanges(args) {
|
|
371
393
|
if (!this[_nativeDb].hasUnsavedChanges())
|
|
372
394
|
return;
|
|
373
395
|
const saveArgs = typeof args === "string" ? { description: args } : args;
|
|
374
396
|
saveArgs === undefined ? this[_nativeDb].saveChanges() : this[_nativeDb].saveChanges(JSON.stringify(saveArgs));
|
|
375
397
|
}
|
|
398
|
+
/**
|
|
399
|
+
* Abandon any unsaved schema changes in this iModel.
|
|
400
|
+
* @internal
|
|
401
|
+
*/
|
|
376
402
|
abandonSchemaChanges() {
|
|
377
403
|
if (!this[_nativeDb].hasUnsavedChanges())
|
|
378
404
|
return;
|
|
@@ -919,7 +945,7 @@ export class IModelDb extends IModel {
|
|
|
919
945
|
async dropSchemas(schemaNames) {
|
|
920
946
|
if (schemaNames.length === 0)
|
|
921
947
|
return;
|
|
922
|
-
if (
|
|
948
|
+
if (SchemaSync.isEnabled(this))
|
|
923
949
|
throw new IModelError(DbResult.BE_SQLITE_ERROR, "Cannot drop schemas when schema sync is enabled");
|
|
924
950
|
if (this[_nativeDb].hasUnsavedChanges())
|
|
925
951
|
throw new IModelError(ChangeSetStatus.HasUncommittedChanges, "Cannot drop schemas with unsaved changes");
|
|
@@ -1005,26 +1031,34 @@ export class IModelDb extends IModel {
|
|
|
1005
1031
|
this.cleanupSnapshot(context.resources);
|
|
1006
1032
|
}
|
|
1007
1033
|
}
|
|
1008
|
-
/**
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1034
|
+
/** Refuse a schema import this briefcase is in no state to run. Shared by [[importSchemas]] and
|
|
1035
|
+
* [[BriefcaseDb.upgradeSchemas]], which reach the native importer by different routes.
|
|
1036
|
+
* @internal
|
|
1037
|
+
*/
|
|
1038
|
+
assertCanImportSchemas() {
|
|
1039
|
+
if (!this.isBriefcaseDb())
|
|
1040
|
+
return;
|
|
1041
|
+
if (this.txns.rebaser.isRebasing) {
|
|
1042
|
+
throw new IModelError(IModelStatus.BadRequest, "Cannot import schemas while rebasing");
|
|
1043
|
+
}
|
|
1044
|
+
if (this.txns.isIndirectChanges) {
|
|
1045
|
+
throw new IModelError(IModelStatus.BadRequest, "Cannot import schemas while in an indirect change scope");
|
|
1046
|
+
}
|
|
1047
|
+
// Additional checks when semantic rebase is enabled
|
|
1048
|
+
if (IModelHost.useSemanticRebase) {
|
|
1049
|
+
if (this[_nativeDb].hasUnsavedChanges()) {
|
|
1050
|
+
throw new IModelError(IModelStatus.BadRequest, "Cannot import schemas with unsaved changes when useSemanticRebase flag is on");
|
|
1051
|
+
}
|
|
1052
|
+
if (SchemaSync.isEnabled(this)) {
|
|
1053
|
+
throw new IModelError(IModelStatus.BadRequest, "Cannot import schemas when schema sync is enabled and also useSemanticRebase flag is on");
|
|
1026
1054
|
}
|
|
1027
1055
|
}
|
|
1056
|
+
}
|
|
1057
|
+
/** Shared implementation for importing schemas from file or string.
|
|
1058
|
+
* @internal
|
|
1059
|
+
*/
|
|
1060
|
+
async importSchemasInternal(schemas, options, nativeImportOp) {
|
|
1061
|
+
this.assertCanImportSchemas();
|
|
1028
1062
|
if (options?.channelUpgrade) {
|
|
1029
1063
|
const channelUpgrade = options.channelUpgrade;
|
|
1030
1064
|
try {
|
|
@@ -1042,30 +1076,52 @@ export class IModelDb extends IModel {
|
|
|
1042
1076
|
if (options?.schemaImportCallbacks?.preSchemaImportCallback)
|
|
1043
1077
|
preSchemaImportCallbackResult = await this.preSchemaImportCallback(options.schemaImportCallbacks, { iModel: this, data: options.data, schemaData: schemas });
|
|
1044
1078
|
const maybeCustomNativeContext = options?.ecSchemaXmlContext?.nativeContext;
|
|
1045
|
-
if (
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
this.
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1079
|
+
if (SchemaSync.isEnabled(this)) {
|
|
1080
|
+
// The shared lock lets concurrent updates through while blocking anyone taking the exclusive lock for an upgrade.
|
|
1081
|
+
if (this[_nativeDb].getITwinId() !== Guid.empty)
|
|
1082
|
+
await this.locks.acquireLocks({ shared: IModel.repositoryModelId });
|
|
1083
|
+
// The native import adopts rows from the attached SchemaSyncDb. Attach and detach commit
|
|
1084
|
+
// implicitly, so abandoning changes cannot undo the adoption. A later failure must roll the
|
|
1085
|
+
// briefcase back before those ec_ rows can be pushed.
|
|
1086
|
+
let txnBeforeAdopt;
|
|
1087
|
+
// Set once the caller's own work is committed. Getting a token or the container write lock happens
|
|
1088
|
+
// before that, and abandonSchemaChanges discards every unsaved change rather than only this import's,
|
|
1089
|
+
// so abandoning on a failure from that window would throw away work the import never touched.
|
|
1090
|
+
let callerChangesSaved = false;
|
|
1091
|
+
try {
|
|
1092
|
+
await SchemaSync.withLockedAccess(this, { openMode: OpenMode.Readonly, operationName: "schema sync" }, async (syncAccess) => {
|
|
1093
|
+
const schemaSyncDbUri = syncAccess.getUri();
|
|
1094
|
+
this.saveSchemaChanges();
|
|
1095
|
+
callerChangesSaved = true;
|
|
1096
|
+
// After saveSchemaChanges, so rolling back cannot reach the caller's own work.
|
|
1097
|
+
if (this.isBriefcaseDb())
|
|
1098
|
+
txnBeforeAdopt = this.txns.getCurrentTxnId();
|
|
1099
|
+
try {
|
|
1100
|
+
nativeImportOp(schemas, { schemaLockHeld: false, ecSchemaXmlContext: maybeCustomNativeContext, schemaSyncDbUri });
|
|
1063
1101
|
}
|
|
1064
|
-
|
|
1065
|
-
|
|
1102
|
+
catch (err) {
|
|
1103
|
+
if (SchemaSync.requiresUpgrade(err))
|
|
1104
|
+
throw new IModelError(err.errorNumber, `${err.message} - this schema change needs the upgrade path. Use BriefcaseDb.upgradeSchemas, which takes the exclusive schema lock and pushes the result.`);
|
|
1105
|
+
throw new IModelError(err.errorNumber, err.message);
|
|
1066
1106
|
}
|
|
1107
|
+
});
|
|
1108
|
+
}
|
|
1109
|
+
catch (err) {
|
|
1110
|
+
if (callerChangesSaved)
|
|
1111
|
+
this.abandonSchemaChanges();
|
|
1112
|
+
if (this.isBriefcaseDb() && undefined !== txnBeforeAdopt && this.txns.getCurrentTxnId() !== txnBeforeAdopt) {
|
|
1113
|
+
// Saving the adopt's txn started a new undo session, because schema changes are kept out of the
|
|
1114
|
+
// user's undo stack, so this reverses across that boundary. The changes themselves reverse like
|
|
1115
|
+
// any other - a rebase does it to every local txn on every pull. It does not reverse DDL: a table
|
|
1116
|
+
// or column the adopt created stays behind with no ec_ row describing it, which is the state a
|
|
1117
|
+
// briefcase already tolerates, and the next successful import finds the table up to date and
|
|
1118
|
+
// carries on. Cancel rather than reverse, so the rows cannot come back through undo either.
|
|
1119
|
+
const status = this[_nativeDb].cancelTo(txnBeforeAdopt, true);
|
|
1120
|
+
if (IModelStatus.Success !== status)
|
|
1121
|
+
Logger.logError(loggerCategory, `Failed to roll back the adopted schema rows after a failed import: ${IModelStatus[status] ?? status}`);
|
|
1067
1122
|
}
|
|
1068
|
-
|
|
1123
|
+
throw err;
|
|
1124
|
+
}
|
|
1069
1125
|
}
|
|
1070
1126
|
else {
|
|
1071
1127
|
const nativeImportOptions = {
|
|
@@ -2174,7 +2230,7 @@ function processSchemaWriteStatus(status) {
|
|
|
2174
2230
|
* @param props The data for the new model.
|
|
2175
2231
|
* @returns The newly inserted model's Id.
|
|
2176
2232
|
* @throws [[IModelError]] if insertion fails.
|
|
2177
|
-
* @deprecated in 5.9.0 -
|
|
2233
|
+
* @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.insertModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
|
|
2178
2234
|
*/
|
|
2179
2235
|
insertModel(props) {
|
|
2180
2236
|
return this._iModel[_implicitTxn].insertModel(props);
|
|
@@ -2182,7 +2238,7 @@ function processSchemaWriteStatus(status) {
|
|
|
2182
2238
|
/** Update an existing model.
|
|
2183
2239
|
* @param props the properties of the model to change
|
|
2184
2240
|
* @throws [[IModelError]] if update fails.
|
|
2185
|
-
* @deprecated in 5.9.0 -
|
|
2241
|
+
* @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.updateModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
|
|
2186
2242
|
*/
|
|
2187
2243
|
updateModel(props) {
|
|
2188
2244
|
this._iModel[_implicitTxn].updateModel(props);
|
|
@@ -2194,7 +2250,7 @@ function processSchemaWriteStatus(status) {
|
|
|
2194
2250
|
* Cached [Tile]($frontend)s are only invalidated after the geometry guid of the model changes.
|
|
2195
2251
|
* @note This will throw IModelError with [IModelStatus.VersionTooOld]($core-bentley) if a version of the BisCore schema older than 1.0.11 is present in the iModel.
|
|
2196
2252
|
* @throws [[IModelError]] if the update fails.
|
|
2197
|
-
* @deprecated in 5.9.0 -
|
|
2253
|
+
* @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.updateGeometryGuid instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
|
|
2198
2254
|
* @see [[TxnManager.onModelGeometryChanged]] for the event emitted in response to such a change.
|
|
2199
2255
|
*/
|
|
2200
2256
|
updateGeometryGuid(modelId) {
|
|
@@ -2203,7 +2259,7 @@ function processSchemaWriteStatus(status) {
|
|
|
2203
2259
|
/** Delete one or more existing models.
|
|
2204
2260
|
* @param ids The Ids of the models to be deleted
|
|
2205
2261
|
* @throws [[IModelError]] if deletion fails.
|
|
2206
|
-
* @deprecated in 5.9.0 -
|
|
2262
|
+
* @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.deleteModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
|
|
2207
2263
|
*/
|
|
2208
2264
|
deleteModel(ids) {
|
|
2209
2265
|
this._iModel[_implicitTxn].deleteModel(ids);
|
|
@@ -2427,7 +2483,7 @@ function processSchemaWriteStatus(status) {
|
|
|
2427
2483
|
* However when `elProps.federationGuid` is not present or undefined, a new Guid will be generated and stored on the resultant element. But
|
|
2428
2484
|
* the value of `elProps.federationGuid` is *not* updated. Generally, it is best to re-read the element after inserting (e.g. via [[getElementProps]])
|
|
2429
2485
|
* if you intend to continue working with it. That will ensure its values reflect the persistent state.
|
|
2430
|
-
* @deprecated in 5.9.0 -
|
|
2486
|
+
* @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.insertElement instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
|
|
2431
2487
|
*/
|
|
2432
2488
|
insertElement(elProps, options) {
|
|
2433
2489
|
return this._iModel[_implicitTxn].insertElement(elProps, options);
|
|
@@ -2442,7 +2498,7 @@ function processSchemaWriteStatus(status) {
|
|
|
2442
2498
|
* @note The values of `classFullName` and `model` *may not be changed* by this method. Further, it will permute the `elProps` object by adding or
|
|
2443
2499
|
* overwriting their values to the correct values.
|
|
2444
2500
|
* @throws [[ITwinError]] if update fails.
|
|
2445
|
-
* @deprecated in 5.9.0 -
|
|
2501
|
+
* @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.updateElement instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
|
|
2446
2502
|
*/
|
|
2447
2503
|
updateElement(elProps) {
|
|
2448
2504
|
this._iModel[_implicitTxn].updateElement(elProps);
|
|
@@ -2451,7 +2507,7 @@ function processSchemaWriteStatus(status) {
|
|
|
2451
2507
|
* @param ids The set of Ids of the element(s) to be deleted
|
|
2452
2508
|
* @throws [[ITwinError]]
|
|
2453
2509
|
* @see deleteDefinitionElements
|
|
2454
|
-
* @deprecated in 5.9.0 -
|
|
2510
|
+
* @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.deleteElement instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
|
|
2455
2511
|
*/
|
|
2456
2512
|
deleteElement(ids) {
|
|
2457
2513
|
this._iModel[_implicitTxn].deleteElement(ids);
|
|
@@ -2462,7 +2518,7 @@ function processSchemaWriteStatus(status) {
|
|
|
2462
2518
|
* @param deleteOptions Options for the delete operation.
|
|
2463
2519
|
* @returns A result object containing information about the deletion operation success and the element ids that failed to delete (if any).
|
|
2464
2520
|
* @throws [[ITwinError]] if any of the supplied ids are not well-formed/valid [[Id64String]]s.
|
|
2465
|
-
* @deprecated in 5.1.9 -
|
|
2521
|
+
* @deprecated in 5.1.9 - might be removed in next major version. Use EditTxn.deleteElements instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
|
|
2466
2522
|
* @beta
|
|
2467
2523
|
*/
|
|
2468
2524
|
deleteElements(ids, deleteOptions) {
|
|
@@ -2476,7 +2532,7 @@ function processSchemaWriteStatus(status) {
|
|
|
2476
2532
|
* DefinitionElements rather than calling this method separately for each one. Ids that are not valid DefinitionElements will be ignored.
|
|
2477
2533
|
* @returns An IdSet of the DefinitionElements that are used and were therefore not deleted.
|
|
2478
2534
|
* @see deleteElement
|
|
2479
|
-
* @deprecated in 5.9.0 -
|
|
2535
|
+
* @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.deleteDefinitionElements instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
|
|
2480
2536
|
*/
|
|
2481
2537
|
deleteDefinitionElements(definitionElementIds) {
|
|
2482
2538
|
return this._iModel[_implicitTxn].deleteDefinitionElements(definitionElementIds);
|
|
@@ -2719,7 +2775,7 @@ function processSchemaWriteStatus(status) {
|
|
|
2719
2775
|
* @returns the id of the newly inserted aspect.
|
|
2720
2776
|
* @note Aspect Ids may collide with element Ids, so don't put both in a container like Set or Map
|
|
2721
2777
|
* use [EntityReference]($common) for that instead.
|
|
2722
|
-
* @deprecated in 5.9.0 -
|
|
2778
|
+
* @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.insertAspect instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
|
|
2723
2779
|
*/
|
|
2724
2780
|
insertAspect(aspectProps) {
|
|
2725
2781
|
return this._iModel[_implicitTxn].insertAspect(aspectProps);
|
|
@@ -2727,7 +2783,7 @@ function processSchemaWriteStatus(status) {
|
|
|
2727
2783
|
/** Update an exist ElementAspect within the iModel.
|
|
2728
2784
|
* @param aspectProps The properties to use to update the ElementAspect.
|
|
2729
2785
|
* @throws [[IModelError]] if unable to update the ElementAspect.
|
|
2730
|
-
* @deprecated in 5.9.0 -
|
|
2786
|
+
* @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.updateAspect instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
|
|
2731
2787
|
*/
|
|
2732
2788
|
updateAspect(aspectProps) {
|
|
2733
2789
|
this._iModel[_implicitTxn].updateAspect(aspectProps);
|
|
@@ -2735,7 +2791,7 @@ function processSchemaWriteStatus(status) {
|
|
|
2735
2791
|
/** Delete one or more ElementAspects from this iModel.
|
|
2736
2792
|
* @param aspectInstanceIds The set of instance Ids of the ElementAspect(s) to be deleted
|
|
2737
2793
|
* @throws [[IModelError]] if unable to delete the ElementAspect.
|
|
2738
|
-
* @deprecated in 5.9.0 -
|
|
2794
|
+
* @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.deleteAspect instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
|
|
2739
2795
|
*/
|
|
2740
2796
|
deleteAspect(aspectInstanceIds) {
|
|
2741
2797
|
this._iModel[_implicitTxn].deleteAspect(aspectInstanceIds);
|
|
@@ -2744,7 +2800,7 @@ function processSchemaWriteStatus(status) {
|
|
|
2744
2800
|
* @param props The properties specifying the element to reparent and its new parent.
|
|
2745
2801
|
* @throws [[ITwinError]] if the operation fails.
|
|
2746
2802
|
* @beta
|
|
2747
|
-
* @deprecated in 5.11.0 -
|
|
2803
|
+
* @deprecated in 5.11.0 - might be removed in next major version. Use EditTxn.changeElementParent instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
|
|
2748
2804
|
*/
|
|
2749
2805
|
changeElementParent(props) {
|
|
2750
2806
|
this._iModel[_implicitTxn].changeElementParent(props);
|
|
@@ -2753,7 +2809,7 @@ function processSchemaWriteStatus(status) {
|
|
|
2753
2809
|
* @param props The properties specifying the element to move and its new model.
|
|
2754
2810
|
* @throws [[ITwinError]] if the operation fails.
|
|
2755
2811
|
* @beta
|
|
2756
|
-
* @deprecated in 5.11.0 -
|
|
2812
|
+
* @deprecated in 5.11.0 - might be removed in next major version. Use EditTxn.changeElementModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
|
|
2757
2813
|
*/
|
|
2758
2814
|
changeElementModel(props) {
|
|
2759
2815
|
this._iModel[_implicitTxn].changeElementModel(props);
|
|
@@ -2812,7 +2868,7 @@ function processSchemaWriteStatus(status) {
|
|
|
2812
2868
|
return this._viewStore;
|
|
2813
2869
|
}
|
|
2814
2870
|
/**
|
|
2815
|
-
* @beta @deprecated in 5.9.0 -
|
|
2871
|
+
* @beta @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.saveDefaultViewStore instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
|
|
2816
2872
|
*/
|
|
2817
2873
|
saveDefaultViewStore(arg) {
|
|
2818
2874
|
this._iModel[_implicitTxn].saveDefaultViewStore(arg);
|
|
@@ -2830,7 +2886,9 @@ function processSchemaWriteStatus(status) {
|
|
|
2830
2886
|
try {
|
|
2831
2887
|
props.push(imodel.elements.getElementProps(id));
|
|
2832
2888
|
}
|
|
2833
|
-
catch {
|
|
2889
|
+
catch {
|
|
2890
|
+
return;
|
|
2891
|
+
}
|
|
2834
2892
|
});
|
|
2835
2893
|
return props;
|
|
2836
2894
|
}
|
|
@@ -2853,7 +2911,9 @@ function processSchemaWriteStatus(status) {
|
|
|
2853
2911
|
break;
|
|
2854
2912
|
}
|
|
2855
2913
|
}
|
|
2856
|
-
catch {
|
|
2914
|
+
catch {
|
|
2915
|
+
continue;
|
|
2916
|
+
}
|
|
2857
2917
|
}
|
|
2858
2918
|
return finished;
|
|
2859
2919
|
}
|
|
@@ -3063,9 +3123,6 @@ export class BriefcaseDb extends IModelDb {
|
|
|
3063
3123
|
get isBriefcase() { return true; }
|
|
3064
3124
|
/* the BriefcaseId of the briefcase opened with this BriefcaseDb */
|
|
3065
3125
|
briefcaseId;
|
|
3066
|
-
_skipSyncSchemasOnPullAndPush;
|
|
3067
|
-
/** @internal */
|
|
3068
|
-
get skipSyncSchemasOnPullAndPush() { return this._skipSyncSchemasOnPullAndPush ?? false; }
|
|
3069
3126
|
/**
|
|
3070
3127
|
* Event raised just before a BriefcaseDb is opened. Supplies the arguments that will be used to open the BriefcaseDb.
|
|
3071
3128
|
* Throw an exception to stop the open.
|
|
@@ -3148,6 +3205,8 @@ export class BriefcaseDb extends IModelDb {
|
|
|
3148
3205
|
}
|
|
3149
3206
|
constructor(args) {
|
|
3150
3207
|
super({ ...args, changeset: args.nativeDb.getCurrentChangeset() });
|
|
3208
|
+
// Native invokes this private callback dynamically through the object registered by IModelDb.
|
|
3209
|
+
void this.onChangesetConflict;
|
|
3151
3210
|
this._openMode = args.openMode;
|
|
3152
3211
|
this.briefcaseId = args.briefcaseId;
|
|
3153
3212
|
this.makeLockControl();
|
|
@@ -3160,26 +3219,33 @@ export class BriefcaseDb extends IModelDb {
|
|
|
3160
3219
|
wasChanges = nativeDb.hasPendingTxns();
|
|
3161
3220
|
nativeDb.closeFile();
|
|
3162
3221
|
};
|
|
3163
|
-
const
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
}
|
|
3167
|
-
|
|
3222
|
+
const push = async () => {
|
|
3223
|
+
if (wasChanges)
|
|
3224
|
+
await withBriefcaseDb(briefcase, async (db) => db.pushChanges({ ...briefcase, description, retainLocks: true }));
|
|
3225
|
+
};
|
|
3226
|
+
// Asked of the closed file, so an iModel without schema sync never gets opened for this.
|
|
3227
|
+
if (SchemaSync.isEnabled(briefcase)) {
|
|
3228
|
+
await withBriefcaseDb(briefcase, async (db) => SchemaSync.updateDbSchema(db));
|
|
3168
3229
|
await SchemaSync.withLockedAccess(briefcase, { openMode: OpenMode.Readonly, operationName: "schema sync" }, async (syncAccess) => {
|
|
3169
3230
|
const schemaSyncDbUri = syncAccess.getUri();
|
|
3170
3231
|
executeUpgrade();
|
|
3232
|
+
// Overwriting advances the SchemaSync data version, so a no-op upgrade must not call it.
|
|
3233
|
+
if (!wasChanges)
|
|
3234
|
+
return;
|
|
3171
3235
|
await withBriefcaseDb(briefcase, async (db) => {
|
|
3172
|
-
db[_nativeDb].
|
|
3236
|
+
db[_nativeDb].schemaSyncOverwrite(schemaSyncDbUri);
|
|
3173
3237
|
db[_nativeDb].saveChanges();
|
|
3174
3238
|
});
|
|
3175
|
-
|
|
3239
|
+
// Publish the sync db before the changeset while retaining both locks.
|
|
3240
|
+
syncAccess.closeDb();
|
|
3241
|
+
await syncAccess.container.uploadChanges();
|
|
3242
|
+
await push();
|
|
3176
3243
|
});
|
|
3177
3244
|
}
|
|
3178
3245
|
else {
|
|
3179
3246
|
executeUpgrade();
|
|
3247
|
+
await push();
|
|
3180
3248
|
}
|
|
3181
|
-
if (wasChanges)
|
|
3182
|
-
await withBriefcaseDb(briefcase, async (db) => db.pushChanges({ ...briefcase, description, retainLocks: true }));
|
|
3183
3249
|
}
|
|
3184
3250
|
/** Upgrades the schemas in the iModel based on the current version of the software. Follows a sequence of operations -
|
|
3185
3251
|
* * Acquires a schema lock to prevent other users from making any other changes while upgrade is happening
|
|
@@ -3199,6 +3265,22 @@ export class BriefcaseDb extends IModelDb {
|
|
|
3199
3265
|
// - push changes
|
|
3200
3266
|
// - release schema lock
|
|
3201
3267
|
// good thing computers are fast. Fortunately upgrading should be rare (and the push time will dominate anyway.) Don't try to optimize any of this away.
|
|
3268
|
+
// schemaSyncOverwrite can discard unpushed imports, so hold the exclusive lock across both upgrades.
|
|
3269
|
+
if (SchemaSync.isEnabled(briefcase)) {
|
|
3270
|
+
try {
|
|
3271
|
+
await withBriefcaseDb(briefcase, async (db) => {
|
|
3272
|
+
if (!db.locks.isServerBased)
|
|
3273
|
+
throw new IModelError(DbResult.BE_SQLITE_ERROR, "Cannot upgrade schemas with SchemaSync without server-based locking");
|
|
3274
|
+
await db.acquireSchemaLock();
|
|
3275
|
+
});
|
|
3276
|
+
await this.doUpgrade(briefcase, { profile: ProfileOptions.Upgrade, schemaLockHeld: true }, "Upgraded profile");
|
|
3277
|
+
await this.doUpgrade(briefcase, { domain: DomainOptions.Upgrade, schemaLockHeld: true }, "Upgraded domain schemas");
|
|
3278
|
+
}
|
|
3279
|
+
finally {
|
|
3280
|
+
await withBriefcaseDb(briefcase, async (db) => db.locks[_releaseAllLocks]());
|
|
3281
|
+
}
|
|
3282
|
+
return;
|
|
3283
|
+
}
|
|
3202
3284
|
try {
|
|
3203
3285
|
await this.doUpgrade(briefcase, { profile: ProfileOptions.Upgrade }, "Upgraded profile");
|
|
3204
3286
|
}
|
|
@@ -3263,6 +3345,7 @@ export class BriefcaseDb extends IModelDb {
|
|
|
3263
3345
|
}
|
|
3264
3346
|
// load all of the settings from workspaces
|
|
3265
3347
|
await briefcaseDb.loadWorkspaceSettings();
|
|
3348
|
+
await briefcaseDb.initializeSharedElementReservations();
|
|
3266
3349
|
if (openMode === OpenMode.ReadWrite && CodeService.createForIModel) {
|
|
3267
3350
|
try {
|
|
3268
3351
|
briefcaseDb._codeService = await CodeService.createForIModel(briefcaseDb);
|
|
@@ -3318,6 +3401,18 @@ export class BriefcaseDb extends IModelDb {
|
|
|
3318
3401
|
return "foreign key";
|
|
3319
3402
|
}
|
|
3320
3403
|
};
|
|
3404
|
+
// `dgn_Domain` holds one bookkeeping row per BIS domain present in the briefcase. The row is
|
|
3405
|
+
// created automatically as soon as the domain's schema is imported, so merging a changeset
|
|
3406
|
+
// that registers a domain inserts a row that was just created locally. Both rows describe the
|
|
3407
|
+
// same domain and the incoming one is authoritative, so this duplicate insert is never fatal.
|
|
3408
|
+
// Only a primary key collision on an insert is benign - an update or delete whose "before"
|
|
3409
|
+
// values do not match (`DbConflictCause.Data`) describes a real divergence and must not be
|
|
3410
|
+
// silently discarded here.
|
|
3411
|
+
if (args.tableName === "dgn_Domain" && args.cause === DbConflictCause.Conflict && args.opcode === DbOpcode.Insert) {
|
|
3412
|
+
Logger.logWarning(category, `${interpretConflictCause(args.cause)} conflict on dgn_Domain - resolved by replacing the existing row with the incoming row`);
|
|
3413
|
+
args.dump();
|
|
3414
|
+
return DbConflictResolution.Replace;
|
|
3415
|
+
}
|
|
3321
3416
|
if (args.cause === DbConflictCause.Data && !args.indirect) {
|
|
3322
3417
|
/*
|
|
3323
3418
|
* From SQLite Docs CHANGESET_DATA as the second argument
|
|
@@ -3486,10 +3581,12 @@ export class BriefcaseDb extends IModelDb {
|
|
|
3486
3581
|
async pullChanges(arg) {
|
|
3487
3582
|
await this.executeWritable(async () => {
|
|
3488
3583
|
await BriefcaseManager.pullAndApplyChangesets(this, arg ?? {});
|
|
3489
|
-
|
|
3490
|
-
await SchemaSync.pull(this);
|
|
3584
|
+
SchemaSync.updateDbSchema(this);
|
|
3491
3585
|
this.initializeIModelDb("pullMerge");
|
|
3492
3586
|
});
|
|
3587
|
+
// If this pull enabled or disabled SchemaSync for this briefcase, its reservations must now be re-initialized
|
|
3588
|
+
if (this.reservations.isServerBased !== SchemaSync.isEnabled(this))
|
|
3589
|
+
await this.initializeSharedElementReservations();
|
|
3493
3590
|
this.txns._onChangesPulled(this.changeset);
|
|
3494
3591
|
}
|
|
3495
3592
|
async enableChangesetStatTracking() {
|
|
@@ -3569,24 +3666,10 @@ export class BriefcaseDb extends IModelDb {
|
|
|
3569
3666
|
if (nativeDb.hasPendingTxns()) {
|
|
3570
3667
|
throw new IModelError(ChangeSetStatus.HasLocalChanges, "Cannot revert with pending txns");
|
|
3571
3668
|
}
|
|
3572
|
-
const skipSchemaSyncPull = async (func) => {
|
|
3573
|
-
if (nativeDb.schemaSyncEnabled()) {
|
|
3574
|
-
this._skipSyncSchemasOnPullAndPush = true;
|
|
3575
|
-
try {
|
|
3576
|
-
return await func();
|
|
3577
|
-
}
|
|
3578
|
-
finally {
|
|
3579
|
-
this._skipSyncSchemasOnPullAndPush = undefined;
|
|
3580
|
-
}
|
|
3581
|
-
}
|
|
3582
|
-
else {
|
|
3583
|
-
return func();
|
|
3584
|
-
}
|
|
3585
|
-
};
|
|
3586
3669
|
this.clearCaches();
|
|
3587
|
-
await
|
|
3670
|
+
await this.pullChanges({ ...arg, toIndex: undefined });
|
|
3588
3671
|
await this.acquireSchemaLock();
|
|
3589
|
-
if (
|
|
3672
|
+
if (SchemaSync.isEnabled(this)) {
|
|
3590
3673
|
arg.skipSchemaChanges = true;
|
|
3591
3674
|
}
|
|
3592
3675
|
// The native side enables file-based txns during revert. Restore the original setting afterward.
|
|
@@ -3607,7 +3690,7 @@ export class BriefcaseDb extends IModelDb {
|
|
|
3607
3690
|
pushRetryDelay: arg.pushRetryDelay,
|
|
3608
3691
|
retainLocks: arg.retainLocks,
|
|
3609
3692
|
};
|
|
3610
|
-
await
|
|
3693
|
+
await this.pushChanges(pushArgs);
|
|
3611
3694
|
this.clearCaches();
|
|
3612
3695
|
}
|
|
3613
3696
|
catch (err) {
|
|
@@ -3678,9 +3761,62 @@ export class BriefcaseDb extends IModelDb {
|
|
|
3678
3761
|
await BriefcaseManager.pullMergePush(this, arg);
|
|
3679
3762
|
this.initializeIModelDb("pullMerge");
|
|
3680
3763
|
});
|
|
3764
|
+
// If this pull enabled or disabled SchemaSync for this briefcase, its reservations must now be re-initialized
|
|
3765
|
+
if (this.reservations.isServerBased !== SchemaSync.isEnabled(this))
|
|
3766
|
+
await this.initializeSharedElementReservations();
|
|
3681
3767
|
this.txns._onChangesPushed(this.changeset);
|
|
3682
3768
|
BriefcaseManager.deleteRebaseFolders(this);
|
|
3683
3769
|
}
|
|
3770
|
+
/** Import schemas while allowing changes that move or delete data.
|
|
3771
|
+
*
|
|
3772
|
+
* Takes the exclusive schema lock, requires the briefcase to be at the timeline tip, imports, updates the sync db, and pushes the result.
|
|
3773
|
+
* @note The briefcase must have no local changes.
|
|
3774
|
+
* @see [[BriefcaseDb.upgradeSchemas]] (static) for upgrading the software's profile and domain schemas.
|
|
3775
|
+
* @alpha
|
|
3776
|
+
*/
|
|
3777
|
+
async upgradeSchemas(schemaFileNames, arg) {
|
|
3778
|
+
return this.upgradeSchemasInternal(schemaFileNames, arg, (schemas, importOptions) => this[_nativeDb].importSchemas(schemas, importOptions));
|
|
3779
|
+
}
|
|
3780
|
+
/** The [[importSchemaStrings]] counterpart of [[upgradeSchemas]].
|
|
3781
|
+
* @alpha
|
|
3782
|
+
*/
|
|
3783
|
+
async upgradeSchemaStrings(serializedXmlSchemas, arg) {
|
|
3784
|
+
return this.upgradeSchemasInternal(serializedXmlSchemas, arg, (schemas, importOptions) => this[_nativeDb].importXmlSchemas(schemas, importOptions));
|
|
3785
|
+
}
|
|
3786
|
+
async upgradeSchemasInternal(schemas, arg, nativeImportOp) {
|
|
3787
|
+
if (schemas.length === 0)
|
|
3788
|
+
return;
|
|
3789
|
+
this.assertCanImportSchemas();
|
|
3790
|
+
if (this[_nativeDb].hasUnsavedChanges() || this.txns.hasLocalChanges)
|
|
3791
|
+
throw new IModelError(ChangeSetStatus.HasLocalChanges, "Cannot upgrade schemas while there are local changes");
|
|
3792
|
+
if (SchemaSync.isEnabled(this) && !this.locks.isServerBased)
|
|
3793
|
+
throw new IModelError(DbResult.BE_SQLITE_ERROR, "Cannot upgrade schemas with SchemaSync without server-based locking");
|
|
3794
|
+
await this.acquireSchemaLock();
|
|
3795
|
+
await this.pullChanges({ accessToken: arg.accessToken });
|
|
3796
|
+
if (!SchemaSync.isEnabled(this)) {
|
|
3797
|
+
await this.importSchemasInternal(schemas, { ecSchemaXmlContext: arg.ecSchemaXmlContext }, nativeImportOp);
|
|
3798
|
+
await this.pushChanges(arg);
|
|
3799
|
+
return;
|
|
3800
|
+
}
|
|
3801
|
+
await SchemaSync.withLockedAccess(this, { openMode: OpenMode.Readonly, operationName: "schema upgrade" }, async (syncAccess) => {
|
|
3802
|
+
this.saveSchemaChanges();
|
|
3803
|
+
try {
|
|
3804
|
+
nativeImportOp(schemas, {
|
|
3805
|
+
schemaLockHeld: true,
|
|
3806
|
+
ecSchemaXmlContext: arg.ecSchemaXmlContext?.nativeContext,
|
|
3807
|
+
schemaSyncDbUri: syncAccess.getUri(),
|
|
3808
|
+
});
|
|
3809
|
+
}
|
|
3810
|
+
catch (err) {
|
|
3811
|
+
this.abandonSchemaChanges();
|
|
3812
|
+
throw new IModelError(err.errorNumber, err.message);
|
|
3813
|
+
}
|
|
3814
|
+
this.clearCaches();
|
|
3815
|
+
syncAccess.closeDb();
|
|
3816
|
+
await syncAccess.container.uploadChanges();
|
|
3817
|
+
await this.pushChanges(arg);
|
|
3818
|
+
});
|
|
3819
|
+
}
|
|
3684
3820
|
close(options) {
|
|
3685
3821
|
if (this.isBriefcase && this.isOpen && !this.isReadonly && this.txns.rebaser.inProgress()) {
|
|
3686
3822
|
this[_nativeDb].abandonChanges();
|
|
@@ -3852,6 +3988,7 @@ export class SnapshotDb extends IModelDb {
|
|
|
3852
3988
|
const key = CheckpointManager.getKey(checkpoint);
|
|
3853
3989
|
const db = SnapshotDb.openFile(dbName, { key, container });
|
|
3854
3990
|
await db.loadWorkspaceSettings();
|
|
3991
|
+
await db.initializeSharedElementReservations();
|
|
3855
3992
|
return db;
|
|
3856
3993
|
}
|
|
3857
3994
|
/** @internal */
|