@itwin/core-backend 5.14.0-dev.2 → 5.14.0-dev.4
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/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/CloudSqlite.d.ts.map +1 -1
- package/lib/cjs/CloudSqlite.js +9 -2
- package/lib/cjs/CloudSqlite.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/IModelDb.d.ts +42 -7
- package/lib/cjs/IModelDb.d.ts.map +1 -1
- package/lib/cjs/IModelDb.js +175 -74
- package/lib/cjs/IModelDb.js.map +1 -1
- package/lib/cjs/SchemaSync.d.ts +126 -18
- package/lib/cjs/SchemaSync.d.ts.map +1 -1
- package/lib/cjs/SchemaSync.js +303 -81
- package/lib/cjs/SchemaSync.js.map +1 -1
- package/lib/cjs/TxnManager.d.ts.map +1 -1
- package/lib/cjs/TxnManager.js +2 -5
- package/lib/cjs/TxnManager.js.map +1 -1
- package/lib/cjs/internal/SchemaSyncReservations.d.ts.map +1 -1
- package/lib/cjs/internal/SchemaSyncReservations.js +13 -3
- package/lib/cjs/internal/SchemaSyncReservations.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/CloudSqlite.d.ts.map +1 -1
- package/lib/esm/CloudSqlite.js +10 -3
- package/lib/esm/CloudSqlite.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/IModelDb.d.ts +42 -7
- package/lib/esm/IModelDb.d.ts.map +1 -1
- package/lib/esm/IModelDb.js +175 -74
- package/lib/esm/IModelDb.js.map +1 -1
- package/lib/esm/SchemaSync.d.ts +126 -18
- package/lib/esm/SchemaSync.d.ts.map +1 -1
- package/lib/esm/SchemaSync.js +304 -82
- package/lib/esm/SchemaSync.js.map +1 -1
- package/lib/esm/TxnManager.d.ts.map +1 -1
- package/lib/esm/TxnManager.js +2 -5
- package/lib/esm/TxnManager.js.map +1 -1
- package/lib/esm/internal/SchemaSyncReservations.d.ts.map +1 -1
- package/lib/esm/internal/SchemaSyncReservations.js +13 -3
- package/lib/esm/internal/SchemaSyncReservations.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/standalone/SchemaSyncDb.test.js +5 -25
- package/lib/esm/test/standalone/SchemaSyncDb.test.js.map +1 -1
- package/lib/esm/test/standalone/SchemaSyncElementReservation.test.js +1 -0
- package/lib/esm/test/standalone/SchemaSyncElementReservation.test.js.map +1 -1
- package/package.json +13 -13
package/lib/cjs/IModelDb.js
CHANGED
|
@@ -320,7 +320,9 @@ class IModelDb extends core_common_1.IModel {
|
|
|
320
320
|
db[Symbols_1._nativeDb].abandonChanges();
|
|
321
321
|
db.close();
|
|
322
322
|
}
|
|
323
|
-
catch {
|
|
323
|
+
catch {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
324
326
|
});
|
|
325
327
|
});
|
|
326
328
|
}
|
|
@@ -386,12 +388,20 @@ class IModelDb extends core_common_1.IModel {
|
|
|
386
388
|
this._codeService = undefined;
|
|
387
389
|
this[Symbols_1._nativeDb].closeFile();
|
|
388
390
|
}
|
|
391
|
+
/**
|
|
392
|
+
* Save any unsaved schema changes in this iModel.
|
|
393
|
+
* @internal
|
|
394
|
+
*/
|
|
389
395
|
saveSchemaChanges(args) {
|
|
390
396
|
if (!this[Symbols_1._nativeDb].hasUnsavedChanges())
|
|
391
397
|
return;
|
|
392
398
|
const saveArgs = typeof args === "string" ? { description: args } : args;
|
|
393
399
|
saveArgs === undefined ? this[Symbols_1._nativeDb].saveChanges() : this[Symbols_1._nativeDb].saveChanges(JSON.stringify(saveArgs));
|
|
394
400
|
}
|
|
401
|
+
/**
|
|
402
|
+
* Abandon any unsaved schema changes in this iModel.
|
|
403
|
+
* @internal
|
|
404
|
+
*/
|
|
395
405
|
abandonSchemaChanges() {
|
|
396
406
|
if (!this[Symbols_1._nativeDb].hasUnsavedChanges())
|
|
397
407
|
return;
|
|
@@ -938,7 +948,7 @@ class IModelDb extends core_common_1.IModel {
|
|
|
938
948
|
async dropSchemas(schemaNames) {
|
|
939
949
|
if (schemaNames.length === 0)
|
|
940
950
|
return;
|
|
941
|
-
if (
|
|
951
|
+
if (SchemaSync_1.SchemaSync.isEnabled(this))
|
|
942
952
|
throw new core_common_1.IModelError(core_bentley_1.DbResult.BE_SQLITE_ERROR, "Cannot drop schemas when schema sync is enabled");
|
|
943
953
|
if (this[Symbols_1._nativeDb].hasUnsavedChanges())
|
|
944
954
|
throw new core_common_1.IModelError(core_bentley_1.ChangeSetStatus.HasUncommittedChanges, "Cannot drop schemas with unsaved changes");
|
|
@@ -1024,26 +1034,34 @@ class IModelDb extends core_common_1.IModel {
|
|
|
1024
1034
|
this.cleanupSnapshot(context.resources);
|
|
1025
1035
|
}
|
|
1026
1036
|
}
|
|
1027
|
-
/**
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1037
|
+
/** Refuse a schema import this briefcase is in no state to run. Shared by [[importSchemas]] and
|
|
1038
|
+
* [[BriefcaseDb.upgradeSchemas]], which reach the native importer by different routes.
|
|
1039
|
+
* @internal
|
|
1040
|
+
*/
|
|
1041
|
+
assertCanImportSchemas() {
|
|
1042
|
+
if (!this.isBriefcaseDb())
|
|
1043
|
+
return;
|
|
1044
|
+
if (this.txns.rebaser.isRebasing) {
|
|
1045
|
+
throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot import schemas while rebasing");
|
|
1046
|
+
}
|
|
1047
|
+
if (this.txns.isIndirectChanges) {
|
|
1048
|
+
throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot import schemas while in an indirect change scope");
|
|
1049
|
+
}
|
|
1050
|
+
// Additional checks when semantic rebase is enabled
|
|
1051
|
+
if (IModelHost_1.IModelHost.useSemanticRebase) {
|
|
1052
|
+
if (this[Symbols_1._nativeDb].hasUnsavedChanges()) {
|
|
1053
|
+
throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot import schemas with unsaved changes when useSemanticRebase flag is on");
|
|
1054
|
+
}
|
|
1055
|
+
if (SchemaSync_1.SchemaSync.isEnabled(this)) {
|
|
1056
|
+
throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot import schemas when schema sync is enabled and also useSemanticRebase flag is on");
|
|
1045
1057
|
}
|
|
1046
1058
|
}
|
|
1059
|
+
}
|
|
1060
|
+
/** Shared implementation for importing schemas from file or string.
|
|
1061
|
+
* @internal
|
|
1062
|
+
*/
|
|
1063
|
+
async importSchemasInternal(schemas, options, nativeImportOp) {
|
|
1064
|
+
this.assertCanImportSchemas();
|
|
1047
1065
|
if (options?.channelUpgrade) {
|
|
1048
1066
|
const channelUpgrade = options.channelUpgrade;
|
|
1049
1067
|
try {
|
|
@@ -1061,30 +1079,52 @@ class IModelDb extends core_common_1.IModel {
|
|
|
1061
1079
|
if (options?.schemaImportCallbacks?.preSchemaImportCallback)
|
|
1062
1080
|
preSchemaImportCallbackResult = await this.preSchemaImportCallback(options.schemaImportCallbacks, { iModel: this, data: options.data, schemaData: schemas });
|
|
1063
1081
|
const maybeCustomNativeContext = options?.ecSchemaXmlContext?.nativeContext;
|
|
1064
|
-
if (
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
this.
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
+
if (SchemaSync_1.SchemaSync.isEnabled(this)) {
|
|
1083
|
+
// The shared lock lets concurrent updates through while blocking anyone taking the exclusive lock for an upgrade.
|
|
1084
|
+
if (this[Symbols_1._nativeDb].getITwinId() !== core_bentley_1.Guid.empty)
|
|
1085
|
+
await this.locks.acquireLocks({ shared: core_common_1.IModel.repositoryModelId });
|
|
1086
|
+
// The native import adopts rows from the attached SchemaSyncDb. Attach and detach commit
|
|
1087
|
+
// implicitly, so abandoning changes cannot undo the adoption. A later failure must roll the
|
|
1088
|
+
// briefcase back before those ec_ rows can be pushed.
|
|
1089
|
+
let txnBeforeAdopt;
|
|
1090
|
+
// Set once the caller's own work is committed. Getting a token or the container write lock happens
|
|
1091
|
+
// before that, and abandonSchemaChanges discards every unsaved change rather than only this import's,
|
|
1092
|
+
// so abandoning on a failure from that window would throw away work the import never touched.
|
|
1093
|
+
let callerChangesSaved = false;
|
|
1094
|
+
try {
|
|
1095
|
+
await SchemaSync_1.SchemaSync.withLockedAccess(this, { openMode: core_bentley_1.OpenMode.Readonly, operationName: "schema sync" }, async (syncAccess) => {
|
|
1096
|
+
const schemaSyncDbUri = syncAccess.getUri();
|
|
1097
|
+
this.saveSchemaChanges();
|
|
1098
|
+
callerChangesSaved = true;
|
|
1099
|
+
// After saveSchemaChanges, so rolling back cannot reach the caller's own work.
|
|
1100
|
+
if (this.isBriefcaseDb())
|
|
1101
|
+
txnBeforeAdopt = this.txns.getCurrentTxnId();
|
|
1102
|
+
try {
|
|
1103
|
+
nativeImportOp(schemas, { schemaLockHeld: false, ecSchemaXmlContext: maybeCustomNativeContext, schemaSyncDbUri });
|
|
1082
1104
|
}
|
|
1083
|
-
|
|
1084
|
-
|
|
1105
|
+
catch (err) {
|
|
1106
|
+
if (SchemaSync_1.SchemaSync.requiresUpgrade(err))
|
|
1107
|
+
throw new core_common_1.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.`);
|
|
1108
|
+
throw new core_common_1.IModelError(err.errorNumber, err.message);
|
|
1085
1109
|
}
|
|
1110
|
+
});
|
|
1111
|
+
}
|
|
1112
|
+
catch (err) {
|
|
1113
|
+
if (callerChangesSaved)
|
|
1114
|
+
this.abandonSchemaChanges();
|
|
1115
|
+
if (this.isBriefcaseDb() && undefined !== txnBeforeAdopt && this.txns.getCurrentTxnId() !== txnBeforeAdopt) {
|
|
1116
|
+
// Saving the adopt's txn started a new undo session, because schema changes are kept out of the
|
|
1117
|
+
// user's undo stack, so this reverses across that boundary. The changes themselves reverse like
|
|
1118
|
+
// any other - a rebase does it to every local txn on every pull. It does not reverse DDL: a table
|
|
1119
|
+
// or column the adopt created stays behind with no ec_ row describing it, which is the state a
|
|
1120
|
+
// briefcase already tolerates, and the next successful import finds the table up to date and
|
|
1121
|
+
// carries on. Cancel rather than reverse, so the rows cannot come back through undo either.
|
|
1122
|
+
const status = this[Symbols_1._nativeDb].cancelTo(txnBeforeAdopt, true);
|
|
1123
|
+
if (core_bentley_1.IModelStatus.Success !== status)
|
|
1124
|
+
core_bentley_1.Logger.logError(loggerCategory, `Failed to roll back the adopted schema rows after a failed import: ${core_bentley_1.IModelStatus[status] ?? status}`);
|
|
1086
1125
|
}
|
|
1087
|
-
|
|
1126
|
+
throw err;
|
|
1127
|
+
}
|
|
1088
1128
|
}
|
|
1089
1129
|
else {
|
|
1090
1130
|
const nativeImportOptions = {
|
|
@@ -2850,7 +2890,9 @@ function processSchemaWriteStatus(status) {
|
|
|
2850
2890
|
try {
|
|
2851
2891
|
props.push(imodel.elements.getElementProps(id));
|
|
2852
2892
|
}
|
|
2853
|
-
catch {
|
|
2893
|
+
catch {
|
|
2894
|
+
return;
|
|
2895
|
+
}
|
|
2854
2896
|
});
|
|
2855
2897
|
return props;
|
|
2856
2898
|
}
|
|
@@ -2873,7 +2915,9 @@ function processSchemaWriteStatus(status) {
|
|
|
2873
2915
|
break;
|
|
2874
2916
|
}
|
|
2875
2917
|
}
|
|
2876
|
-
catch {
|
|
2918
|
+
catch {
|
|
2919
|
+
continue;
|
|
2920
|
+
}
|
|
2877
2921
|
}
|
|
2878
2922
|
return finished;
|
|
2879
2923
|
}
|
|
@@ -3083,9 +3127,6 @@ class BriefcaseDb extends IModelDb {
|
|
|
3083
3127
|
get isBriefcase() { return true; }
|
|
3084
3128
|
/* the BriefcaseId of the briefcase opened with this BriefcaseDb */
|
|
3085
3129
|
briefcaseId;
|
|
3086
|
-
_skipSyncSchemasOnPullAndPush;
|
|
3087
|
-
/** @internal */
|
|
3088
|
-
get skipSyncSchemasOnPullAndPush() { return this._skipSyncSchemasOnPullAndPush ?? false; }
|
|
3089
3130
|
/**
|
|
3090
3131
|
* Event raised just before a BriefcaseDb is opened. Supplies the arguments that will be used to open the BriefcaseDb.
|
|
3091
3132
|
* Throw an exception to stop the open.
|
|
@@ -3168,6 +3209,8 @@ class BriefcaseDb extends IModelDb {
|
|
|
3168
3209
|
}
|
|
3169
3210
|
constructor(args) {
|
|
3170
3211
|
super({ ...args, changeset: args.nativeDb.getCurrentChangeset() });
|
|
3212
|
+
// Native invokes this private callback dynamically through the object registered by IModelDb.
|
|
3213
|
+
void this.onChangesetConflict;
|
|
3171
3214
|
this._openMode = args.openMode;
|
|
3172
3215
|
this.briefcaseId = args.briefcaseId;
|
|
3173
3216
|
this.makeLockControl();
|
|
@@ -3180,26 +3223,33 @@ class BriefcaseDb extends IModelDb {
|
|
|
3180
3223
|
wasChanges = nativeDb.hasPendingTxns();
|
|
3181
3224
|
nativeDb.closeFile();
|
|
3182
3225
|
};
|
|
3183
|
-
const
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
}
|
|
3187
|
-
|
|
3226
|
+
const push = async () => {
|
|
3227
|
+
if (wasChanges)
|
|
3228
|
+
await withBriefcaseDb(briefcase, async (db) => db.pushChanges({ ...briefcase, description, retainLocks: true }));
|
|
3229
|
+
};
|
|
3230
|
+
// Asked of the closed file, so an iModel without schema sync never gets opened for this.
|
|
3231
|
+
if (SchemaSync_1.SchemaSync.isEnabled(briefcase)) {
|
|
3232
|
+
await withBriefcaseDb(briefcase, async (db) => SchemaSync_1.SchemaSync.updateDbSchema(db));
|
|
3188
3233
|
await SchemaSync_1.SchemaSync.withLockedAccess(briefcase, { openMode: core_bentley_1.OpenMode.Readonly, operationName: "schema sync" }, async (syncAccess) => {
|
|
3189
3234
|
const schemaSyncDbUri = syncAccess.getUri();
|
|
3190
3235
|
executeUpgrade();
|
|
3236
|
+
// Overwriting advances the SchemaSync data version, so a no-op upgrade must not call it.
|
|
3237
|
+
if (!wasChanges)
|
|
3238
|
+
return;
|
|
3191
3239
|
await withBriefcaseDb(briefcase, async (db) => {
|
|
3192
|
-
db[Symbols_1._nativeDb].
|
|
3240
|
+
db[Symbols_1._nativeDb].schemaSyncOverwrite(schemaSyncDbUri);
|
|
3193
3241
|
db[Symbols_1._nativeDb].saveChanges();
|
|
3194
3242
|
});
|
|
3195
|
-
|
|
3243
|
+
// Publish the sync db before the changeset while retaining both locks.
|
|
3244
|
+
syncAccess.closeDb();
|
|
3245
|
+
await syncAccess.container.uploadChanges();
|
|
3246
|
+
await push();
|
|
3196
3247
|
});
|
|
3197
3248
|
}
|
|
3198
3249
|
else {
|
|
3199
3250
|
executeUpgrade();
|
|
3251
|
+
await push();
|
|
3200
3252
|
}
|
|
3201
|
-
if (wasChanges)
|
|
3202
|
-
await withBriefcaseDb(briefcase, async (db) => db.pushChanges({ ...briefcase, description, retainLocks: true }));
|
|
3203
3253
|
}
|
|
3204
3254
|
/** Upgrades the schemas in the iModel based on the current version of the software. Follows a sequence of operations -
|
|
3205
3255
|
* * Acquires a schema lock to prevent other users from making any other changes while upgrade is happening
|
|
@@ -3219,6 +3269,22 @@ class BriefcaseDb extends IModelDb {
|
|
|
3219
3269
|
// - push changes
|
|
3220
3270
|
// - release schema lock
|
|
3221
3271
|
// 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.
|
|
3272
|
+
// schemaSyncOverwrite can discard unpushed imports, so hold the exclusive lock across both upgrades.
|
|
3273
|
+
if (SchemaSync_1.SchemaSync.isEnabled(briefcase)) {
|
|
3274
|
+
try {
|
|
3275
|
+
await withBriefcaseDb(briefcase, async (db) => {
|
|
3276
|
+
if (!db.locks.isServerBased)
|
|
3277
|
+
throw new core_common_1.IModelError(core_bentley_1.DbResult.BE_SQLITE_ERROR, "Cannot upgrade schemas with SchemaSync without server-based locking");
|
|
3278
|
+
await db.acquireSchemaLock();
|
|
3279
|
+
});
|
|
3280
|
+
await this.doUpgrade(briefcase, { profile: core_common_1.ProfileOptions.Upgrade, schemaLockHeld: true }, "Upgraded profile");
|
|
3281
|
+
await this.doUpgrade(briefcase, { domain: core_common_1.DomainOptions.Upgrade, schemaLockHeld: true }, "Upgraded domain schemas");
|
|
3282
|
+
}
|
|
3283
|
+
finally {
|
|
3284
|
+
await withBriefcaseDb(briefcase, async (db) => db.locks[Symbols_1._releaseAllLocks]());
|
|
3285
|
+
}
|
|
3286
|
+
return;
|
|
3287
|
+
}
|
|
3222
3288
|
try {
|
|
3223
3289
|
await this.doUpgrade(briefcase, { profile: core_common_1.ProfileOptions.Upgrade }, "Upgraded profile");
|
|
3224
3290
|
}
|
|
@@ -3519,8 +3585,7 @@ class BriefcaseDb extends IModelDb {
|
|
|
3519
3585
|
async pullChanges(arg) {
|
|
3520
3586
|
await this.executeWritable(async () => {
|
|
3521
3587
|
await BriefcaseManager_1.BriefcaseManager.pullAndApplyChangesets(this, arg ?? {});
|
|
3522
|
-
|
|
3523
|
-
await SchemaSync_1.SchemaSync.pull(this);
|
|
3588
|
+
SchemaSync_1.SchemaSync.updateDbSchema(this);
|
|
3524
3589
|
this.initializeIModelDb("pullMerge");
|
|
3525
3590
|
});
|
|
3526
3591
|
// If this pull enabled or disabled SchemaSync for this briefcase, its reservations must now be re-initialized
|
|
@@ -3605,24 +3670,10 @@ class BriefcaseDb extends IModelDb {
|
|
|
3605
3670
|
if (nativeDb.hasPendingTxns()) {
|
|
3606
3671
|
throw new core_common_1.IModelError(core_bentley_1.ChangeSetStatus.HasLocalChanges, "Cannot revert with pending txns");
|
|
3607
3672
|
}
|
|
3608
|
-
const skipSchemaSyncPull = async (func) => {
|
|
3609
|
-
if (nativeDb.schemaSyncEnabled()) {
|
|
3610
|
-
this._skipSyncSchemasOnPullAndPush = true;
|
|
3611
|
-
try {
|
|
3612
|
-
return await func();
|
|
3613
|
-
}
|
|
3614
|
-
finally {
|
|
3615
|
-
this._skipSyncSchemasOnPullAndPush = undefined;
|
|
3616
|
-
}
|
|
3617
|
-
}
|
|
3618
|
-
else {
|
|
3619
|
-
return func();
|
|
3620
|
-
}
|
|
3621
|
-
};
|
|
3622
3673
|
this.clearCaches();
|
|
3623
|
-
await
|
|
3674
|
+
await this.pullChanges({ ...arg, toIndex: undefined });
|
|
3624
3675
|
await this.acquireSchemaLock();
|
|
3625
|
-
if (
|
|
3676
|
+
if (SchemaSync_1.SchemaSync.isEnabled(this)) {
|
|
3626
3677
|
arg.skipSchemaChanges = true;
|
|
3627
3678
|
}
|
|
3628
3679
|
// The native side enables file-based txns during revert. Restore the original setting afterward.
|
|
@@ -3643,7 +3694,7 @@ class BriefcaseDb extends IModelDb {
|
|
|
3643
3694
|
pushRetryDelay: arg.pushRetryDelay,
|
|
3644
3695
|
retainLocks: arg.retainLocks,
|
|
3645
3696
|
};
|
|
3646
|
-
await
|
|
3697
|
+
await this.pushChanges(pushArgs);
|
|
3647
3698
|
this.clearCaches();
|
|
3648
3699
|
}
|
|
3649
3700
|
catch (err) {
|
|
@@ -3720,6 +3771,56 @@ class BriefcaseDb extends IModelDb {
|
|
|
3720
3771
|
this.txns._onChangesPushed(this.changeset);
|
|
3721
3772
|
BriefcaseManager_1.BriefcaseManager.deleteRebaseFolders(this);
|
|
3722
3773
|
}
|
|
3774
|
+
/** Import schemas while allowing changes that move or delete data.
|
|
3775
|
+
*
|
|
3776
|
+
* Takes the exclusive schema lock, requires the briefcase to be at the timeline tip, imports, updates the sync db, and pushes the result.
|
|
3777
|
+
* @note The briefcase must have no local changes.
|
|
3778
|
+
* @see [[BriefcaseDb.upgradeSchemas]] (static) for upgrading the software's profile and domain schemas.
|
|
3779
|
+
* @alpha
|
|
3780
|
+
*/
|
|
3781
|
+
async upgradeSchemas(schemaFileNames, arg) {
|
|
3782
|
+
return this.upgradeSchemasInternal(schemaFileNames, arg, (schemas, importOptions) => this[Symbols_1._nativeDb].importSchemas(schemas, importOptions));
|
|
3783
|
+
}
|
|
3784
|
+
/** The [[importSchemaStrings]] counterpart of [[upgradeSchemas]].
|
|
3785
|
+
* @alpha
|
|
3786
|
+
*/
|
|
3787
|
+
async upgradeSchemaStrings(serializedXmlSchemas, arg) {
|
|
3788
|
+
return this.upgradeSchemasInternal(serializedXmlSchemas, arg, (schemas, importOptions) => this[Symbols_1._nativeDb].importXmlSchemas(schemas, importOptions));
|
|
3789
|
+
}
|
|
3790
|
+
async upgradeSchemasInternal(schemas, arg, nativeImportOp) {
|
|
3791
|
+
if (schemas.length === 0)
|
|
3792
|
+
return;
|
|
3793
|
+
this.assertCanImportSchemas();
|
|
3794
|
+
if (this[Symbols_1._nativeDb].hasUnsavedChanges() || this.txns.hasLocalChanges)
|
|
3795
|
+
throw new core_common_1.IModelError(core_bentley_1.ChangeSetStatus.HasLocalChanges, "Cannot upgrade schemas while there are local changes");
|
|
3796
|
+
if (SchemaSync_1.SchemaSync.isEnabled(this) && !this.locks.isServerBased)
|
|
3797
|
+
throw new core_common_1.IModelError(core_bentley_1.DbResult.BE_SQLITE_ERROR, "Cannot upgrade schemas with SchemaSync without server-based locking");
|
|
3798
|
+
await this.acquireSchemaLock();
|
|
3799
|
+
await this.pullChanges({ accessToken: arg.accessToken });
|
|
3800
|
+
if (!SchemaSync_1.SchemaSync.isEnabled(this)) {
|
|
3801
|
+
await this.importSchemasInternal(schemas, { ecSchemaXmlContext: arg.ecSchemaXmlContext }, nativeImportOp);
|
|
3802
|
+
await this.pushChanges(arg);
|
|
3803
|
+
return;
|
|
3804
|
+
}
|
|
3805
|
+
await SchemaSync_1.SchemaSync.withLockedAccess(this, { openMode: core_bentley_1.OpenMode.Readonly, operationName: "schema upgrade" }, async (syncAccess) => {
|
|
3806
|
+
this.saveSchemaChanges();
|
|
3807
|
+
try {
|
|
3808
|
+
nativeImportOp(schemas, {
|
|
3809
|
+
schemaLockHeld: true,
|
|
3810
|
+
ecSchemaXmlContext: arg.ecSchemaXmlContext?.nativeContext,
|
|
3811
|
+
schemaSyncDbUri: syncAccess.getUri(),
|
|
3812
|
+
});
|
|
3813
|
+
}
|
|
3814
|
+
catch (err) {
|
|
3815
|
+
this.abandonSchemaChanges();
|
|
3816
|
+
throw new core_common_1.IModelError(err.errorNumber, err.message);
|
|
3817
|
+
}
|
|
3818
|
+
this.clearCaches();
|
|
3819
|
+
syncAccess.closeDb();
|
|
3820
|
+
await syncAccess.container.uploadChanges();
|
|
3821
|
+
await this.pushChanges(arg);
|
|
3822
|
+
});
|
|
3823
|
+
}
|
|
3723
3824
|
close(options) {
|
|
3724
3825
|
if (this.isBriefcase && this.isOpen && !this.isReadonly && this.txns.rebaser.inProgress()) {
|
|
3725
3826
|
this[Symbols_1._nativeDb].abandonChanges();
|