@itwin/core-backend 5.7.0-dev.8 → 5.8.0-dev.1
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 +8 -1
- package/lib/cjs/BriefcaseManager.d.ts +138 -1
- package/lib/cjs/BriefcaseManager.d.ts.map +1 -1
- package/lib/cjs/BriefcaseManager.js +336 -1
- package/lib/cjs/BriefcaseManager.js.map +1 -1
- package/lib/cjs/CloudSqlite.js +1 -1
- package/lib/cjs/CloudSqlite.js.map +1 -1
- package/lib/cjs/IModelDb.d.ts +71 -0
- package/lib/cjs/IModelDb.d.ts.map +1 -1
- package/lib/cjs/IModelDb.js +122 -6
- package/lib/cjs/IModelDb.js.map +1 -1
- package/lib/cjs/IModelHost.d.ts +15 -0
- package/lib/cjs/IModelHost.d.ts.map +1 -1
- package/lib/cjs/IModelHost.js +12 -0
- package/lib/cjs/IModelHost.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 +2 -0
- package/lib/cjs/IModelJsFs.js.map +1 -1
- package/lib/cjs/TileStorage.js +1 -1
- package/lib/cjs/TileStorage.js.map +1 -1
- package/lib/cjs/TxnManager.d.ts +41 -3
- package/lib/cjs/TxnManager.d.ts.map +1 -1
- package/lib/cjs/TxnManager.js +151 -3
- package/lib/cjs/TxnManager.js.map +1 -1
- package/lib/cjs/ViewDefinition.d.ts.map +1 -1
- package/lib/cjs/ViewDefinition.js +2 -0
- package/lib/cjs/ViewDefinition.js.map +1 -1
- package/lib/cjs/internal/IModelDbFontsImpl.js +1 -1
- package/lib/cjs/internal/IModelDbFontsImpl.js.map +1 -1
- package/lib/cjs/internal/IntegrityCheck.d.ts +240 -0
- package/lib/cjs/internal/IntegrityCheck.d.ts.map +1 -0
- package/lib/cjs/internal/IntegrityCheck.js +193 -0
- package/lib/cjs/internal/IntegrityCheck.js.map +1 -0
- package/lib/cjs/internal/annotations/fields.js +2 -2
- package/lib/cjs/internal/annotations/fields.js.map +1 -1
- package/lib/cjs/rpc/tracing.js +2 -2
- package/lib/cjs/rpc/tracing.js.map +1 -1
- package/lib/cjs/workspace/Workspace.js +1 -1
- package/lib/cjs/workspace/Workspace.js.map +1 -1
- package/lib/esm/BriefcaseManager.d.ts +138 -1
- package/lib/esm/BriefcaseManager.d.ts.map +1 -1
- package/lib/esm/BriefcaseManager.js +336 -1
- package/lib/esm/BriefcaseManager.js.map +1 -1
- package/lib/esm/CloudSqlite.js +1 -1
- package/lib/esm/CloudSqlite.js.map +1 -1
- package/lib/esm/IModelDb.d.ts +71 -0
- package/lib/esm/IModelDb.d.ts.map +1 -1
- package/lib/esm/IModelDb.js +122 -6
- package/lib/esm/IModelDb.js.map +1 -1
- package/lib/esm/IModelHost.d.ts +15 -0
- package/lib/esm/IModelHost.d.ts.map +1 -1
- package/lib/esm/IModelHost.js +12 -0
- package/lib/esm/IModelHost.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 +2 -0
- package/lib/esm/IModelJsFs.js.map +1 -1
- package/lib/esm/TileStorage.js +1 -1
- package/lib/esm/TileStorage.js.map +1 -1
- package/lib/esm/TxnManager.d.ts +41 -3
- package/lib/esm/TxnManager.d.ts.map +1 -1
- package/lib/esm/TxnManager.js +152 -4
- package/lib/esm/TxnManager.js.map +1 -1
- package/lib/esm/ViewDefinition.d.ts.map +1 -1
- package/lib/esm/ViewDefinition.js +2 -0
- package/lib/esm/ViewDefinition.js.map +1 -1
- package/lib/esm/internal/IModelDbFontsImpl.js +1 -1
- package/lib/esm/internal/IModelDbFontsImpl.js.map +1 -1
- package/lib/esm/internal/IntegrityCheck.d.ts +240 -0
- package/lib/esm/internal/IntegrityCheck.d.ts.map +1 -0
- package/lib/esm/internal/IntegrityCheck.js +187 -0
- package/lib/esm/internal/IntegrityCheck.js.map +1 -0
- package/lib/esm/internal/annotations/fields.js +2 -2
- package/lib/esm/internal/annotations/fields.js.map +1 -1
- package/lib/esm/rpc/tracing.js +2 -2
- package/lib/esm/rpc/tracing.js.map +1 -1
- package/lib/esm/test/SquashSchemaAndDataChanges.test.d.ts +2 -0
- package/lib/esm/test/SquashSchemaAndDataChanges.test.d.ts.map +1 -0
- package/lib/esm/test/SquashSchemaAndDataChanges.test.js +241 -0
- package/lib/esm/test/SquashSchemaAndDataChanges.test.js.map +1 -0
- package/lib/esm/test/hubaccess/Rebase.test.js +1575 -1568
- package/lib/esm/test/hubaccess/Rebase.test.js.map +1 -1
- package/lib/esm/test/hubaccess/SemanticRebase.test.d.ts +2 -0
- package/lib/esm/test/hubaccess/SemanticRebase.test.d.ts.map +1 -0
- package/lib/esm/test/hubaccess/SemanticRebase.test.js +1206 -0
- package/lib/esm/test/hubaccess/SemanticRebase.test.js.map +1 -0
- package/lib/esm/test/imodel/IModel.test.js +1 -1
- package/lib/esm/test/imodel/IModel.test.js.map +1 -1
- package/lib/esm/test/standalone/ChangesetReader.test.js +173 -2
- package/lib/esm/test/standalone/ChangesetReader.test.js.map +1 -1
- package/lib/esm/test/standalone/IntegrityCheck.test.d.ts +2 -0
- package/lib/esm/test/standalone/IntegrityCheck.test.d.ts.map +1 -0
- package/lib/esm/test/standalone/IntegrityCheck.test.js +385 -0
- package/lib/esm/test/standalone/IntegrityCheck.test.js.map +1 -0
- package/lib/esm/test/standalone/ViewDefinition.test.js +14 -2
- package/lib/esm/test/standalone/ViewDefinition.test.js.map +1 -1
- package/lib/esm/test/standalone/Workspace.test.js +5 -0
- package/lib/esm/test/standalone/Workspace.test.js.map +1 -1
- package/lib/esm/workspace/Workspace.js +1 -1
- package/lib/esm/workspace/Workspace.js.map +1 -1
- package/package.json +13 -13
|
@@ -5,6 +5,58 @@
|
|
|
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
|
// cspell:ignore cset csets ecchanges
|
|
9
61
|
import * as path from "node:path";
|
|
10
62
|
import * as os from "node:os";
|
|
@@ -19,6 +71,8 @@ import { SchemaSync } from "./SchemaSync";
|
|
|
19
71
|
import { _hubAccess, _nativeDb, _releaseAllLocks } from "./internal/Symbols";
|
|
20
72
|
import { IModelNative } from "./internal/NativePlatform";
|
|
21
73
|
import { StashManager } from "./StashManager";
|
|
74
|
+
import { ChangesetECAdaptor, ECChangeUnifierCache, PartialECChangeUnifier } from "./ChangesetECAdaptor";
|
|
75
|
+
import { SqliteChangesetReader } from "./SqliteChangesetReader";
|
|
22
76
|
const loggerCategory = BackendLoggerCategory.IModelDb;
|
|
23
77
|
/** Manages downloading Briefcases and downloading and uploading changesets.
|
|
24
78
|
* @public
|
|
@@ -229,6 +283,8 @@ export class BriefcaseManager {
|
|
|
229
283
|
briefcaseId: db.getBriefcaseId(),
|
|
230
284
|
};
|
|
231
285
|
db.closeFile();
|
|
286
|
+
if (this.isValidBriefcaseId(briefcase.briefcaseId))
|
|
287
|
+
this.cleanupRebaseFolders(filePath, briefcase.briefcaseId); // cleanup rebase folders
|
|
232
288
|
if (accessToken) {
|
|
233
289
|
if (this.isValidBriefcaseId(briefcase.briefcaseId)) {
|
|
234
290
|
await BriefcaseManager.releaseBriefcase(accessToken, briefcase);
|
|
@@ -462,10 +518,24 @@ export class BriefcaseManager {
|
|
|
462
518
|
Logger.logInfo(loggerCategory, `Creating restore point ${this.PULL_MERGE_RESTORE_POINT_NAME}`);
|
|
463
519
|
await this.createRestorePoint(briefcaseDb, this.PULL_MERGE_RESTORE_POINT_NAME);
|
|
464
520
|
}
|
|
521
|
+
const hasIncomingSchemaChange = changesets.some((changeset) => changeset.changesType === ChangesetType.Schema);
|
|
522
|
+
const hasLocalSchemaTxn = briefcaseDb?.checkIfSchemaTxnExists() ?? false;
|
|
523
|
+
const useSemanticRebase = briefcaseDb !== undefined &&
|
|
524
|
+
IModelHost.useSemanticRebase &&
|
|
525
|
+
(hasIncomingSchemaChange || hasLocalSchemaTxn);
|
|
526
|
+
if (useSemanticRebase) {
|
|
527
|
+
Logger.logInfo(loggerCategory, `Using semantic rebase (incoming schema change: ${hasIncomingSchemaChange}, local schema txn: ${hasLocalSchemaTxn})`);
|
|
528
|
+
}
|
|
465
529
|
if (!reverse) {
|
|
466
530
|
if (briefcaseDb) {
|
|
531
|
+
if (useSemanticRebase) {
|
|
532
|
+
this.capturePatchInstances(briefcaseDb);
|
|
533
|
+
}
|
|
467
534
|
briefcaseDb.txns.rebaser.notifyReverseLocalChangesBegin();
|
|
468
535
|
const reversedTxns = nativeDb.pullMergeReverseLocalChanges();
|
|
536
|
+
if (useSemanticRebase) {
|
|
537
|
+
nativeDb.clearECDbCache(); // Clear the ECDb cache after reversing local changes to ensure consistency during semantic rebase with schema changes.
|
|
538
|
+
}
|
|
469
539
|
const reversedTxnProps = reversedTxns.map((txn) => briefcaseDb.txns.getTxnProps(txn)).filter((props) => props !== undefined);
|
|
470
540
|
briefcaseDb.txns.rebaser.notifyReverseLocalChangesEnd(reversedTxnProps);
|
|
471
541
|
Logger.logInfo(loggerCategory, `Reversed ${reversedTxns.length} local changes`);
|
|
@@ -498,7 +568,10 @@ export class BriefcaseManager {
|
|
|
498
568
|
}
|
|
499
569
|
if (!reverse) {
|
|
500
570
|
if (briefcaseDb) {
|
|
501
|
-
|
|
571
|
+
if (useSemanticRebase)
|
|
572
|
+
await briefcaseDb.txns.rebaser.resumeSemantic();
|
|
573
|
+
else
|
|
574
|
+
await briefcaseDb.txns.rebaser.resume();
|
|
502
575
|
}
|
|
503
576
|
else {
|
|
504
577
|
// Only Briefcase has change management. Following is
|
|
@@ -678,5 +751,267 @@ export class BriefcaseManager {
|
|
|
678
751
|
}
|
|
679
752
|
}
|
|
680
753
|
}
|
|
754
|
+
// #region Semantic Rebase Interop Helper
|
|
755
|
+
static REBASING_FOLDER = ".rebasing";
|
|
756
|
+
static EC_FOLDER = "ec";
|
|
757
|
+
static SCHEMAS_FOLDER = "schemas";
|
|
758
|
+
static DATA_FOLDER = "data";
|
|
759
|
+
static DATA_FILE_NAME = "data.json";
|
|
760
|
+
/**
|
|
761
|
+
* Captures the changed instances as patch instances from each data txn in the briefcase db for semantic rebase
|
|
762
|
+
* @param db The {@link BriefcaseDb} instance for which to capture the changed instances as patch instances for all data txns
|
|
763
|
+
* @internal
|
|
764
|
+
*/
|
|
765
|
+
static capturePatchInstances(db) {
|
|
766
|
+
const txns = Array.from(db.txns.queryTxns());
|
|
767
|
+
txns.forEach((txn) => {
|
|
768
|
+
if (txn.type !== "Data")
|
|
769
|
+
return;
|
|
770
|
+
// already captured(This actually shows that first rebase operation is already done but during that while reinstating this txns,
|
|
771
|
+
// some error happened so the folder still exists so we don't want to capture again)
|
|
772
|
+
if (this.semanticRebaseDataFolderExists(db, txn.id))
|
|
773
|
+
return;
|
|
774
|
+
const changedInstances = this.captureChangedInstancesAsJSON(db, txn.id);
|
|
775
|
+
const instancePatches = this.constructPatchInstances(db, changedInstances);
|
|
776
|
+
this.storeChangedInstancesForSemanticRebase(db, txn.id, instancePatches);
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
/**
|
|
780
|
+
* Captures changed instances from a txn as JSON
|
|
781
|
+
* @param txnId The txn id for which to capture changed instances
|
|
782
|
+
* @param db The {@link BriefcaseDb} instance from which to capture changed instances as json
|
|
783
|
+
* @returns changed instances for semantic rebase
|
|
784
|
+
* @internal
|
|
785
|
+
*/
|
|
786
|
+
static captureChangedInstancesAsJSON(db, txnId) {
|
|
787
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
788
|
+
try {
|
|
789
|
+
const reader = SqliteChangesetReader.openTxn({
|
|
790
|
+
txnId, db, disableSchemaCheck: true
|
|
791
|
+
});
|
|
792
|
+
const adaptor = new ChangesetECAdaptor(reader);
|
|
793
|
+
const indirectUnifier = __addDisposableResource(env_1, new PartialECChangeUnifier(reader.db, ECChangeUnifierCache.createInMemoryCache()), false);
|
|
794
|
+
const directUnifier = __addDisposableResource(env_1, new PartialECChangeUnifier(reader.db, ECChangeUnifierCache.createInMemoryCache()), false);
|
|
795
|
+
while (adaptor.step()) {
|
|
796
|
+
if (adaptor.reader.isIndirect)
|
|
797
|
+
indirectUnifier.appendFrom(adaptor);
|
|
798
|
+
else
|
|
799
|
+
directUnifier.appendFrom(adaptor);
|
|
800
|
+
}
|
|
801
|
+
return [...Array.from(directUnifier.instances).map((instance) => ({ isIndirect: false, instance })), ...Array.from(indirectUnifier.instances).map((instance) => ({ isIndirect: true, instance }))];
|
|
802
|
+
}
|
|
803
|
+
catch (e_1) {
|
|
804
|
+
env_1.error = e_1;
|
|
805
|
+
env_1.hasError = true;
|
|
806
|
+
}
|
|
807
|
+
finally {
|
|
808
|
+
__disposeResources(env_1);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Constructs patch instances from changed instances
|
|
813
|
+
* @param changedInstances The changed instances from which to construct the patch instances
|
|
814
|
+
* @param db The {@link BriefcaseDb} instance for which to construct the patch instances
|
|
815
|
+
* @returns The {@link InstancePatch} instance patches for semantic rebase
|
|
816
|
+
* @internal
|
|
817
|
+
*/
|
|
818
|
+
static constructPatchInstances(db, changedInstances) {
|
|
819
|
+
return changedInstances
|
|
820
|
+
.filter((changedInstance) => !(changedInstance.instance.$meta?.op === "Updated" && changedInstance.instance.$meta.stage === "Old")) // we will not take the old stage of updated instances
|
|
821
|
+
.map((changedInstance) => this.constructPatchInstance(db, changedInstance));
|
|
822
|
+
}
|
|
823
|
+
/**
|
|
824
|
+
* Constructs a single patch instance from changed instance
|
|
825
|
+
* @param changedInstance The changed instance from which to construct the patch instance
|
|
826
|
+
* @param db The {@link BriefcaseDb} instance for which to construct the single patch instance
|
|
827
|
+
* @returns a single instance patch {@link InstancePatch}
|
|
828
|
+
* @throws IModelError If cannot determine classId or unknown operation encountered
|
|
829
|
+
*/
|
|
830
|
+
static constructPatchInstance(db, changedInstance) {
|
|
831
|
+
const className = (changedInstance.instance.ECClassId && db.getClassNameFromId(changedInstance.instance.ECClassId))
|
|
832
|
+
?? changedInstance.instance.$meta?.classFullName
|
|
833
|
+
?? (changedInstance.instance.$meta?.fallbackClassId && db.getClassNameFromId(changedInstance.instance.$meta.fallbackClassId));
|
|
834
|
+
if (!className)
|
|
835
|
+
throw new IModelError(IModelStatus.BadArg, "Cannot determine classId of changed instance");
|
|
836
|
+
const instanceKey = { id: changedInstance.instance.ECInstanceId, classFullName: className };
|
|
837
|
+
const op = changedInstance.instance.$meta?.op;
|
|
838
|
+
if (op !== "Inserted" && op !== "Updated" && op !== "Deleted")
|
|
839
|
+
throw new IModelError(IModelStatus.BadArg, `Unknown operation: ${op}`);
|
|
840
|
+
return {
|
|
841
|
+
key: instanceKey,
|
|
842
|
+
op,
|
|
843
|
+
isIndirect: changedInstance.isIndirect,
|
|
844
|
+
props: op !== "Deleted" ? db[_nativeDb].readInstance(instanceKey, { useJsNames: true }) : undefined,
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
/**
|
|
848
|
+
* Stores changed instances for semantic rebase locally in appropriate json file in a folder structure
|
|
849
|
+
* @param db The {@link BriefcaseDb} instance for storing the changed instances against a txn
|
|
850
|
+
* @param txnId The txn id for which we are storing the changed instances
|
|
851
|
+
* @param instancePatches The {@link InstancePatch} instance patches to be stored
|
|
852
|
+
* @internal
|
|
853
|
+
*/
|
|
854
|
+
static storeChangedInstancesForSemanticRebase(db, txnId, instancePatches) {
|
|
855
|
+
const basePath = this.getBasePathForSemanticRebaseLocalFiles(db);
|
|
856
|
+
const targetDir = path.join(basePath, txnId, this.DATA_FOLDER);
|
|
857
|
+
const filePath = path.join(targetDir, this.DATA_FILE_NAME);
|
|
858
|
+
if (IModelJsFs.existsSync(targetDir))
|
|
859
|
+
IModelJsFs.removeSync(targetDir);
|
|
860
|
+
IModelJsFs.recursiveMkDirSync(targetDir);
|
|
861
|
+
IModelJsFs.writeFileSync(filePath, JSON.stringify(instancePatches, undefined, 2));
|
|
862
|
+
}
|
|
863
|
+
/**
|
|
864
|
+
* Gets the base path for semantic rebase local files
|
|
865
|
+
* @param db The {@link BriefcaseDb} instance for which to get the base path
|
|
866
|
+
* @returns base path for semantic rebase local files
|
|
867
|
+
* @internal
|
|
868
|
+
*/
|
|
869
|
+
static getBasePathForSemanticRebaseLocalFiles(db) {
|
|
870
|
+
return path.join(path.dirname(db.pathName), this.REBASING_FOLDER, db.briefcaseId.toString(), this.EC_FOLDER);
|
|
871
|
+
}
|
|
872
|
+
/**
|
|
873
|
+
* Stores schemas for semantic rebase locally in appropriate folder structure
|
|
874
|
+
* @param db The {@link BriefcaseDb} instance for storing the schemas against a txn
|
|
875
|
+
* @param txnId The txn id for which we are storing the schemas
|
|
876
|
+
* @param schemaFileNames The schema file paths or schema xml strings to be stored
|
|
877
|
+
* @internal
|
|
878
|
+
*/
|
|
879
|
+
static storeSchemasForSemanticRebase(db, txnId, schemaFileNames) {
|
|
880
|
+
const basePath = this.getBasePathForSemanticRebaseLocalFiles(db);
|
|
881
|
+
const targetDir = path.join(basePath, txnId, this.SCHEMAS_FOLDER);
|
|
882
|
+
if (IModelJsFs.existsSync(targetDir))
|
|
883
|
+
IModelJsFs.removeSync(targetDir);
|
|
884
|
+
IModelJsFs.recursiveMkDirSync(targetDir);
|
|
885
|
+
schemaFileNames.forEach((schemaFileOrXml, index) => {
|
|
886
|
+
if (IModelJsFs.existsSync(schemaFileOrXml)) { // This means it is a file
|
|
887
|
+
const fileName = path.basename(schemaFileOrXml);
|
|
888
|
+
const filePath = path.join(targetDir, fileName);
|
|
889
|
+
IModelJsFs.copySync(schemaFileOrXml, filePath);
|
|
890
|
+
}
|
|
891
|
+
else {
|
|
892
|
+
const fileName = `${"Schema"}_${index}.ecschema.xml`;
|
|
893
|
+
const filePath = path.join(targetDir, fileName);
|
|
894
|
+
IModelJsFs.writeFileSync(filePath, schemaFileOrXml);
|
|
895
|
+
}
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
/**
|
|
899
|
+
* Gets schemas for semantic rebase for a txn
|
|
900
|
+
* @param db The {@link BriefcaseDb} instance for getting the locally stored schemas against a txn
|
|
901
|
+
* @param txnId The txn id for which we are getting the schemas
|
|
902
|
+
* @returns the schema file paths
|
|
903
|
+
* @internal
|
|
904
|
+
*/
|
|
905
|
+
static getSchemasForTxn(db, txnId) {
|
|
906
|
+
const basePath = BriefcaseManager.getBasePathForSemanticRebaseLocalFiles(db);
|
|
907
|
+
const folderPath = path.join(basePath, txnId, BriefcaseManager.SCHEMAS_FOLDER);
|
|
908
|
+
return IModelJsFs.readdirSync(folderPath).map((file) => path.join(folderPath, file));
|
|
909
|
+
}
|
|
910
|
+
/**
|
|
911
|
+
* Get the changed instances data for semantic rebase for a txn
|
|
912
|
+
* @param db - The {@link BriefcaseDb} instance for getting the locally stored changed instances against a txn
|
|
913
|
+
* @param txnId - The txn id for which we are getting the changed instances
|
|
914
|
+
* @returns Instance patches
|
|
915
|
+
* @internal
|
|
916
|
+
*/
|
|
917
|
+
static getChangedInstancesDataForTxn(db, txnId) {
|
|
918
|
+
const basePath = BriefcaseManager.getBasePathForSemanticRebaseLocalFiles(db);
|
|
919
|
+
const folderPath = path.join(basePath, txnId, BriefcaseManager.DATA_FOLDER);
|
|
920
|
+
const filePath = path.join(folderPath, BriefcaseManager.DATA_FILE_NAME);
|
|
921
|
+
const fileContents = IModelJsFs.readFileWithEncodingSync(filePath, "utf-8");
|
|
922
|
+
return JSON.parse(fileContents);
|
|
923
|
+
}
|
|
924
|
+
/**
|
|
925
|
+
* Checks if schema folder exists for semantic rebase for a txn
|
|
926
|
+
* @param db - The {@link BriefcaseDb} instance for which TO check the schema folder
|
|
927
|
+
* @param txnId - The txn id for which we are check the schema folder
|
|
928
|
+
* @returns true if exists, false otherwise
|
|
929
|
+
* @internal
|
|
930
|
+
*/
|
|
931
|
+
static semanticRebaseSchemaFolderExists(db, txnId) {
|
|
932
|
+
const basePath = BriefcaseManager.getBasePathForSemanticRebaseLocalFiles(db);
|
|
933
|
+
const folderPath = path.join(basePath, txnId, BriefcaseManager.SCHEMAS_FOLDER);
|
|
934
|
+
return IModelJsFs.existsSync(folderPath);
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* Checks if data folder exists for semantic rebase for a txn
|
|
938
|
+
* @param db The {@link BriefcaseDb} instance for which to check the data folder.
|
|
939
|
+
* @param txnId The txn id for which to check the data folder
|
|
940
|
+
* @returns true if exists, false otherwise
|
|
941
|
+
* @internal
|
|
942
|
+
*/
|
|
943
|
+
static semanticRebaseDataFolderExists(db, txnId) {
|
|
944
|
+
const basePath = BriefcaseManager.getBasePathForSemanticRebaseLocalFiles(db);
|
|
945
|
+
const folderPath = path.join(basePath, txnId, BriefcaseManager.DATA_FOLDER);
|
|
946
|
+
return IModelJsFs.existsSync(folderPath);
|
|
947
|
+
}
|
|
948
|
+
/**
|
|
949
|
+
* Deletes the schema folder for semantic rebase for a txn
|
|
950
|
+
* @param db The {@link BriefcaseDb} instance for which to delete the schema folder.
|
|
951
|
+
* @param txnId The txn id for which to delete the schema folder
|
|
952
|
+
* @internal
|
|
953
|
+
*/
|
|
954
|
+
static deleteTxnSchemaFolder(db, txnId) {
|
|
955
|
+
const basePath = BriefcaseManager.getBasePathForSemanticRebaseLocalFiles(db);
|
|
956
|
+
const txnFolderPath = path.join(basePath, txnId);
|
|
957
|
+
const folderPath = path.join(txnFolderPath, BriefcaseManager.SCHEMAS_FOLDER);
|
|
958
|
+
if (!IModelJsFs.existsSync(folderPath))
|
|
959
|
+
return;
|
|
960
|
+
IModelJsFs.removeSync(folderPath);
|
|
961
|
+
if (IModelJsFs.readdirSync(txnFolderPath).length === 0) // Also delete the txn folder if empty
|
|
962
|
+
IModelJsFs.removeSync(txnFolderPath);
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* Deletes the data folder for semantic rebase for a txn
|
|
966
|
+
* @param db The {@link BriefcaseDb} instance for which to delete the data folder.
|
|
967
|
+
* @param txnId The txn id for which to delete the data folder
|
|
968
|
+
* @internal
|
|
969
|
+
*/
|
|
970
|
+
static deleteTxnDataFolder(db, txnId) {
|
|
971
|
+
const basePath = BriefcaseManager.getBasePathForSemanticRebaseLocalFiles(db);
|
|
972
|
+
const txnFolderPath = path.join(basePath, txnId);
|
|
973
|
+
const folderPath = path.join(txnFolderPath, BriefcaseManager.DATA_FOLDER);
|
|
974
|
+
if (!IModelJsFs.existsSync(folderPath))
|
|
975
|
+
return;
|
|
976
|
+
IModelJsFs.removeSync(folderPath);
|
|
977
|
+
if (IModelJsFs.readdirSync(txnFolderPath).length === 0) // Also delete the txn folder if empty
|
|
978
|
+
IModelJsFs.removeSync(txnFolderPath);
|
|
979
|
+
}
|
|
980
|
+
/**
|
|
981
|
+
* Deletes rebase folders for semantic rebase
|
|
982
|
+
* @param db The {@link BriefcaseDb} instance for which to delete the rebase folders.
|
|
983
|
+
* @param checkIfEmpty If true, only deletes the base folder if it is empty, default is false
|
|
984
|
+
* @internal
|
|
985
|
+
*/
|
|
986
|
+
static deleteRebaseFolders(db, checkIfEmpty = false) {
|
|
987
|
+
const briefcaseRebasingRoot = path.join(path.dirname(db.pathName), this.REBASING_FOLDER, db.briefcaseId.toString());
|
|
988
|
+
if (!IModelJsFs.existsSync(briefcaseRebasingRoot))
|
|
989
|
+
return;
|
|
990
|
+
if (checkIfEmpty) {
|
|
991
|
+
const basePath = this.getBasePathForSemanticRebaseLocalFiles(db);
|
|
992
|
+
if (IModelJsFs.existsSync(basePath) && IModelJsFs.readdirSync(basePath).length > 0)
|
|
993
|
+
return;
|
|
994
|
+
}
|
|
995
|
+
IModelJsFs.removeSync(briefcaseRebasingRoot);
|
|
996
|
+
// remove .rebasing root if it's now empty
|
|
997
|
+
const rebasingRoot = path.join(path.dirname(db.pathName), this.REBASING_FOLDER);
|
|
998
|
+
if (IModelJsFs.existsSync(rebasingRoot) && IModelJsFs.readdirSync(rebasingRoot).length === 0)
|
|
999
|
+
IModelJsFs.removeSync(rebasingRoot);
|
|
1000
|
+
}
|
|
1001
|
+
/**
|
|
1002
|
+
* Cleans up rebase folders for semantic rebase given briefcase file path and briefcase id
|
|
1003
|
+
* @param briefcaseFilePath The briefcase file path
|
|
1004
|
+
* @param briefcaseId The briefcase id
|
|
1005
|
+
* @internal
|
|
1006
|
+
*/
|
|
1007
|
+
static cleanupRebaseFolders(briefcaseFilePath, briefcaseId) {
|
|
1008
|
+
const briefcaseRebasingRoot = path.join(path.dirname(briefcaseFilePath), this.REBASING_FOLDER, briefcaseId.toString());
|
|
1009
|
+
if (IModelJsFs.existsSync(briefcaseRebasingRoot))
|
|
1010
|
+
IModelJsFs.removeSync(briefcaseRebasingRoot);
|
|
1011
|
+
// remove .rebasing root if it's now empty
|
|
1012
|
+
const rebasingRoot = path.join(path.dirname(briefcaseFilePath), this.REBASING_FOLDER);
|
|
1013
|
+
if (IModelJsFs.existsSync(rebasingRoot) && IModelJsFs.readdirSync(rebasingRoot).length === 0)
|
|
1014
|
+
IModelJsFs.removeSync(rebasingRoot);
|
|
1015
|
+
}
|
|
681
1016
|
}
|
|
682
1017
|
//# sourceMappingURL=BriefcaseManager.js.map
|