@itwin/core-backend 5.9.0 → 5.9.2
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 +15 -1
- package/lib/cjs/BriefcaseManager.d.ts +17 -59
- package/lib/cjs/BriefcaseManager.d.ts.map +1 -1
- package/lib/cjs/BriefcaseManager.js +45 -162
- package/lib/cjs/BriefcaseManager.js.map +1 -1
- package/lib/cjs/IModelJsFs.d.ts +2 -0
- package/lib/cjs/IModelJsFs.d.ts.map +1 -1
- package/lib/cjs/IModelJsFs.js +14 -0
- package/lib/cjs/IModelJsFs.js.map +1 -1
- package/lib/cjs/TxnManager.d.ts +3 -0
- package/lib/cjs/TxnManager.d.ts.map +1 -1
- package/lib/cjs/TxnManager.js +95 -13
- package/lib/cjs/TxnManager.js.map +1 -1
- package/lib/cjs/internal/cross-package.d.ts +1 -1
- package/lib/cjs/internal/cross-package.d.ts.map +1 -1
- package/lib/cjs/internal/cross-package.js +2 -1
- package/lib/cjs/internal/cross-package.js.map +1 -1
- package/lib/esm/BriefcaseManager.d.ts +17 -59
- package/lib/esm/BriefcaseManager.d.ts.map +1 -1
- package/lib/esm/BriefcaseManager.js +46 -163
- package/lib/esm/BriefcaseManager.js.map +1 -1
- package/lib/esm/IModelJsFs.d.ts +2 -0
- package/lib/esm/IModelJsFs.d.ts.map +1 -1
- package/lib/esm/IModelJsFs.js +14 -0
- package/lib/esm/IModelJsFs.js.map +1 -1
- package/lib/esm/TxnManager.d.ts +3 -0
- package/lib/esm/TxnManager.d.ts.map +1 -1
- package/lib/esm/TxnManager.js +96 -14
- package/lib/esm/TxnManager.js.map +1 -1
- package/lib/esm/internal/cross-package.d.ts +1 -1
- package/lib/esm/internal/cross-package.d.ts.map +1 -1
- package/lib/esm/internal/cross-package.js +1 -1
- package/lib/esm/internal/cross-package.js.map +1 -1
- package/lib/esm/test/hubaccess/SemanticRebase.test.js +2276 -70
- package/lib/esm/test/hubaccess/SemanticRebase.test.js.map +1 -1
- package/package.json +14 -14
package/lib/esm/TxnManager.js
CHANGED
|
@@ -5,14 +5,68 @@
|
|
|
5
5
|
/** @packageDocumentation
|
|
6
6
|
* @module iModels
|
|
7
7
|
*/
|
|
8
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
9
|
+
if (value !== null && value !== void 0) {
|
|
10
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
11
|
+
var dispose, inner;
|
|
12
|
+
if (async) {
|
|
13
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
14
|
+
dispose = value[Symbol.asyncDispose];
|
|
15
|
+
}
|
|
16
|
+
if (dispose === void 0) {
|
|
17
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
18
|
+
dispose = value[Symbol.dispose];
|
|
19
|
+
if (async) inner = dispose;
|
|
20
|
+
}
|
|
21
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
22
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
23
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
24
|
+
}
|
|
25
|
+
else if (async) {
|
|
26
|
+
env.stack.push({ async: true });
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
};
|
|
30
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
31
|
+
return function (env) {
|
|
32
|
+
function fail(e) {
|
|
33
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
34
|
+
env.hasError = true;
|
|
35
|
+
}
|
|
36
|
+
var r, s = 0;
|
|
37
|
+
function next() {
|
|
38
|
+
while (r = env.stack.pop()) {
|
|
39
|
+
try {
|
|
40
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
41
|
+
if (r.dispose) {
|
|
42
|
+
var result = r.dispose.call(r.value);
|
|
43
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
44
|
+
}
|
|
45
|
+
else s |= 1;
|
|
46
|
+
}
|
|
47
|
+
catch (e) {
|
|
48
|
+
fail(e);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
52
|
+
if (env.hasError) throw env.error;
|
|
53
|
+
}
|
|
54
|
+
return next();
|
|
55
|
+
};
|
|
56
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
57
|
+
var e = new Error(message);
|
|
58
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
59
|
+
});
|
|
8
60
|
import * as touch from "touch";
|
|
9
|
-
import { assert, BeEvent, BentleyError, compareStrings, CompressedId64Set, DbConflictResolution, DbResult, IModelStatus, IndexMap, Logger, OrderedId64Array } from "@itwin/core-bentley";
|
|
61
|
+
import { assert, BeEvent, BentleyError, compareStrings, CompressedId64Set, DbConflictResolution, DbResult, Id64, IModelStatus, IndexMap, Logger, OrderedId64Array } from "@itwin/core-bentley";
|
|
10
62
|
import { IModelError } from "@itwin/core-common";
|
|
11
63
|
import { BackendLoggerCategory } from "./BackendLoggerCategory";
|
|
12
64
|
import { IpcHost } from "./IpcHost";
|
|
13
65
|
import { _nativeDb } from "./internal/Symbols";
|
|
14
66
|
import { RebaseChangesetConflictArgs } from "./internal/ChangesetConflictArgs";
|
|
15
67
|
import { BriefcaseManager } from "./BriefcaseManager";
|
|
68
|
+
import { ChangesetReader } from "./ChangesetReader";
|
|
69
|
+
import { ChangeUnifierCache, PartialChangeUnifier } from "./PartialChangeUnifier";
|
|
16
70
|
/** Strictly for tests. @internal */
|
|
17
71
|
export function setMaxEntitiesPerEvent(max) {
|
|
18
72
|
const prevMax = ChangedEntitiesProc.maxPerEvent;
|
|
@@ -514,16 +568,15 @@ export class RebaseManager {
|
|
|
514
568
|
if (!BriefcaseManager.semanticRebaseDataFolderExists(this._iModel, txnProps.id)) {
|
|
515
569
|
throw new IModelError(IModelStatus.BadRequest, `Local folder does not exist for transaction ${txnProps.id}`);
|
|
516
570
|
}
|
|
517
|
-
const
|
|
518
|
-
|
|
519
|
-
if (instance.isIndirect) {
|
|
571
|
+
for await (const instance of BriefcaseManager.getChangedInstancesDataForTxn(this._iModel, txnProps.id)) {
|
|
572
|
+
if (instance.$meta.isIndirectChange) {
|
|
520
573
|
this._iModel.txns.withIndirectTxnMode(() => {
|
|
521
574
|
this.applyInstancePatch(instance);
|
|
522
575
|
});
|
|
523
|
-
|
|
576
|
+
continue;
|
|
524
577
|
}
|
|
525
578
|
this.applyInstancePatch(instance);
|
|
526
|
-
}
|
|
579
|
+
}
|
|
527
580
|
BriefcaseManager.deleteTxnDataFolder(this._iModel, txnProps.id); // delete the folder after importing
|
|
528
581
|
}
|
|
529
582
|
else {
|
|
@@ -537,27 +590,34 @@ export class RebaseManager {
|
|
|
537
590
|
*/
|
|
538
591
|
applyInstancePatch(instance) {
|
|
539
592
|
const nativeDb = this._iModel[_nativeDb];
|
|
540
|
-
|
|
593
|
+
const { $meta, ...props } = instance;
|
|
594
|
+
switch ($meta.op) {
|
|
541
595
|
case "Inserted": {
|
|
542
|
-
if (!
|
|
596
|
+
if (!props)
|
|
543
597
|
throw new IModelError(IModelStatus.BadRequest, "InstancePatch with op 'Inserted' must have props");
|
|
544
598
|
const options = { forceUseId: true, useJsNames: true };
|
|
545
|
-
nativeDb.insertInstance(
|
|
599
|
+
const id = nativeDb.insertInstance(props, options);
|
|
600
|
+
if (!Id64.isValidId64(id))
|
|
601
|
+
throw new IModelError(IModelStatus.BadRequest, `Failed to insert instance with id ${props.id}`);
|
|
546
602
|
break;
|
|
547
603
|
}
|
|
548
604
|
case "Updated": {
|
|
549
|
-
if (!
|
|
605
|
+
if (!props)
|
|
550
606
|
throw new IModelError(IModelStatus.BadRequest, "InstancePatch with op 'Updated' must have props");
|
|
551
|
-
nativeDb.updateInstance(
|
|
607
|
+
const isSuccess = nativeDb.updateInstance(props, { useJsNames: true });
|
|
608
|
+
if (!isSuccess)
|
|
609
|
+
throw new IModelError(IModelStatus.BadRequest, `Failed to update instance with id ${props.id}`);
|
|
552
610
|
break;
|
|
553
611
|
}
|
|
554
612
|
case "Deleted": {
|
|
555
|
-
const key = { id:
|
|
556
|
-
nativeDb.deleteInstance(key, { useJsNames: true });
|
|
613
|
+
const key = { id: props.id, classFullName: props.className };
|
|
614
|
+
const isSuccess = nativeDb.deleteInstance(key, { useJsNames: true });
|
|
615
|
+
if (!isSuccess)
|
|
616
|
+
throw new IModelError(IModelStatus.BadRequest, `Failed to delete instance with id ${props.id}`);
|
|
557
617
|
break;
|
|
558
618
|
}
|
|
559
619
|
default:
|
|
560
|
-
throw new IModelError(IModelStatus.BadRequest, `Unknown InstancePatch op '${
|
|
620
|
+
throw new IModelError(IModelStatus.BadRequest, `Unknown InstancePatch op '${$meta.op}'`);
|
|
561
621
|
}
|
|
562
622
|
}
|
|
563
623
|
/**
|
|
@@ -800,6 +860,28 @@ export class TxnManager {
|
|
|
800
860
|
this.onEndValidation.raiseEvent();
|
|
801
861
|
// TODO: if (this.validationErrors.length !== 0) throw new IModelError(validation ...)
|
|
802
862
|
}
|
|
863
|
+
/** Called by native code during semantic rebase while reversing local changes to create instance patches to be used for reinstating changes.
|
|
864
|
+
* @internal */
|
|
865
|
+
_captureInstanceChanges(id) {
|
|
866
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
867
|
+
try {
|
|
868
|
+
if (BriefcaseManager.semanticRebaseDataFolderExists(this._iModel, id))
|
|
869
|
+
return; // if folder already exists that means we have already captured the changes for this txn during this rebase so we can skip capturing again
|
|
870
|
+
const reader = __addDisposableResource(env_1, ChangesetReader.openTxn({ db: this._iModel, txnId: id, rowOptions: { useJsName: true, abbreviateBlobs: false } }), false);
|
|
871
|
+
const pcu = __addDisposableResource(env_1, new PartialChangeUnifier(ChangeUnifierCache.createSqliteBackedCache()), false);
|
|
872
|
+
while (reader.step()) {
|
|
873
|
+
pcu.appendFrom(reader);
|
|
874
|
+
}
|
|
875
|
+
BriefcaseManager.storeChangedInstancesForSemanticRebase(this._iModel, id, pcu.instances);
|
|
876
|
+
}
|
|
877
|
+
catch (e_1) {
|
|
878
|
+
env_1.error = e_1;
|
|
879
|
+
env_1.hasError = true;
|
|
880
|
+
}
|
|
881
|
+
finally {
|
|
882
|
+
__disposeResources(env_1);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
803
885
|
/** @internal */
|
|
804
886
|
_onGeometryChanged(modelProps) {
|
|
805
887
|
this.onGeometryChanged.raiseEvent(modelProps);
|