@itwin/core-backend 5.12.0-dev.11 → 5.12.0-dev.13
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/IModelDb.d.ts.map +1 -1
- package/lib/cjs/IModelDb.js +2 -4
- package/lib/cjs/IModelDb.js.map +1 -1
- package/lib/cjs/SQLiteDb.d.ts +34 -0
- package/lib/cjs/SQLiteDb.d.ts.map +1 -1
- package/lib/cjs/SQLiteDb.js +42 -0
- package/lib/cjs/SQLiteDb.js.map +1 -1
- package/lib/esm/IModelDb.d.ts.map +1 -1
- package/lib/esm/IModelDb.js +2 -4
- package/lib/esm/IModelDb.js.map +1 -1
- package/lib/esm/SQLiteDb.d.ts +34 -0
- package/lib/esm/SQLiteDb.d.ts.map +1 -1
- package/lib/esm/SQLiteDb.js +42 -0
- package/lib/esm/SQLiteDb.js.map +1 -1
- package/lib/esm/test/standalone/MergeConflict.test.js +1 -1
- package/lib/esm/test/standalone/MergeConflict.test.js.map +1 -1
- package/lib/esm/test/standalone/SQLiteDb.test.d.ts +1 -1
- package/lib/esm/test/standalone/SQLiteDb.test.d.ts.map +1 -1
- package/lib/esm/test/standalone/SQLiteDb.test.js +146 -1
- package/lib/esm/test/standalone/SQLiteDb.test.js.map +1 -1
- package/package.json +13 -13
package/lib/esm/SQLiteDb.d.ts
CHANGED
|
@@ -101,6 +101,40 @@ export declare class SQLiteDb {
|
|
|
101
101
|
saveChanges(): void;
|
|
102
102
|
/** Abandon (cancel) the outermost transaction, discarding all changes since last save. Then, restart the default transaction. */
|
|
103
103
|
abandonChanges(): void;
|
|
104
|
+
/**
|
|
105
|
+
* Apply a changeset file - in the same on-disk format used for iModel changesets - to this SQLiteDb.
|
|
106
|
+
* Unlike `BriefcaseDb.pullChanges`, this does *not* validate the changeset header (e.g. parentId/changesetId)
|
|
107
|
+
* against the current state of the database - it simply applies the changes it contains. If applying the
|
|
108
|
+
* changeset encounters any conflict, or otherwise fails, this method throws (conflicts are never resolved
|
|
109
|
+
* automatically).
|
|
110
|
+
* @note this method only throws on failure - it does *not* commit or abandon any changes itself. If it
|
|
111
|
+
* throws, some (but not necessarily all) of the changeset's changes may have already been applied to the
|
|
112
|
+
* current transaction. It is the caller's responsibility to call [[saveChanges]] or [[abandonChanges]]
|
|
113
|
+
* as appropriate after catching an error from this method.
|
|
114
|
+
* @param changesetFile the local file name of the changeset to apply.
|
|
115
|
+
* @internal
|
|
116
|
+
*/
|
|
117
|
+
applyChangeset(changesetFile: LocalFileName): void;
|
|
118
|
+
/**
|
|
119
|
+
* Begin capturing DDL and data changes made to this SQLiteDb, so they may later be saved via [[createChangeset]].
|
|
120
|
+
* Intended only to produce changeset files for testing [[applyChangeset]] - not for any other purpose.
|
|
121
|
+
* @internal
|
|
122
|
+
*/
|
|
123
|
+
startChangeTracking(): void;
|
|
124
|
+
/**
|
|
125
|
+
* Execute a DDL statement (e.g. `CREATE TABLE`) so that, if change tracking is active (see [[startChangeTracking]]),
|
|
126
|
+
* the DDL is captured for inclusion in the changeset produced by [[createChangeset]]. DDL executed via [[executeSQL]]
|
|
127
|
+
* is *not* captured for change tracking purposes.
|
|
128
|
+
* @internal
|
|
129
|
+
*/
|
|
130
|
+
executeDdl(ddl: string): void;
|
|
131
|
+
/**
|
|
132
|
+
* Write out the changes captured since [[startChangeTracking]] was called to a changeset file, in the same
|
|
133
|
+
* on-disk format used for iModel changesets.
|
|
134
|
+
* @param changesetFile the local file name to write the changeset to.
|
|
135
|
+
* @internal
|
|
136
|
+
*/
|
|
137
|
+
createChangeset(changesetFile: LocalFileName): void;
|
|
104
138
|
/**
|
|
105
139
|
* Use a prepared SQL statement, potentially from the statement cache. If the requested statement doesn't exist
|
|
106
140
|
* in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SQLiteDb.d.ts","sourceRoot":"","sources":["../../src/SQLiteDb.ts"],"names":[],"mappings":"AAIA;;GAEG;AAKH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAe,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,EAAE,eAAe,EAAkB,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAI/C;;;GAGG;AACH,qBAAa,QAAQ;IACnB,gBAAgB;IAChB,SAAgB,CAAC,SAAS,CAAC,0BAAwC;IACnE,OAAO,CAAC,qBAAqB,CAAyC;IAEtE,gBAAgB;WACF,YAAY,IAAI,QAAQ,CAAC,MAAM;IAI7C;;OAEG;IACI,OAAO,IAAI,IAAI;IAItB;;OAEG;IACI,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IACrC,YAAY;IACL,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,WAAW,CAAC,cAAc,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,YAAY,GAAG,IAAI;IAK7G;;OAEG;IACI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC,UAAU,GAAG,IAAI;IAC7E;;;OAGG;IACI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,WAAW,CAAC,cAAc,GAAG,IAAI;IAKrH;;OAEG;IACI,OAAO,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI;IAO3C,4CAA4C;IAC5C,IAAW,MAAM,IAAI,OAAO,CAAqC;IAEjE,qDAAqD;IACrD,IAAW,UAAU,IAAI,OAAO,CAAyC;IAEzE,2CAA2C;IAC3C,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE;QAC1B,uCAAuC;QACvC,SAAS,EAAE,MAAM,CAAC;QAClB,uCAAuC;QACvC,OAAO,EAAE,MAAM,CAAC;QAChB,4CAA4C;QAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,yFAAyF;QACzF,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB;IAQD;;;MAGE;IACK,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAO9D;;;;;;;;;;;OAWG;IACI,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,cAAc,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC;IAgB1E;;OAEG;IACH,IAAW,cAAc,IAAI,WAAW,CAAC,cAAc,GAAG,SAAS,CAElE;IAED,+JAA+J;IACxJ,kBAAkB,IAAI,MAAM;IAInC;;;;;;;;;;;;OAYG;IACU,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,eAAe,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC;IAIlG;;OAEG;IACI,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,YAAY;IAI1C,4GAA4G;IACrG,WAAW,IAAI,IAAI;IAI1B,iIAAiI;IAC1H,cAAc,IAAI,IAAI;IAI7B;;;;;;;;;OASG;IACI,2BAA2B,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,CAAC,GAAG,CAAC;IAa7F;;;;;;;OAOG;IACI,mBAAmB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,CAAC,GAAG,CAAC;IAarF;;;;OAIG;IACI,aAAa,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,IAAI;IAcjE;;;;SAIK;IACE,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,UAAO,GAAG,eAAe;IAM7E,+BAA+B;IACxB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ;CAIzC;AAED;;;;;;;;;;GAUG;AACH,8BAAsB,iBAAkB,SAAQ,QAAQ;IACtD,SAAS,CAAC,MAAM,CAAC,aAAa;;;MAAwD;IAEtF;;;;;;;;MAQE;IACF,SAAgB,SAAS,EAAE,MAAM,CAAC;IAElC;;;;;OAKG;IACI,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,qBAAqB;IAKnE,gFAAgF;IACzE,mBAAmB;IAa1B;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IAE7C;;;OAGG;WACW,WAAW,CAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE,GAAG;IAalE;;;OAGG;IACH,SAAS,CAAC,cAAc;IAaxB;;;;OAIG;IACa,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,WAAW,CAAC,cAAc;IAK1G,aAAa,CAAC,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE;YAAE,SAAS,EAAE,WAAW,CAAC,cAAc,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,SAAS,EAAE,MAAM,IAAI,CAAA;KAAE,yBAAN,IAAI;CAMjJ;AAED,cAAc;AACd,yBAAiB,QAAQ,CAAC;IACxB;;OAEG;IACH,KAAY,YAAY,GAAG,MAAM,CAAC;IAElC;;;OAGG;IACH,UAAiB,qBAAqB;QACpC,uFAAuF;QACvF,QAAQ,CAAC,WAAW,EAAE,YAAY,CAAC;QACnC,qFAAqF;QACrF,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;KACrC;IAED;;OAEG;IACH,UAAiB,MAAM;QACrB;;YAEI;QACJ,KAAK,IAAI,IAAI,CAAC;QACd,gDAAgD;QAChD,WAAW,IAAI,MAAM,CAAC;QACtB,mGAAmG;QACnG,OAAO,IAAI,OAAO,CAAC;QACnB,0DAA0D;QAC1D,IAAI;QACF,gCAAgC;QAChC,EAAE,EAAE,cAAc,CAAC,KAAK,EACxB,IAAI,EAAE;YACJ,wCAAwC;YACxC,SAAS,EAAE,MAAM,CAAC;YAClB,0CAA0C;YAC1C,UAAU,EAAE,MAAM,CAAC;YACnB,4BAA4B;YAC5B,GAAG,EAAE,MAAM,CAAC;YACZ,iDAAiD;YACjD,SAAS,CAAC,EAAE,OAAO,CAAC;SACrB,GAAG,IAAI,CAAC;QACX;;aAEK;QACL,IAAI,CAAC,IAAI,EAAE;YACT,kCAAkC;YAClC,QAAQ,EAAE,MAAM,CAAC;YACjB,8CAA8C;YAC9C,MAAM,EAAE,MAAM,CAAC;YACf,6EAA6E;YAC7E,IAAI,CAAC,EAAE,WAAW,CAAC;SACpB,GAAG,UAAU,CAAC;QACf;;aAEK;QACL,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,sBAAsB;QACtB,KAAK,CAAC,IAAI,EAAE;YACV,oCAAoC;YACpC,QAAQ,EAAE,MAAM,CAAC;YACjB,+CAA+C;YAC/C,MAAM,EAAE,MAAM,CAAC;YACf,yBAAyB;YACzB,IAAI,EAAE,WAAW,CAAC;SACnB,GAAG,IAAI,CAAC;KACV;IAED;;OAEG;IACH,KAAY,cAAc;QACxB,4GAA4G;QAC5G,IAAI,IAAI;QACR,4FAA4F;QAC5F,QAAQ,IAAI;QACZ,yEAAyE;QACzE,SAAS,IAAI;QACb,yEAAyE;QACzE,SAAS,IAAI;KACd;IAED,8DAA8D;IAC9D,UAAiB,kBAAkB;QACjC,6DAA6D;QAC7D,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,sEAAsE;QACtE,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,oFAAoF;QACpF,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB;;QAEA;QACA,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3B,2FAA2F;QAC3F,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB;IAED,kDAAkD;IAClD,UAAiB,UAAW,SAAQ,kBAAkB;QACpD,gEAAgE;QAChE,QAAQ,EAAE,QAAQ,CAAC;KACpB;IAED,uCAAuC;IACvC,UAAiB,QAAQ;QACvB,8DAA8D;QAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;IAED,6CAA6C;IAC7C,KAAY,YAAY,GAAG,kBAAkB,GAAG,QAAQ,CAAC;IAEzD,0CAA0C;IAC1C,UAAiB,cAAc;QAC7B,uCAAuC;QACvC,MAAM,EAAE,MAAM,CAAC;QACf,wEAAwE;QACxE,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC;QAC1C,gBAAgB;QAChB,SAAS,CAAC,EAAE,WAAW,CAAC,cAAc,CAAC;KACxC;IAED,sCAAsC;IACtC,UAAiB,YAAa,SAAQ,QAAQ;QAC5C,6FAA6F;QAC7F,IAAI,CAAC,EAAE,aAAa,CAAC;KACtB;CACF"}
|
|
1
|
+
{"version":3,"file":"SQLiteDb.d.ts","sourceRoot":"","sources":["../../src/SQLiteDb.ts"],"names":[],"mappings":"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"}
|
package/lib/esm/SQLiteDb.js
CHANGED
|
@@ -190,6 +190,48 @@ export class SQLiteDb {
|
|
|
190
190
|
abandonChanges() {
|
|
191
191
|
this[_nativeDb].abandonChanges();
|
|
192
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Apply a changeset file - in the same on-disk format used for iModel changesets - to this SQLiteDb.
|
|
195
|
+
* Unlike `BriefcaseDb.pullChanges`, this does *not* validate the changeset header (e.g. parentId/changesetId)
|
|
196
|
+
* against the current state of the database - it simply applies the changes it contains. If applying the
|
|
197
|
+
* changeset encounters any conflict, or otherwise fails, this method throws (conflicts are never resolved
|
|
198
|
+
* automatically).
|
|
199
|
+
* @note this method only throws on failure - it does *not* commit or abandon any changes itself. If it
|
|
200
|
+
* throws, some (but not necessarily all) of the changeset's changes may have already been applied to the
|
|
201
|
+
* current transaction. It is the caller's responsibility to call [[saveChanges]] or [[abandonChanges]]
|
|
202
|
+
* as appropriate after catching an error from this method.
|
|
203
|
+
* @param changesetFile the local file name of the changeset to apply.
|
|
204
|
+
* @internal
|
|
205
|
+
*/
|
|
206
|
+
applyChangeset(changesetFile) {
|
|
207
|
+
this[_nativeDb].applyChangeset(changesetFile);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Begin capturing DDL and data changes made to this SQLiteDb, so they may later be saved via [[createChangeset]].
|
|
211
|
+
* Intended only to produce changeset files for testing [[applyChangeset]] - not for any other purpose.
|
|
212
|
+
* @internal
|
|
213
|
+
*/
|
|
214
|
+
startChangeTracking() {
|
|
215
|
+
this[_nativeDb].startChangeTracking();
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Execute a DDL statement (e.g. `CREATE TABLE`) so that, if change tracking is active (see [[startChangeTracking]]),
|
|
219
|
+
* the DDL is captured for inclusion in the changeset produced by [[createChangeset]]. DDL executed via [[executeSQL]]
|
|
220
|
+
* is *not* captured for change tracking purposes.
|
|
221
|
+
* @internal
|
|
222
|
+
*/
|
|
223
|
+
executeDdl(ddl) {
|
|
224
|
+
this[_nativeDb].executeDdl(ddl);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Write out the changes captured since [[startChangeTracking]] was called to a changeset file, in the same
|
|
228
|
+
* on-disk format used for iModel changesets.
|
|
229
|
+
* @param changesetFile the local file name to write the changeset to.
|
|
230
|
+
* @internal
|
|
231
|
+
*/
|
|
232
|
+
createChangeset(changesetFile) {
|
|
233
|
+
this[_nativeDb].createChangeset(changesetFile);
|
|
234
|
+
}
|
|
193
235
|
/**
|
|
194
236
|
* Use a prepared SQL statement, potentially from the statement cache. If the requested statement doesn't exist
|
|
195
237
|
* in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved
|
package/lib/esm/SQLiteDb.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SQLiteDb.js","sourceRoot":"","sources":["../../src/SQLiteDb.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module SQLiteDb\n */\n\nimport * as fs from \"fs\";\nimport { dirname } from \"path\";\nimport * as semver from \"semver\";\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\nimport { DbResult, OpenMode } from \"@itwin/core-bentley\";\nimport { LocalFileName, SqliteError } from \"@itwin/core-common\";\nimport { CloudSqlite } from \"./CloudSqlite\";\nimport { IModelNative } from \"./internal/NativePlatform\";\nimport { IModelJsFs } from \"./IModelJsFs\";\nimport { SqliteStatement, StatementCache } from \"./SqliteStatement\";\nimport { _nativeDb } from \"./internal/Symbols\";\n\n// cspell:ignore savepoint julianday rowid\n\n/**\n * A \"generic\" SQLiteDb. This class may be used to access local files or databases in a cloud container.\n * @public\n */\nexport class SQLiteDb {\n /** @internal */\n public readonly [_nativeDb] = new IModelNative.platform.SQLiteDb();\n private _sqliteStatementCache = new StatementCache<SqliteStatement>();\n\n /** @internal */\n public static createBlobIO(): SQLiteDb.BlobIO {\n return new IModelNative.platform.BlobIO();\n }\n\n /** alias for closeDb.\n * @deprecated in 4.0 - might be removed in next major version. Use [[closeDb]]\n */\n public dispose(): void {\n this.closeDb();\n }\n\n /** Create a SQLiteDb\n * @param dbName The path to the SQLiteDb file to create.\n */\n public createDb(dbName: string): void;\n /** @beta */\n public createDb(dbName: string, container?: CloudSqlite.CloudContainer, params?: SQLiteDb.CreateParams): void;\n public createDb(dbName: string, container?: CloudSqlite.CloudContainer, params?: SQLiteDb.CreateParams): void {\n this[_nativeDb].createDb(dbName, container, params);\n }\n\n /** Open a SQLiteDb.\n * @param dbName The path to the SQLiteDb file to open\n */\n public openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams): void;\n /**\n * @param container optional CloudContainer holding database\n * @beta\n */\n public openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer): void;\n public openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer): void {\n this[_nativeDb].openDb(dbName, openMode, container);\n }\n\n /** Close SQLiteDb.\n * @param saveChanges if true, call `saveChanges` before closing db. Otherwise unsaved changes are abandoned.\n */\n public closeDb(saveChanges?: boolean): void {\n if (saveChanges && this.isOpen)\n this.saveChanges();\n this._sqliteStatementCache.clear();\n this[_nativeDb].closeDb();\n }\n\n /** Returns true if this SQLiteDb is open */\n public get isOpen(): boolean { return this[_nativeDb].isOpen(); }\n\n /** Returns true if this SQLiteDb is open readonly */\n public get isReadonly(): boolean { return this[_nativeDb].isReadonly(); }\n\n /** Create a new table in this database. */\n protected createTable(args: {\n /** The name of the table to create. */\n tableName: string;\n /** all of the columns in the table. */\n columns: string;\n /** any unique or foreign key constraints */\n constraints?: string;\n /** if true, add a \"lastMod\" timestamp column and triggers to automatically update it. */\n addTimestamp?: boolean;\n }) {\n const timestampCol = args.addTimestamp ? \",lastMod TIMESTAMP NOT NULL DEFAULT(julianday('now'))\" : \"\";\n const constraints = args.constraints ? `,${args.constraints}` : \"\";\n this.executeSQL(`CREATE TABLE ${args.tableName}(${args.columns}${timestampCol}${constraints})`);\n if (args.addTimestamp)\n this.executeSQL(`CREATE TRIGGER ${args.tableName}_timestamp AFTER UPDATE ON ${args.tableName} WHEN old.lastMod=new.lastMod AND old.lastMod != julianday('now') BEGIN UPDATE ${args.tableName} SET lastMod=julianday('now') WHERE rowid=new.rowid; END`);\n }\n\n /**\n * Get the last modified date for a row in a table of this database.\n * @note the table must have been created with `addTimestamp: true`\n */\n public readLastModTime(tableName: string, rowId: number): Date {\n return this.withSqliteStatement(`SELECT lastMod from ${tableName} WHERE rowid=?`, (stmt) => {\n stmt.bindInteger(1, rowId);\n return stmt.getValueDate(0);\n });\n }\n\n /**\n * Open a database, perform an operation, then close the database.\n *\n * Details:\n * - if database is open, throw an error\n * - open a database\n * - call a function with the database opened. If it is async, await its return.\n * - if function throws, abandon all changes, close database, and rethrow\n * - save all changes\n * - close the database\n * @return value from operation\n */\n public withOpenDb<T>(args: SQLiteDb.WithOpenDbArgs, operation: () => T): T {\n if (this.isOpen)\n SqliteError.throwError(\"already-open\", \"database is already open\", args.dbName);\n\n const save = () => this.closeDb(true), abandon = () => this.closeDb(false);\n this.openDb(args.dbName, args.openMode ?? OpenMode.Readonly, args.container);\n try {\n const result = operation();\n result instanceof Promise ? result.then(save, abandon) : save();\n return result;\n } catch (e) {\n abandon();\n throw e;\n }\n }\n\n /** The cloud container backing this SQLite database, if any.\n * @beta\n */\n public get cloudContainer(): CloudSqlite.CloudContainer | undefined {\n return this[_nativeDb].cloudContainer;\n }\n\n /** Returns the Id of the most-recently-inserted row in this database, per [sqlite3_last_insert_rowid](https://www.sqlite.org/c3ref/last_insert_rowid.html). */\n public getLastInsertRowId(): number {\n return this[_nativeDb].getLastInsertRowId();\n }\n\n /**\n * Perform an operation on a database in a CloudContainer with the write lock held.\n *\n * Details:\n * - acquire the write lock on a CloudContainer\n * - call `withOpenDb` with openMode `ReadWrite`\n * - upload changes\n * - release the write lock\n * @param args arguments to lock the container and open the database\n * @param operation an operation performed on the database with the write lock held.\n * @return value from operation\n * @internal\n */\n public async withLockedContainer<T>(args: CloudSqlite.LockAndOpenArgs, operation: () => Promise<T>) {\n return CloudSqlite.withWriteLock(args, async () => this.withOpenDb({ ...args, openMode: args.openMode ?? OpenMode.ReadWrite }, operation));\n }\n\n /** vacuum this database\n * @see https://www.sqlite.org/lang_vacuum.html\n */\n public vacuum(args?: SQLiteDb.VacuumDbArgs) {\n this[_nativeDb].vacuum(args);\n }\n\n /** Commit the outermost transaction, writing changes to the file. Then, restart the default transaction. */\n public saveChanges(): void {\n this[_nativeDb].saveChanges();\n }\n\n /** Abandon (cancel) the outermost transaction, discarding all changes since last save. Then, restart the default transaction. */\n public abandonChanges(): void {\n this[_nativeDb].abandonChanges();\n }\n\n /**\n * Use a prepared SQL statement, potentially from the statement cache. If the requested statement doesn't exist\n * in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved\n * in the statement cache so it can be reused in the future. Use this method for SQL statements that will be\n * reused often and are expensive to prepare. The statement cache holds the most recently used statements, discarding\n * the oldest statements as it fills. For statements you don't intend to reuse, instead use [[withSqliteStatement]].\n * @param sql The SQLite SQL statement to execute\n * @param callback the callback to invoke on the prepared statement\n * @returns the value returned by `callback`.\n */\n public withPreparedSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T): T {\n const stmt = this._sqliteStatementCache.findAndRemove(sql) ?? this.prepareSqliteStatement(sql);\n const release = () => this._sqliteStatementCache.addOrDispose(stmt);\n try {\n const val = callback(stmt);\n val instanceof Promise ? val.then(release, release) : release();\n return val;\n } catch (err) {\n release();\n throw err;\n }\n }\n\n /**\n * Prepare and execute a callback on a SQL statement. After the callback completes the statement is disposed.\n * Use this method for SQL statements are either not expected to be reused, or are not expensive to prepare.\n * For statements that will be reused often, instead use [[withPreparedSqliteStatement]].\n * @param sql The SQLite SQL statement to execute\n * @param callback the callback to invoke on the prepared statement\n * @returns the value returned by `callback`.\n */\n public withSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T): T {\n const stmt = this.prepareSqliteStatement(sql);\n const release = () => stmt[Symbol.dispose]();\n try {\n const val = callback(stmt);\n val instanceof Promise ? val.then(release, release) : release();\n return val;\n } catch (err) {\n release();\n throw err;\n }\n }\n\n /**\n * Perform an operation on this database within a [savepoint](https://www.sqlite.org/lang_savepoint.html). If the operation completes successfully, the\n * changes remain in the current transaction. If the operation throws an exception, the savepoint is rolled back\n * and all changes to the database from this method are reversed, leaving the transaction exactly as it was before this method.\n */\n public withSavePoint(savePointName: string, operation: () => void) {\n if (this.isReadonly)\n SqliteError.throwError(\"readonly\", \"database is readonly\", this[_nativeDb].getFilePath());\n\n this.executeSQL(`SAVEPOINT ${savePointName}`);\n try {\n operation();\n this.executeSQL(`RELEASE ${savePointName}`);\n } catch (e) {\n this.executeSQL(`ROLLBACK TO ${savePointName}`);\n throw e;\n }\n }\n\n /** Prepare an SQL statement.\n * @param sql The SQLite SQL statement to prepare\n * @param logErrors Determine if errors are logged or not\n * @internal\n */\n public prepareSqliteStatement(sql: string, logErrors = true): SqliteStatement {\n const stmt = new SqliteStatement(sql);\n stmt.prepare(this[_nativeDb], logErrors);\n return stmt;\n }\n\n /** execute an SQL statement */\n public executeSQL(sql: string): DbResult {\n using stmt = this.prepareSqliteStatement(sql);\n return stmt.step();\n }\n}\n\n/**\n * Abstract base class for a SQLite database that has [[SQLiteDb.RequiredVersionRanges]] stored in it.\n * This class provides version checking when the database is opened, to guarantee that a valid version of software is\n * always used for access.\n *\n * Notes:\n * - This class may be used either to access a local file, or one stored in a cloud container.\n * - Subclasses must provide a `myVersion` member indicating the version of its software, and implement the `createDDL` member to create its\n * tables.\n * @beta\n */\nexport abstract class VersionedSqliteDb extends SQLiteDb {\n protected static _versionProps = { namespace: \"SQLiteDb\", name: \"versions\" } as const;\n\n /** The current semver \"persistence version\" of this class.\n * @note This value should only be changed when logic in its code is modified in a way that affects the operation of extant copies.\n * If this value is outside of the range of accepted versions of a to-be-opened VersionedSqliteDb, the operation will fail. In this manner, if\n * changes are made to the format of a VersionedSqliteDb, or if bug fixes are necessary, the `requiredVersions` property in a VersionedSqliteDb may be updated\n * and immediately old versions of the package will refuse to open the VersionedSqliteDb, with a message to the user that they need to upgrade their\n * software. Likewise, if a new version of the package is asked to open an older VersionedSqliteDb that has not been upgraded to the lowest version\n * supported by it, the user will be informed that they need to upgrade their software.\n * @note this identifier is independent of versions in `package.json` files.\n */\n public abstract myVersion: string;\n\n /**\n * Change the \"versions required to open this database\" property stored in this database. After this call,\n * versions of software that don't meet the supplied ranges will fail.\n * @param versions the new versions required for reading and writing this database.\n * @note the database must be opened for write access.\n */\n public setRequiredVersions(versions: SQLiteDb.RequiredVersionRanges) {\n // NOTE: It might look tempting to just stringify the supplied `versions` object, but we only include required members - there may be others.\n this[_nativeDb].saveFileProperty(VersionedSqliteDb._versionProps, JSON.stringify({ readVersion: versions.readVersion, writeVersion: versions.writeVersion }));\n }\n\n /** Get the required version ranges necessary to open this VersionedSqliteDb. */\n public getRequiredVersions() {\n const checkIsString = (value: any) => {\n if (typeof value !== \"string\")\n SqliteError.throwError(\"invalid-versions-property\", `CloudDb has invalid \"versions\" property`, this[_nativeDb].getFilePath());\n return value;\n };\n const versionJson = checkIsString(this[_nativeDb].queryFileProperty(VersionedSqliteDb._versionProps, true));\n const versionRanges = JSON.parse(versionJson) as SQLiteDb.RequiredVersionRanges;\n checkIsString(versionRanges.readVersion);\n checkIsString(versionRanges.writeVersion);\n return versionRanges;\n }\n\n /**\n * Implement this method to create all tables for this subclass of `VersionedSqliteDb` when a new database file is created. Called from [[createNewDb]].\n */\n protected abstract createDDL(args: any): void;\n\n /**\n * Create a new database file for the subclass of VersionedSqliteDb.\n * @note The required versions are saved as [[myVersion]] or newer for both read and write.\n */\n public static createNewDb(fileName: LocalFileName, setupArgs?: any) {\n const db = new (this as any)() as VersionedSqliteDb; // \"as any\" necessary because VersionedSqliteDb is abstract\n IModelJsFs.recursiveMkDirSync(dirname(fileName));\n if (fs.existsSync(fileName))\n fs.unlinkSync(fileName);\n\n db.createDb(fileName);\n db.createDDL(setupArgs);\n const minVer = `^${db.myVersion}`;\n db.setRequiredVersions({ readVersion: minVer, writeVersion: minVer });\n db.closeDb(true);\n }\n\n /**\n * Verify that this version of the software meets the required version range (as appropriate, read or write) stored in the database.\n * Throws otherwise.\n */\n protected verifyVersions() {\n const versions = this.getRequiredVersions();\n const isReadonly = this.isReadonly; // so we can tell read/write after the file is closed.\n const range = isReadonly ? versions.readVersion : versions.writeVersion;\n if (semver.satisfies(this.myVersion, range))\n return;\n\n this.closeDb();\n const tooNew = semver.gtr(this.myVersion, range);\n SqliteError.throwError(\"incompatible-version\", `requires ${tooNew ? \"older\" : \"newer\"} version of ${this.constructor.name} for ${isReadonly ? \"read\" : \"write\"}`, this[_nativeDb].getFilePath());\n\n }\n\n /**\n * Open this database and verify that this version of the software meets the required version range (as appropriate, read or write) stored in the database.\n * Throws otherwise.\n * @see [[SqliteDb.openDb]] for argument types\n */\n public override openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer) {\n super.openDb(dbName, openMode, container);\n this.verifyVersions();\n }\n\n public async upgradeSchema(arg: { dbName: string, lockContainer?: { container: CloudSqlite.CloudContainer, user: string }, upgradeFn: () => void }) {\n // can't use \"this\" because it checks for version, which we don't want here\n return (arg.lockContainer) ?\n super.withLockedContainer({ dbName: arg.dbName, ...arg.lockContainer }, async () => arg.upgradeFn) :\n super.withOpenDb({ ...arg, openMode: OpenMode.ReadWrite }, arg.upgradeFn);\n }\n}\n\n/** @public */\nexport namespace SQLiteDb {\n /** A semver version range.\n * @see https://docs.npmjs.com/cli/v6/using-npm/semver\n */\n export type VersionRange = string;\n\n /**\n * A pair of semver [[SQLiteDb.VersionRange]]s, one for read and one for write, required to access a [[VersionedSqliteDb]].\n * If the version of the software attempting to read or write the database does not satisfy the range, access is denied.\n */\n export interface RequiredVersionRanges {\n /** a range of acceptable persistence versions for reading from a VersionedSqliteDb. */\n readonly readVersion: VersionRange;\n /** a range of acceptable persistence versions for writing to a VersionedSqliteDb. */\n readonly writeVersion: VersionRange;\n }\n\n /** interface for reading and writing to a blob in a SQLiteDb\n * @internal\n */\n export interface BlobIO {\n /** Close this BlobIO if it is opened.\n * @note this BlobIO *may* be reused after this call by calling `open` again.\n */\n close(): void;\n /** get the total number of bytes in the blob */\n getNumBytes(): number;\n /** @return true if this BlobIO was successfully opened and may be use to read or write the blob */\n isValid(): boolean;\n /** Open this BlobIO against a table/row/column in a Db */\n open(\n /** The database for the blob */\n db: IModelJsNative.AnyDb,\n args: {\n /** the name of the table for the blob*/\n tableName: string;\n /** the name of the column for the blob */\n columnName: string;\n /** The rowId of the blob */\n row: number;\n /** If true, open this BlobIO for write access */\n writeable?: boolean;\n }): void;\n /** Read from a blob\n * @returns the contents of the requested byte range\n */\n read(args: {\n /** The number of bytes to read */\n numBytes: number;\n /** starting offset within the blob to read */\n offset: number;\n /** If present and of sufficient size, use this ArrayBuffer for the value. */\n blob?: ArrayBuffer;\n }): Uint8Array;\n /** Reposition this BlobIO to a new rowId\n * @note this BlobIO must be valid when this methods is called.\n */\n changeRow(row: number): void;\n /** Write to a blob */\n write(args: {\n /** The number of bytes to write */\n numBytes: number;\n /** starting offset within the blob to write */\n offset: number;\n /** the value to write */\n blob: ArrayBuffer;\n }): void;\n }\n\n /** Default transaction mode for SQLiteDbs.\n * @see https://www.sqlite.org/lang_transaction.html\n */\n export enum DefaultTxnMode {\n /** no default transaction is started. You must use BEGIN/COMMIT or SQLite will use implicit transactions */\n None = 0,\n /** A deferred transaction is started when the file is first opened. This is the default. */\n Deferred = 1,\n /** An immediate transaction is started when the file is first opened. */\n Immediate = 2,\n /** An exclusive transaction is started when the file is first opened. */\n Exclusive = 3\n }\n\n /** parameters common to opening or creating a new SQLiteDb */\n export interface OpenOrCreateParams {\n /** If true, do not require that the `be_Prop` table exist */\n rawSQLite?: boolean;\n /** @see immutable option at https://www.sqlite.org/c3ref/open.html */\n immutable?: boolean;\n /** Do not attempt to verify that the file is a valid sQLite file before opening. */\n skipFileCheck?: boolean;\n /** the default transaction mode\n * @see [[SQLiteDb.DefaultTxnMode]]\n */\n defaultTxn?: 0 | 1 | 2 | 3;\n /** see query parameters from 'URI Filenames' in https://www.sqlite.org/c3ref/open.html */\n queryParam?: string;\n }\n\n /** Parameters for opening an existing SQLiteDb */\n export interface OpenParams extends OpenOrCreateParams {\n /** use OpenMode.ReadWrite to open the file with write access */\n openMode: OpenMode;\n }\n\n /** Size of a SQLiteDb page in bytes */\n export interface PageSize {\n /** see https://www.sqlite.org/pragma.html#pragma_page_size */\n pageSize?: number;\n }\n\n /** Parameters for creating a new SQLiteDb */\n export type CreateParams = OpenOrCreateParams & PageSize;\n\n /** Arguments for `SqliteDb.withOpenDb` */\n export interface WithOpenDbArgs {\n /** The name of the database to open */\n dbName: string;\n /** either an object with the open parameters or just OpenMode value. */\n openMode?: OpenMode | SQLiteDb.OpenParams;\n /** @internal */\n container?: CloudSqlite.CloudContainer;\n }\n\n /** Arguments for `SQLiteDb.vacuum` */\n export interface VacuumDbArgs extends PageSize {\n /** if present, name of new file to [vacuum into](https://www.sqlite.org/lang_vacuum.html) */\n into?: LocalFileName;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SQLiteDb.js","sourceRoot":"","sources":["../../src/SQLiteDb.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module SQLiteDb\n */\n\nimport * as fs from \"fs\";\nimport { dirname } from \"path\";\nimport * as semver from \"semver\";\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\nimport { DbResult, OpenMode } from \"@itwin/core-bentley\";\nimport { LocalFileName, SqliteError } from \"@itwin/core-common\";\nimport { CloudSqlite } from \"./CloudSqlite\";\nimport { IModelNative } from \"./internal/NativePlatform\";\nimport { IModelJsFs } from \"./IModelJsFs\";\nimport { SqliteStatement, StatementCache } from \"./SqliteStatement\";\nimport { _nativeDb } from \"./internal/Symbols\";\n\n// cspell:ignore savepoint julianday rowid\n\n/**\n * A \"generic\" SQLiteDb. This class may be used to access local files or databases in a cloud container.\n * @public\n */\nexport class SQLiteDb {\n /** @internal */\n public readonly [_nativeDb] = new IModelNative.platform.SQLiteDb();\n private _sqliteStatementCache = new StatementCache<SqliteStatement>();\n\n /** @internal */\n public static createBlobIO(): SQLiteDb.BlobIO {\n return new IModelNative.platform.BlobIO();\n }\n\n /** alias for closeDb.\n * @deprecated in 4.0 - might be removed in next major version. Use [[closeDb]]\n */\n public dispose(): void {\n this.closeDb();\n }\n\n /** Create a SQLiteDb\n * @param dbName The path to the SQLiteDb file to create.\n */\n public createDb(dbName: string): void;\n /** @beta */\n public createDb(dbName: string, container?: CloudSqlite.CloudContainer, params?: SQLiteDb.CreateParams): void;\n public createDb(dbName: string, container?: CloudSqlite.CloudContainer, params?: SQLiteDb.CreateParams): void {\n this[_nativeDb].createDb(dbName, container, params);\n }\n\n /** Open a SQLiteDb.\n * @param dbName The path to the SQLiteDb file to open\n */\n public openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams): void;\n /**\n * @param container optional CloudContainer holding database\n * @beta\n */\n public openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer): void;\n public openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer): void {\n this[_nativeDb].openDb(dbName, openMode, container);\n }\n\n /** Close SQLiteDb.\n * @param saveChanges if true, call `saveChanges` before closing db. Otherwise unsaved changes are abandoned.\n */\n public closeDb(saveChanges?: boolean): void {\n if (saveChanges && this.isOpen)\n this.saveChanges();\n this._sqliteStatementCache.clear();\n this[_nativeDb].closeDb();\n }\n\n /** Returns true if this SQLiteDb is open */\n public get isOpen(): boolean { return this[_nativeDb].isOpen(); }\n\n /** Returns true if this SQLiteDb is open readonly */\n public get isReadonly(): boolean { return this[_nativeDb].isReadonly(); }\n\n /** Create a new table in this database. */\n protected createTable(args: {\n /** The name of the table to create. */\n tableName: string;\n /** all of the columns in the table. */\n columns: string;\n /** any unique or foreign key constraints */\n constraints?: string;\n /** if true, add a \"lastMod\" timestamp column and triggers to automatically update it. */\n addTimestamp?: boolean;\n }) {\n const timestampCol = args.addTimestamp ? \",lastMod TIMESTAMP NOT NULL DEFAULT(julianday('now'))\" : \"\";\n const constraints = args.constraints ? `,${args.constraints}` : \"\";\n this.executeSQL(`CREATE TABLE ${args.tableName}(${args.columns}${timestampCol}${constraints})`);\n if (args.addTimestamp)\n this.executeSQL(`CREATE TRIGGER ${args.tableName}_timestamp AFTER UPDATE ON ${args.tableName} WHEN old.lastMod=new.lastMod AND old.lastMod != julianday('now') BEGIN UPDATE ${args.tableName} SET lastMod=julianday('now') WHERE rowid=new.rowid; END`);\n }\n\n /**\n * Get the last modified date for a row in a table of this database.\n * @note the table must have been created with `addTimestamp: true`\n */\n public readLastModTime(tableName: string, rowId: number): Date {\n return this.withSqliteStatement(`SELECT lastMod from ${tableName} WHERE rowid=?`, (stmt) => {\n stmt.bindInteger(1, rowId);\n return stmt.getValueDate(0);\n });\n }\n\n /**\n * Open a database, perform an operation, then close the database.\n *\n * Details:\n * - if database is open, throw an error\n * - open a database\n * - call a function with the database opened. If it is async, await its return.\n * - if function throws, abandon all changes, close database, and rethrow\n * - save all changes\n * - close the database\n * @return value from operation\n */\n public withOpenDb<T>(args: SQLiteDb.WithOpenDbArgs, operation: () => T): T {\n if (this.isOpen)\n SqliteError.throwError(\"already-open\", \"database is already open\", args.dbName);\n\n const save = () => this.closeDb(true), abandon = () => this.closeDb(false);\n this.openDb(args.dbName, args.openMode ?? OpenMode.Readonly, args.container);\n try {\n const result = operation();\n result instanceof Promise ? result.then(save, abandon) : save();\n return result;\n } catch (e) {\n abandon();\n throw e;\n }\n }\n\n /** The cloud container backing this SQLite database, if any.\n * @beta\n */\n public get cloudContainer(): CloudSqlite.CloudContainer | undefined {\n return this[_nativeDb].cloudContainer;\n }\n\n /** Returns the Id of the most-recently-inserted row in this database, per [sqlite3_last_insert_rowid](https://www.sqlite.org/c3ref/last_insert_rowid.html). */\n public getLastInsertRowId(): number {\n return this[_nativeDb].getLastInsertRowId();\n }\n\n /**\n * Perform an operation on a database in a CloudContainer with the write lock held.\n *\n * Details:\n * - acquire the write lock on a CloudContainer\n * - call `withOpenDb` with openMode `ReadWrite`\n * - upload changes\n * - release the write lock\n * @param args arguments to lock the container and open the database\n * @param operation an operation performed on the database with the write lock held.\n * @return value from operation\n * @internal\n */\n public async withLockedContainer<T>(args: CloudSqlite.LockAndOpenArgs, operation: () => Promise<T>) {\n return CloudSqlite.withWriteLock(args, async () => this.withOpenDb({ ...args, openMode: args.openMode ?? OpenMode.ReadWrite }, operation));\n }\n\n /** vacuum this database\n * @see https://www.sqlite.org/lang_vacuum.html\n */\n public vacuum(args?: SQLiteDb.VacuumDbArgs) {\n this[_nativeDb].vacuum(args);\n }\n\n /** Commit the outermost transaction, writing changes to the file. Then, restart the default transaction. */\n public saveChanges(): void {\n this[_nativeDb].saveChanges();\n }\n\n /** Abandon (cancel) the outermost transaction, discarding all changes since last save. Then, restart the default transaction. */\n public abandonChanges(): void {\n this[_nativeDb].abandonChanges();\n }\n\n /**\n * Apply a changeset file - in the same on-disk format used for iModel changesets - to this SQLiteDb.\n * Unlike `BriefcaseDb.pullChanges`, this does *not* validate the changeset header (e.g. parentId/changesetId)\n * against the current state of the database - it simply applies the changes it contains. If applying the\n * changeset encounters any conflict, or otherwise fails, this method throws (conflicts are never resolved\n * automatically).\n * @note this method only throws on failure - it does *not* commit or abandon any changes itself. If it\n * throws, some (but not necessarily all) of the changeset's changes may have already been applied to the\n * current transaction. It is the caller's responsibility to call [[saveChanges]] or [[abandonChanges]]\n * as appropriate after catching an error from this method.\n * @param changesetFile the local file name of the changeset to apply.\n * @internal\n */\n public applyChangeset(changesetFile: LocalFileName): void {\n this[_nativeDb].applyChangeset(changesetFile);\n }\n\n /**\n * Begin capturing DDL and data changes made to this SQLiteDb, so they may later be saved via [[createChangeset]].\n * Intended only to produce changeset files for testing [[applyChangeset]] - not for any other purpose.\n * @internal\n */\n public startChangeTracking(): void {\n this[_nativeDb].startChangeTracking();\n }\n\n /**\n * Execute a DDL statement (e.g. `CREATE TABLE`) so that, if change tracking is active (see [[startChangeTracking]]),\n * the DDL is captured for inclusion in the changeset produced by [[createChangeset]]. DDL executed via [[executeSQL]]\n * is *not* captured for change tracking purposes.\n * @internal\n */\n public executeDdl(ddl: string): void {\n this[_nativeDb].executeDdl(ddl);\n }\n\n /**\n * Write out the changes captured since [[startChangeTracking]] was called to a changeset file, in the same\n * on-disk format used for iModel changesets.\n * @param changesetFile the local file name to write the changeset to.\n * @internal\n */\n public createChangeset(changesetFile: LocalFileName): void {\n this[_nativeDb].createChangeset(changesetFile);\n }\n\n /**\n * Use a prepared SQL statement, potentially from the statement cache. If the requested statement doesn't exist\n * in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved\n * in the statement cache so it can be reused in the future. Use this method for SQL statements that will be\n * reused often and are expensive to prepare. The statement cache holds the most recently used statements, discarding\n * the oldest statements as it fills. For statements you don't intend to reuse, instead use [[withSqliteStatement]].\n * @param sql The SQLite SQL statement to execute\n * @param callback the callback to invoke on the prepared statement\n * @returns the value returned by `callback`.\n */\n public withPreparedSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T): T {\n const stmt = this._sqliteStatementCache.findAndRemove(sql) ?? this.prepareSqliteStatement(sql);\n const release = () => this._sqliteStatementCache.addOrDispose(stmt);\n try {\n const val = callback(stmt);\n val instanceof Promise ? val.then(release, release) : release();\n return val;\n } catch (err) {\n release();\n throw err;\n }\n }\n\n /**\n * Prepare and execute a callback on a SQL statement. After the callback completes the statement is disposed.\n * Use this method for SQL statements are either not expected to be reused, or are not expensive to prepare.\n * For statements that will be reused often, instead use [[withPreparedSqliteStatement]].\n * @param sql The SQLite SQL statement to execute\n * @param callback the callback to invoke on the prepared statement\n * @returns the value returned by `callback`.\n */\n public withSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T): T {\n const stmt = this.prepareSqliteStatement(sql);\n const release = () => stmt[Symbol.dispose]();\n try {\n const val = callback(stmt);\n val instanceof Promise ? val.then(release, release) : release();\n return val;\n } catch (err) {\n release();\n throw err;\n }\n }\n\n /**\n * Perform an operation on this database within a [savepoint](https://www.sqlite.org/lang_savepoint.html). If the operation completes successfully, the\n * changes remain in the current transaction. If the operation throws an exception, the savepoint is rolled back\n * and all changes to the database from this method are reversed, leaving the transaction exactly as it was before this method.\n */\n public withSavePoint(savePointName: string, operation: () => void) {\n if (this.isReadonly)\n SqliteError.throwError(\"readonly\", \"database is readonly\", this[_nativeDb].getFilePath());\n\n this.executeSQL(`SAVEPOINT ${savePointName}`);\n try {\n operation();\n this.executeSQL(`RELEASE ${savePointName}`);\n } catch (e) {\n this.executeSQL(`ROLLBACK TO ${savePointName}`);\n throw e;\n }\n }\n\n /** Prepare an SQL statement.\n * @param sql The SQLite SQL statement to prepare\n * @param logErrors Determine if errors are logged or not\n * @internal\n */\n public prepareSqliteStatement(sql: string, logErrors = true): SqliteStatement {\n const stmt = new SqliteStatement(sql);\n stmt.prepare(this[_nativeDb], logErrors);\n return stmt;\n }\n\n /** execute an SQL statement */\n public executeSQL(sql: string): DbResult {\n using stmt = this.prepareSqliteStatement(sql);\n return stmt.step();\n }\n}\n\n/**\n * Abstract base class for a SQLite database that has [[SQLiteDb.RequiredVersionRanges]] stored in it.\n * This class provides version checking when the database is opened, to guarantee that a valid version of software is\n * always used for access.\n *\n * Notes:\n * - This class may be used either to access a local file, or one stored in a cloud container.\n * - Subclasses must provide a `myVersion` member indicating the version of its software, and implement the `createDDL` member to create its\n * tables.\n * @beta\n */\nexport abstract class VersionedSqliteDb extends SQLiteDb {\n protected static _versionProps = { namespace: \"SQLiteDb\", name: \"versions\" } as const;\n\n /** The current semver \"persistence version\" of this class.\n * @note This value should only be changed when logic in its code is modified in a way that affects the operation of extant copies.\n * If this value is outside of the range of accepted versions of a to-be-opened VersionedSqliteDb, the operation will fail. In this manner, if\n * changes are made to the format of a VersionedSqliteDb, or if bug fixes are necessary, the `requiredVersions` property in a VersionedSqliteDb may be updated\n * and immediately old versions of the package will refuse to open the VersionedSqliteDb, with a message to the user that they need to upgrade their\n * software. Likewise, if a new version of the package is asked to open an older VersionedSqliteDb that has not been upgraded to the lowest version\n * supported by it, the user will be informed that they need to upgrade their software.\n * @note this identifier is independent of versions in `package.json` files.\n */\n public abstract myVersion: string;\n\n /**\n * Change the \"versions required to open this database\" property stored in this database. After this call,\n * versions of software that don't meet the supplied ranges will fail.\n * @param versions the new versions required for reading and writing this database.\n * @note the database must be opened for write access.\n */\n public setRequiredVersions(versions: SQLiteDb.RequiredVersionRanges) {\n // NOTE: It might look tempting to just stringify the supplied `versions` object, but we only include required members - there may be others.\n this[_nativeDb].saveFileProperty(VersionedSqliteDb._versionProps, JSON.stringify({ readVersion: versions.readVersion, writeVersion: versions.writeVersion }));\n }\n\n /** Get the required version ranges necessary to open this VersionedSqliteDb. */\n public getRequiredVersions() {\n const checkIsString = (value: any) => {\n if (typeof value !== \"string\")\n SqliteError.throwError(\"invalid-versions-property\", `CloudDb has invalid \"versions\" property`, this[_nativeDb].getFilePath());\n return value;\n };\n const versionJson = checkIsString(this[_nativeDb].queryFileProperty(VersionedSqliteDb._versionProps, true));\n const versionRanges = JSON.parse(versionJson) as SQLiteDb.RequiredVersionRanges;\n checkIsString(versionRanges.readVersion);\n checkIsString(versionRanges.writeVersion);\n return versionRanges;\n }\n\n /**\n * Implement this method to create all tables for this subclass of `VersionedSqliteDb` when a new database file is created. Called from [[createNewDb]].\n */\n protected abstract createDDL(args: any): void;\n\n /**\n * Create a new database file for the subclass of VersionedSqliteDb.\n * @note The required versions are saved as [[myVersion]] or newer for both read and write.\n */\n public static createNewDb(fileName: LocalFileName, setupArgs?: any) {\n const db = new (this as any)() as VersionedSqliteDb; // \"as any\" necessary because VersionedSqliteDb is abstract\n IModelJsFs.recursiveMkDirSync(dirname(fileName));\n if (fs.existsSync(fileName))\n fs.unlinkSync(fileName);\n\n db.createDb(fileName);\n db.createDDL(setupArgs);\n const minVer = `^${db.myVersion}`;\n db.setRequiredVersions({ readVersion: minVer, writeVersion: minVer });\n db.closeDb(true);\n }\n\n /**\n * Verify that this version of the software meets the required version range (as appropriate, read or write) stored in the database.\n * Throws otherwise.\n */\n protected verifyVersions() {\n const versions = this.getRequiredVersions();\n const isReadonly = this.isReadonly; // so we can tell read/write after the file is closed.\n const range = isReadonly ? versions.readVersion : versions.writeVersion;\n if (semver.satisfies(this.myVersion, range))\n return;\n\n this.closeDb();\n const tooNew = semver.gtr(this.myVersion, range);\n SqliteError.throwError(\"incompatible-version\", `requires ${tooNew ? \"older\" : \"newer\"} version of ${this.constructor.name} for ${isReadonly ? \"read\" : \"write\"}`, this[_nativeDb].getFilePath());\n\n }\n\n /**\n * Open this database and verify that this version of the software meets the required version range (as appropriate, read or write) stored in the database.\n * Throws otherwise.\n * @see [[SqliteDb.openDb]] for argument types\n */\n public override openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer) {\n super.openDb(dbName, openMode, container);\n this.verifyVersions();\n }\n\n public async upgradeSchema(arg: { dbName: string, lockContainer?: { container: CloudSqlite.CloudContainer, user: string }, upgradeFn: () => void }) {\n // can't use \"this\" because it checks for version, which we don't want here\n return (arg.lockContainer) ?\n super.withLockedContainer({ dbName: arg.dbName, ...arg.lockContainer }, async () => arg.upgradeFn) :\n super.withOpenDb({ ...arg, openMode: OpenMode.ReadWrite }, arg.upgradeFn);\n }\n}\n\n/** @public */\nexport namespace SQLiteDb {\n /** A semver version range.\n * @see https://docs.npmjs.com/cli/v6/using-npm/semver\n */\n export type VersionRange = string;\n\n /**\n * A pair of semver [[SQLiteDb.VersionRange]]s, one for read and one for write, required to access a [[VersionedSqliteDb]].\n * If the version of the software attempting to read or write the database does not satisfy the range, access is denied.\n */\n export interface RequiredVersionRanges {\n /** a range of acceptable persistence versions for reading from a VersionedSqliteDb. */\n readonly readVersion: VersionRange;\n /** a range of acceptable persistence versions for writing to a VersionedSqliteDb. */\n readonly writeVersion: VersionRange;\n }\n\n /** interface for reading and writing to a blob in a SQLiteDb\n * @internal\n */\n export interface BlobIO {\n /** Close this BlobIO if it is opened.\n * @note this BlobIO *may* be reused after this call by calling `open` again.\n */\n close(): void;\n /** get the total number of bytes in the blob */\n getNumBytes(): number;\n /** @return true if this BlobIO was successfully opened and may be use to read or write the blob */\n isValid(): boolean;\n /** Open this BlobIO against a table/row/column in a Db */\n open(\n /** The database for the blob */\n db: IModelJsNative.AnyDb,\n args: {\n /** the name of the table for the blob*/\n tableName: string;\n /** the name of the column for the blob */\n columnName: string;\n /** The rowId of the blob */\n row: number;\n /** If true, open this BlobIO for write access */\n writeable?: boolean;\n }): void;\n /** Read from a blob\n * @returns the contents of the requested byte range\n */\n read(args: {\n /** The number of bytes to read */\n numBytes: number;\n /** starting offset within the blob to read */\n offset: number;\n /** If present and of sufficient size, use this ArrayBuffer for the value. */\n blob?: ArrayBuffer;\n }): Uint8Array;\n /** Reposition this BlobIO to a new rowId\n * @note this BlobIO must be valid when this methods is called.\n */\n changeRow(row: number): void;\n /** Write to a blob */\n write(args: {\n /** The number of bytes to write */\n numBytes: number;\n /** starting offset within the blob to write */\n offset: number;\n /** the value to write */\n blob: ArrayBuffer;\n }): void;\n }\n\n /** Default transaction mode for SQLiteDbs.\n * @see https://www.sqlite.org/lang_transaction.html\n */\n export enum DefaultTxnMode {\n /** no default transaction is started. You must use BEGIN/COMMIT or SQLite will use implicit transactions */\n None = 0,\n /** A deferred transaction is started when the file is first opened. This is the default. */\n Deferred = 1,\n /** An immediate transaction is started when the file is first opened. */\n Immediate = 2,\n /** An exclusive transaction is started when the file is first opened. */\n Exclusive = 3\n }\n\n /** parameters common to opening or creating a new SQLiteDb */\n export interface OpenOrCreateParams {\n /** If true, do not require that the `be_Prop` table exist */\n rawSQLite?: boolean;\n /** @see immutable option at https://www.sqlite.org/c3ref/open.html */\n immutable?: boolean;\n /** Do not attempt to verify that the file is a valid sQLite file before opening. */\n skipFileCheck?: boolean;\n /** the default transaction mode\n * @see [[SQLiteDb.DefaultTxnMode]]\n */\n defaultTxn?: 0 | 1 | 2 | 3;\n /** see query parameters from 'URI Filenames' in https://www.sqlite.org/c3ref/open.html */\n queryParam?: string;\n }\n\n /** Parameters for opening an existing SQLiteDb */\n export interface OpenParams extends OpenOrCreateParams {\n /** use OpenMode.ReadWrite to open the file with write access */\n openMode: OpenMode;\n }\n\n /** Size of a SQLiteDb page in bytes */\n export interface PageSize {\n /** see https://www.sqlite.org/pragma.html#pragma_page_size */\n pageSize?: number;\n }\n\n /** Parameters for creating a new SQLiteDb */\n export type CreateParams = OpenOrCreateParams & PageSize;\n\n /** Arguments for `SqliteDb.withOpenDb` */\n export interface WithOpenDbArgs {\n /** The name of the database to open */\n dbName: string;\n /** either an object with the open parameters or just OpenMode value. */\n openMode?: OpenMode | SQLiteDb.OpenParams;\n /** @internal */\n container?: CloudSqlite.CloudContainer;\n }\n\n /** Arguments for `SQLiteDb.vacuum` */\n export interface VacuumDbArgs extends PageSize {\n /** if present, name of new file to [vacuum into](https://www.sqlite.org/lang_vacuum.html) */\n into?: LocalFileName;\n }\n}\n"]}
|
|
@@ -37,7 +37,7 @@ async function assertThrowsAsync(test, msg) {
|
|
|
37
37
|
}
|
|
38
38
|
throw new Error(`Failed to throw error with message: "${msg}"`);
|
|
39
39
|
}
|
|
40
|
-
describe
|
|
40
|
+
describe("Merge conflict & locking", () => {
|
|
41
41
|
let iTwinId;
|
|
42
42
|
before(() => {
|
|
43
43
|
HubMock.startup("MergeConflictTest", KnownTestLocations.outputDir);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MergeConflict.test.js","sourceRoot":"","sources":["../../../../src/test/standalone/MergeConflict.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\nimport { GuidString, Id64String } from \"@itwin/core-bentley\";\nimport { EditTxn, withEditTxn } from \"../../EditTxn\";\nimport {\n ElementAspectProps,\n IModel,\n SubCategoryAppearance,\n} from \"@itwin/core-common\";\nimport * as chai from \"chai\";\nimport { assert, expect } from \"chai\";\nimport * as chaiAsPromised from \"chai-as-promised\";\nimport { HubWrappers, KnownTestLocations } from \"../\";\nimport { HubMock } from \"../../internal/HubMock\";\nimport {\n BriefcaseDb,\n ChannelControl,\n DictionaryModel,\n ExternalSourceAspect,\n SpatialCategory,\n SqliteChangeOp,\n} from \"../../core-backend\";\nimport { IModelTestUtils, TestUserType } from \"../IModelTestUtils\";\nimport { RebaseChangesetConflictArgs, SqliteConflictCause } from \"../../internal/ChangesetConflictArgs\";\nchai.use(chaiAsPromised);\nimport * as sinon from \"sinon\";\n\nexport async function createNewModelAndCategory(txn: EditTxn, parent?: Id64String) {\n const rwIModel = txn.iModel as BriefcaseDb;\n // Create a new physical model.\n const [, modelId] = await IModelTestUtils.createAndInsertPhysicalPartitionAndModelAsync(txn, IModelTestUtils.getUniqueModelCode(rwIModel, \"newPhysicalModel\"), true, parent);\n\n // Find or create a SpatialCategory.\n const dictionary: DictionaryModel = rwIModel.models.getModel<DictionaryModel>(IModel.dictionaryId);\n const newCategoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, \"ThisTestSpatialCategory\");\n const category = SpatialCategory.create(rwIModel, IModel.dictionaryId, newCategoryCode.value);\n const spatialCategoryId = txn.insertElement(category.toJSON());\n category.setDefaultAppearance(txn, new SubCategoryAppearance({ color: 0xff0000 }));\n\n return { modelId, spatialCategoryId };\n}\n\nasync function assertThrowsAsync<T>(test: () => Promise<T>, msg?: string) {\n try {\n await test();\n } catch (e) {\n if (e instanceof Error && msg) {\n assert.equal(e.message, msg);\n }\n return;\n }\n throw new Error(`Failed to throw error with message: \"${msg}\"`);\n}\n\ndescribe.skip(\"Merge conflict & locking\", () => { // ###TODO FLAKY https://github.com/iTwin/itwinjs-core/issues/7730\n let iTwinId: GuidString;\n\n before(() => {\n HubMock.startup(\"MergeConflictTest\", KnownTestLocations.outputDir);\n iTwinId = HubMock.iTwinId;\n });\n after(() => HubMock.shutdown());\n\n it(\"pull/merge causing update conflict - dirty read/modify (with no lock)\", async () => {\n /**\n * To simulate a a data conflict for dirty read we update same aspect from two different briefcases\n * and when the second briefcase try to push its changes it will fail with following error.\n * \"UPDATE/DELETE before value do not match with one in db or CASCADE action was triggered.\"\n */\n const accessToken1 = await HubWrappers.getAccessToken(TestUserType.SuperManager);\n const accessToken2 = await HubWrappers.getAccessToken(TestUserType.Regular);\n const accessToken3 = await HubWrappers.getAccessToken(TestUserType.Super);\n\n // Delete any existing iModels with the same name as the read-write test iModel\n const iModelName = \"TestIModel\";\n\n // Create a new empty iModel on the Hub & obtain a briefcase\n const rwIModelId = await HubMock.createNewIModel({ accessToken: accessToken1, iTwinId, iModelName, description: \"TestSubject\", noLocks: undefined });\n assert.isNotEmpty(rwIModelId);\n\n // to reproduce the issue we will disable locks altogether.\n const b1 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken1, iTwinId, iModelId: rwIModelId, noLock: true });\n b1.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b2 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken2, iTwinId, iModelId: rwIModelId, noLock: true });\n b2.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b3 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken3, iTwinId, iModelId: rwIModelId, noLock: true });\n const b1Txn = new EditTxn(b1, \"merge conflict\");\n b1Txn.start();\n const b2Txn = new EditTxn(b2, \"merge conflict\");\n b2Txn.start();\n\n // create and insert a new model with code1\n const [, modelId] = IModelTestUtils.createAndInsertPhysicalPartitionAndModel(\n b1Txn,\n IModelTestUtils.getUniqueModelCode(b1, \"newPhysicalModel\"),\n true);\n\n const dictionary: DictionaryModel = b1.models.getModel<DictionaryModel>(IModel.dictionaryId);\n const newCategoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, \"ThisTestSpatialCategory\");\n\n const spatialCategoryId = SpatialCategory.insert(\n b1Txn,\n dictionary.id,\n newCategoryCode.value,\n new SubCategoryAppearance({ color: 0xff0000 }),\n );\n\n // insert element and aspect\n const el1 = b1Txn.insertElement(IModelTestUtils.createPhysicalObject(b1, modelId, spatialCategoryId).toJSON());\n await b1.pullChanges();\n const aspectId1 = b1Txn.insertAspect({\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier\",\n } as ElementAspectProps);\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `inserted element with aspect ${el1}` });\n\n // b1 same as b2 and now both will modify same aspect\n await b2.pullChanges();\n\n // b1 will change identifier from \"test identifier\" to \"test identifier (modified by b1)\"\n b1Txn.updateAspect({\n id: aspectId1,\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier (modified by b1)\",\n } as ElementAspectProps);\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `modify aspect ${aspectId1} with no lock` });\n\n // b2 will change identifier from \"test identifier\" to \"test identifier (modified by b2)\"\n b2Txn.updateAspect({\n id: aspectId1,\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier (modified by b2)\",\n } as ElementAspectProps);\n b2Txn.saveChanges();\n\n const conflicts: {\n cause: SqliteConflictCause,\n tableName: string,\n opcode?: SqliteChangeOp,\n id: Id64String,\n }[] = [];\n\n // we will not handle conflict and let the default conflict handler deal with it.\n b2.txns.rebaser.addConflictHandler({\n id: \"custom\", handler: (arg: RebaseChangesetConflictArgs) => {\n conflicts.push({\n cause: arg.cause,\n tableName: arg.tableName,\n opcode: arg.opcode,\n id: arg.getValueId(0, arg.opcode === \"Inserted\" ? \"New\" : \"Old\") as Id64String,\n });\n return undefined;\n }\n });\n\n await b2.pushChanges({ accessToken: accessToken1, description: `modify aspect ${aspectId1} with no lock` });\n\n expect(conflicts.length).to.be.equals(3);\n\n chai.expect(\n [\n {\n \"cause\": \"Data\",\n \"tableName\": \"bis_Element\",\n \"opcode\": \"Updated\",\n \"id\": \"0x20000000004\"\n },\n {\n \"cause\": \"Data\",\n \"tableName\": \"bis_ElementMultiAspect\",\n \"opcode\": \"Updated\",\n \"id\": \"0x20000000001\"\n },\n {\n \"cause\": \"Data\",\n \"tableName\": \"bis_Model\",\n \"opcode\": \"Updated\",\n \"id\": \"0x20000000001\"\n }\n ]).to.be.deep.equals(conflicts);\n\n await b3.pullChanges();\n await b1.pullChanges();\n\n // b2 win as default conflict handler choose Replace to override local changes over master.\n (b2.elements.getAspect(aspectId1) as ExternalSourceAspect).identifier = \"test identifier (modified by b2)\";\n (b3.elements.getAspect(aspectId1) as ExternalSourceAspect).identifier = \"test identifier (modified by b2)\";\n (b1.elements.getAspect(aspectId1) as ExternalSourceAspect).identifier = \"test identifier (modified by b2)\";\n\n b1.close();\n b2.close();\n b3.close();\n });\n it(\"pull/merge causing update conflict - update causing local changes (with no lock)\", async () => {\n /**\n * To simulate a a data conflict for dirty read we update same aspect from two different briefcases\n * and when the second briefcase try to push its changes it will fail with following error.\n * \"UPDATE/DELETE before value do not match with one in db or CASCADE action was triggered.\"\n */\n const accessToken1 = await HubWrappers.getAccessToken(TestUserType.SuperManager);\n const accessToken2 = await HubWrappers.getAccessToken(TestUserType.Regular);\n const accessToken3 = await HubWrappers.getAccessToken(TestUserType.Super);\n\n // Delete any existing iModels with the same name as the read-write test iModel\n const iModelName = \"TestIModel\";\n\n // Create a new empty iModel on the Hub & obtain a briefcase\n const rwIModelId = await HubMock.createNewIModel({ accessToken: accessToken1, iTwinId, iModelName, description: \"TestSubject\", noLocks: undefined });\n assert.isNotEmpty(rwIModelId);\n\n // to reproduce the issue we will disable locks altogether.\n const b1 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken1, iTwinId, iModelId: rwIModelId, noLock: true });\n b1.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b2 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken2, iTwinId, iModelId: rwIModelId, noLock: true });\n b2.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b3 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken3, iTwinId, iModelId: rwIModelId, noLock: true });\n const b1Txn = new EditTxn(b1, \"merge conflict\");\n b1Txn.start();\n const b2Txn = new EditTxn(b2, \"merge conflict\");\n b2Txn.start();\n\n // create and insert a new model with code1\n const [, modelId] = IModelTestUtils.createAndInsertPhysicalPartitionAndModel(\n b1Txn,\n IModelTestUtils.getUniqueModelCode(b1, \"newPhysicalModel\"),\n true);\n\n const dictionary: DictionaryModel = b1.models.getModel<DictionaryModel>(IModel.dictionaryId);\n const newCategoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, \"ThisTestSpatialCategory\");\n\n const spatialCategoryId = SpatialCategory.insert(\n b1Txn,\n dictionary.id,\n newCategoryCode.value,\n new SubCategoryAppearance({ color: 0xff0000 }),\n );\n\n // insert element and aspect\n const el1 = b1Txn.insertElement(IModelTestUtils.createPhysicalObject(b1, modelId, spatialCategoryId).toJSON());\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `inserted element with aspect ${el1}` });\n\n await b2.pullChanges();\n const aspectId1 = b2Txn.insertAspect({\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier\",\n } as ElementAspectProps);\n b2Txn.saveChanges();\n\n b1Txn.deleteElement(el1);\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `deleted element ${el1}` });\n\n const conflicts: {\n cause: SqliteConflictCause,\n tableName: string,\n opcode?: SqliteChangeOp,\n id: Id64String | undefined,\n }[] = [];\n\n // we will not handle conflict and let the default conflict handler deal with it.\n b2.txns.rebaser.addConflictHandler({\n id: \"custom\", handler: (arg: RebaseChangesetConflictArgs) => {\n let id;\n if (arg.cause !== \"ForeignKey\") {\n id = arg.getValueId(0, arg.opcode === \"Inserted\" ? \"New\" : \"Old\") as Id64String;\n }\n conflicts.push({\n cause: arg.cause,\n tableName: arg.tableName,\n opcode: arg.opcode,\n id,\n });\n return undefined;\n }\n });\n\n\n await assertThrowsAsync(\n async () => b2.pushChanges({ accessToken: accessToken1, description: `inserted element with aspect ${el1}` }),\n \"Foreign key conflicts in ChangeSet. Aborting rebase.\");\n\n expect(conflicts.length).to.be.equals(3);\n expect(conflicts).to.deep.equal([\n {\n cause: \"NotFound\",\n tableName: \"bis_Element\",\n opcode: \"Updated\",\n id: \"0x20000000004\"\n },\n {\n cause: \"Data\",\n tableName: \"bis_Model\",\n opcode: \"Updated\",\n id: \"0x20000000001\"\n },\n {\n cause: \"ForeignKey\",\n tableName: \"\",\n opcode: undefined,\n id: undefined\n }\n ]);\n\n b2.txns.rebaser.addConflictHandler({\n id: \"delete_aspect_when_element_is_deleted\", handler: (arg: RebaseChangesetConflictArgs) => {\n if (arg.cause === \"NotFound\" && arg.tableName === \"bis_Element\") {\n // if element does not exist any more let delete the aspects as well.\n const elId = arg.getValueId(0, arg.opcode === \"Inserted\" ? \"New\" : \"Old\") as Id64String;\n withEditTxn(b2, (txn) => {\n b2.elements.getAspects(elId).forEach((aspect) => {\n txn.deleteAspect(aspect.id);\n });\n });\n }\n return undefined;\n }\n });\n\n b2Txn.saveChanges();\n conflicts.length = 0;\n\n await b2.pushChanges({ accessToken: accessToken1, description: `nothing is pushed as the only change we made is reverted` });\n await b3.pullChanges();\n await b1.pullChanges();\n\n expect(() => b1.elements.getElement(el1)).throws(`Element=${el1}`);\n expect(() => b2.elements.getElement(el1)).throws(`Element=${el1}`);\n expect(() => b3.elements.getElement(el1)).throws(`Element=${el1}`);\n\n expect(() => b1.elements.getAspect(aspectId1)).throws(`ElementAspect not found ${aspectId1}`);\n expect(() => b2.elements.getAspect(aspectId1)).throws(`ElementAspect not found ${aspectId1}`);\n expect(() => b3.elements.getAspect(aspectId1)).throws(`ElementAspect not found ${aspectId1}`);\n\n b1.close();\n b2.close();\n b3.close();\n });\n\n it(\"aspect insert, update & delete requires exclusive lock\", async () => {\n const accessToken1 = await HubWrappers.getAccessToken(TestUserType.SuperManager);\n const accessToken2 = await HubWrappers.getAccessToken(TestUserType.Regular);\n const accessToken3 = await HubWrappers.getAccessToken(TestUserType.Super);\n\n // Delete any existing iModels with the same name as the read-write test iModel\n const iModelName = \"TestIModel\";\n\n // Create a new empty iModel on the Hub & obtain a briefcase\n const rwIModelId = await HubMock.createNewIModel({ accessToken: accessToken1, iTwinId, iModelName, description: \"TestSubject\", noLocks: undefined });\n assert.isNotEmpty(rwIModelId);\n\n const b1 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken1, iTwinId, iModelId: rwIModelId });\n b1.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b2 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken2, iTwinId, iModelId: rwIModelId });\n b2.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b3 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken3, iTwinId, iModelId: rwIModelId });\n const b1Txn = new EditTxn(b1, \"merge conflict\");\n b1Txn.start();\n const b2Txn = new EditTxn(b2, \"merge conflict\");\n b2Txn.start();\n\n await b1.locks.acquireLocks({ shared: IModel.repositoryModelId });\n await b2.locks.acquireLocks({ shared: IModel.repositoryModelId });\n\n // create and insert a new model with code1\n const [, modelId] = IModelTestUtils.createAndInsertPhysicalPartitionAndModel(\n b1Txn,\n IModelTestUtils.getUniqueModelCode(b1, \"newPhysicalModel\"),\n true);\n\n const dictionary: DictionaryModel = b1.models.getModel<DictionaryModel>(IModel.dictionaryId);\n const newCategoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, \"ThisTestSpatialCategory\");\n\n await b1.locks.acquireLocks({ shared: dictionary.id });\n const spatialCategoryId = SpatialCategory.insert(\n b1Txn,\n dictionary.id,\n newCategoryCode.value,\n new SubCategoryAppearance({ color: 0xff0000 }),\n );\n const el1 = b1Txn.insertElement(IModelTestUtils.createPhysicalObject(b1, modelId, spatialCategoryId).toJSON());\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `inserted element ${el1}` });\n\n await b2.pullChanges();\n let aspectId: Id64String;\n const insertAspectIntoB2 = () => {\n aspectId = b2Txn.insertAspect({\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier\",\n } as ElementAspectProps);\n };\n\n /* attempt to insert aspect without a lock */\n assert.throws(insertAspectIntoB2, \"Error inserting ElementAspect [exclusive lock not held on element for insert aspect (id=0x20000000004)], class: BisCore:ExternalSourceAspect\");\n\n /* acquire lock and try again */\n await b2.locks.acquireLocks({ exclusive: el1 });\n insertAspectIntoB2();\n\n /* b1 cannot acquire lock on el1 as its already taken by b2 */\n await expect(b1.locks.acquireLocks({ exclusive: el1 })).to.be.rejectedWith(\"exclusive lock is already held\");\n\n /* push changes on b2 to release lock on el1 */\n b2Txn.saveChanges();\n await b2.pushChanges({ accessToken: accessToken2, description: `add aspect to element ${el1}` });\n\n await b1.pullChanges();\n\n const updateAspectIntoB1 = () => {\n b1Txn.updateAspect({\n id: aspectId,\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier (modified)\",\n } as ElementAspectProps);\n };\n\n /* attempt to update aspect without a lock */\n assert.throws(updateAspectIntoB1, \"Error updating ElementAspect [exclusive lock not held on element for update aspect (id=0x20000000004)], id: 0x30000000001\");\n\n /* acquire lock and try again */\n await b1.locks.acquireLocks({ exclusive: el1 });\n updateAspectIntoB1();\n\n /* delete the element */\n b1Txn.deleteElement(el1);\n b1Txn.saveChanges();\n\n await b1.pushChanges({ accessToken: accessToken1, description: `deleted element ${el1}` });\n\n const onChangesetConflictStub = sinon.stub(BriefcaseDb.prototype, \"onChangesetConflict\" as any);\n /* we should be able to apply all changesets */\n await b3.pullChanges();\n expect(onChangesetConflictStub.callCount).eq(0, \"native conflict handler should not be called BriefcaseDb.onChangesetConflict()\");\n onChangesetConflictStub.restore();\n b1.close();\n b2.close();\n b3.close();\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"MergeConflict.test.js","sourceRoot":"","sources":["../../../../src/test/standalone/MergeConflict.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\nimport { GuidString, Id64String } from \"@itwin/core-bentley\";\nimport { EditTxn, withEditTxn } from \"../../EditTxn\";\nimport {\n ElementAspectProps,\n IModel,\n SubCategoryAppearance,\n} from \"@itwin/core-common\";\nimport * as chai from \"chai\";\nimport { assert, expect } from \"chai\";\nimport * as chaiAsPromised from \"chai-as-promised\";\nimport { HubWrappers, KnownTestLocations } from \"../\";\nimport { HubMock } from \"../../internal/HubMock\";\nimport {\n BriefcaseDb,\n ChannelControl,\n DictionaryModel,\n ExternalSourceAspect,\n SpatialCategory,\n SqliteChangeOp,\n} from \"../../core-backend\";\nimport { IModelTestUtils, TestUserType } from \"../IModelTestUtils\";\nimport { RebaseChangesetConflictArgs, SqliteConflictCause } from \"../../internal/ChangesetConflictArgs\";\nchai.use(chaiAsPromised);\nimport * as sinon from \"sinon\";\n\nexport async function createNewModelAndCategory(txn: EditTxn, parent?: Id64String) {\n const rwIModel = txn.iModel as BriefcaseDb;\n // Create a new physical model.\n const [, modelId] = await IModelTestUtils.createAndInsertPhysicalPartitionAndModelAsync(txn, IModelTestUtils.getUniqueModelCode(rwIModel, \"newPhysicalModel\"), true, parent);\n\n // Find or create a SpatialCategory.\n const dictionary: DictionaryModel = rwIModel.models.getModel<DictionaryModel>(IModel.dictionaryId);\n const newCategoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, \"ThisTestSpatialCategory\");\n const category = SpatialCategory.create(rwIModel, IModel.dictionaryId, newCategoryCode.value);\n const spatialCategoryId = txn.insertElement(category.toJSON());\n category.setDefaultAppearance(txn, new SubCategoryAppearance({ color: 0xff0000 }));\n\n return { modelId, spatialCategoryId };\n}\n\nasync function assertThrowsAsync<T>(test: () => Promise<T>, msg?: string) {\n try {\n await test();\n } catch (e) {\n if (e instanceof Error && msg) {\n assert.equal(e.message, msg);\n }\n return;\n }\n throw new Error(`Failed to throw error with message: \"${msg}\"`);\n}\n\ndescribe(\"Merge conflict & locking\", () => { \n let iTwinId: GuidString;\n\n before(() => {\n HubMock.startup(\"MergeConflictTest\", KnownTestLocations.outputDir);\n iTwinId = HubMock.iTwinId;\n });\n after(() => HubMock.shutdown());\n\n it(\"pull/merge causing update conflict - dirty read/modify (with no lock)\", async () => {\n /**\n * To simulate a a data conflict for dirty read we update same aspect from two different briefcases\n * and when the second briefcase try to push its changes it will fail with following error.\n * \"UPDATE/DELETE before value do not match with one in db or CASCADE action was triggered.\"\n */\n const accessToken1 = await HubWrappers.getAccessToken(TestUserType.SuperManager);\n const accessToken2 = await HubWrappers.getAccessToken(TestUserType.Regular);\n const accessToken3 = await HubWrappers.getAccessToken(TestUserType.Super);\n\n // Delete any existing iModels with the same name as the read-write test iModel\n const iModelName = \"TestIModel\";\n\n // Create a new empty iModel on the Hub & obtain a briefcase\n const rwIModelId = await HubMock.createNewIModel({ accessToken: accessToken1, iTwinId, iModelName, description: \"TestSubject\", noLocks: undefined });\n assert.isNotEmpty(rwIModelId);\n\n // to reproduce the issue we will disable locks altogether.\n const b1 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken1, iTwinId, iModelId: rwIModelId, noLock: true });\n b1.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b2 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken2, iTwinId, iModelId: rwIModelId, noLock: true });\n b2.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b3 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken3, iTwinId, iModelId: rwIModelId, noLock: true });\n const b1Txn = new EditTxn(b1, \"merge conflict\");\n b1Txn.start();\n const b2Txn = new EditTxn(b2, \"merge conflict\");\n b2Txn.start();\n\n // create and insert a new model with code1\n const [, modelId] = IModelTestUtils.createAndInsertPhysicalPartitionAndModel(\n b1Txn,\n IModelTestUtils.getUniqueModelCode(b1, \"newPhysicalModel\"),\n true);\n\n const dictionary: DictionaryModel = b1.models.getModel<DictionaryModel>(IModel.dictionaryId);\n const newCategoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, \"ThisTestSpatialCategory\");\n\n const spatialCategoryId = SpatialCategory.insert(\n b1Txn,\n dictionary.id,\n newCategoryCode.value,\n new SubCategoryAppearance({ color: 0xff0000 }),\n );\n\n // insert element and aspect\n const el1 = b1Txn.insertElement(IModelTestUtils.createPhysicalObject(b1, modelId, spatialCategoryId).toJSON());\n await b1.pullChanges();\n const aspectId1 = b1Txn.insertAspect({\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier\",\n } as ElementAspectProps);\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `inserted element with aspect ${el1}` });\n\n // b1 same as b2 and now both will modify same aspect\n await b2.pullChanges();\n\n // b1 will change identifier from \"test identifier\" to \"test identifier (modified by b1)\"\n b1Txn.updateAspect({\n id: aspectId1,\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier (modified by b1)\",\n } as ElementAspectProps);\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `modify aspect ${aspectId1} with no lock` });\n\n // b2 will change identifier from \"test identifier\" to \"test identifier (modified by b2)\"\n b2Txn.updateAspect({\n id: aspectId1,\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier (modified by b2)\",\n } as ElementAspectProps);\n b2Txn.saveChanges();\n\n const conflicts: {\n cause: SqliteConflictCause,\n tableName: string,\n opcode?: SqliteChangeOp,\n id: Id64String,\n }[] = [];\n\n // we will not handle conflict and let the default conflict handler deal with it.\n b2.txns.rebaser.addConflictHandler({\n id: \"custom\", handler: (arg: RebaseChangesetConflictArgs) => {\n conflicts.push({\n cause: arg.cause,\n tableName: arg.tableName,\n opcode: arg.opcode,\n id: arg.getValueId(0, arg.opcode === \"Inserted\" ? \"New\" : \"Old\") as Id64String,\n });\n return undefined;\n }\n });\n\n await b2.pushChanges({ accessToken: accessToken1, description: `modify aspect ${aspectId1} with no lock` });\n\n expect(conflicts.length).to.be.equals(3);\n\n chai.expect(\n [\n {\n \"cause\": \"Data\",\n \"tableName\": \"bis_Element\",\n \"opcode\": \"Updated\",\n \"id\": \"0x20000000004\"\n },\n {\n \"cause\": \"Data\",\n \"tableName\": \"bis_ElementMultiAspect\",\n \"opcode\": \"Updated\",\n \"id\": \"0x20000000001\"\n },\n {\n \"cause\": \"Data\",\n \"tableName\": \"bis_Model\",\n \"opcode\": \"Updated\",\n \"id\": \"0x20000000001\"\n }\n ]).to.be.deep.equals(conflicts);\n\n await b3.pullChanges();\n await b1.pullChanges();\n\n // b2 win as default conflict handler choose Replace to override local changes over master.\n (b2.elements.getAspect(aspectId1) as ExternalSourceAspect).identifier = \"test identifier (modified by b2)\";\n (b3.elements.getAspect(aspectId1) as ExternalSourceAspect).identifier = \"test identifier (modified by b2)\";\n (b1.elements.getAspect(aspectId1) as ExternalSourceAspect).identifier = \"test identifier (modified by b2)\";\n\n b1.close();\n b2.close();\n b3.close();\n });\n it(\"pull/merge causing update conflict - update causing local changes (with no lock)\", async () => {\n /**\n * To simulate a a data conflict for dirty read we update same aspect from two different briefcases\n * and when the second briefcase try to push its changes it will fail with following error.\n * \"UPDATE/DELETE before value do not match with one in db or CASCADE action was triggered.\"\n */\n const accessToken1 = await HubWrappers.getAccessToken(TestUserType.SuperManager);\n const accessToken2 = await HubWrappers.getAccessToken(TestUserType.Regular);\n const accessToken3 = await HubWrappers.getAccessToken(TestUserType.Super);\n\n // Delete any existing iModels with the same name as the read-write test iModel\n const iModelName = \"TestIModel\";\n\n // Create a new empty iModel on the Hub & obtain a briefcase\n const rwIModelId = await HubMock.createNewIModel({ accessToken: accessToken1, iTwinId, iModelName, description: \"TestSubject\", noLocks: undefined });\n assert.isNotEmpty(rwIModelId);\n\n // to reproduce the issue we will disable locks altogether.\n const b1 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken1, iTwinId, iModelId: rwIModelId, noLock: true });\n b1.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b2 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken2, iTwinId, iModelId: rwIModelId, noLock: true });\n b2.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b3 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken3, iTwinId, iModelId: rwIModelId, noLock: true });\n const b1Txn = new EditTxn(b1, \"merge conflict\");\n b1Txn.start();\n const b2Txn = new EditTxn(b2, \"merge conflict\");\n b2Txn.start();\n\n // create and insert a new model with code1\n const [, modelId] = IModelTestUtils.createAndInsertPhysicalPartitionAndModel(\n b1Txn,\n IModelTestUtils.getUniqueModelCode(b1, \"newPhysicalModel\"),\n true);\n\n const dictionary: DictionaryModel = b1.models.getModel<DictionaryModel>(IModel.dictionaryId);\n const newCategoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, \"ThisTestSpatialCategory\");\n\n const spatialCategoryId = SpatialCategory.insert(\n b1Txn,\n dictionary.id,\n newCategoryCode.value,\n new SubCategoryAppearance({ color: 0xff0000 }),\n );\n\n // insert element and aspect\n const el1 = b1Txn.insertElement(IModelTestUtils.createPhysicalObject(b1, modelId, spatialCategoryId).toJSON());\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `inserted element with aspect ${el1}` });\n\n await b2.pullChanges();\n const aspectId1 = b2Txn.insertAspect({\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier\",\n } as ElementAspectProps);\n b2Txn.saveChanges();\n\n b1Txn.deleteElement(el1);\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `deleted element ${el1}` });\n\n const conflicts: {\n cause: SqliteConflictCause,\n tableName: string,\n opcode?: SqliteChangeOp,\n id: Id64String | undefined,\n }[] = [];\n\n // we will not handle conflict and let the default conflict handler deal with it.\n b2.txns.rebaser.addConflictHandler({\n id: \"custom\", handler: (arg: RebaseChangesetConflictArgs) => {\n let id;\n if (arg.cause !== \"ForeignKey\") {\n id = arg.getValueId(0, arg.opcode === \"Inserted\" ? \"New\" : \"Old\") as Id64String;\n }\n conflicts.push({\n cause: arg.cause,\n tableName: arg.tableName,\n opcode: arg.opcode,\n id,\n });\n return undefined;\n }\n });\n\n\n await assertThrowsAsync(\n async () => b2.pushChanges({ accessToken: accessToken1, description: `inserted element with aspect ${el1}` }),\n \"Foreign key conflicts in ChangeSet. Aborting rebase.\");\n\n expect(conflicts.length).to.be.equals(3);\n expect(conflicts).to.deep.equal([\n {\n cause: \"NotFound\",\n tableName: \"bis_Element\",\n opcode: \"Updated\",\n id: \"0x20000000004\"\n },\n {\n cause: \"Data\",\n tableName: \"bis_Model\",\n opcode: \"Updated\",\n id: \"0x20000000001\"\n },\n {\n cause: \"ForeignKey\",\n tableName: \"\",\n opcode: undefined,\n id: undefined\n }\n ]);\n\n b2.txns.rebaser.addConflictHandler({\n id: \"delete_aspect_when_element_is_deleted\", handler: (arg: RebaseChangesetConflictArgs) => {\n if (arg.cause === \"NotFound\" && arg.tableName === \"bis_Element\") {\n // if element does not exist any more let delete the aspects as well.\n const elId = arg.getValueId(0, arg.opcode === \"Inserted\" ? \"New\" : \"Old\") as Id64String;\n withEditTxn(b2, (txn) => {\n b2.elements.getAspects(elId).forEach((aspect) => {\n txn.deleteAspect(aspect.id);\n });\n });\n }\n return undefined;\n }\n });\n\n b2Txn.saveChanges();\n conflicts.length = 0;\n\n await b2.pushChanges({ accessToken: accessToken1, description: `nothing is pushed as the only change we made is reverted` });\n await b3.pullChanges();\n await b1.pullChanges();\n\n expect(() => b1.elements.getElement(el1)).throws(`Element=${el1}`);\n expect(() => b2.elements.getElement(el1)).throws(`Element=${el1}`);\n expect(() => b3.elements.getElement(el1)).throws(`Element=${el1}`);\n\n expect(() => b1.elements.getAspect(aspectId1)).throws(`ElementAspect not found ${aspectId1}`);\n expect(() => b2.elements.getAspect(aspectId1)).throws(`ElementAspect not found ${aspectId1}`);\n expect(() => b3.elements.getAspect(aspectId1)).throws(`ElementAspect not found ${aspectId1}`);\n\n b1.close();\n b2.close();\n b3.close();\n });\n\n it(\"aspect insert, update & delete requires exclusive lock\", async () => {\n const accessToken1 = await HubWrappers.getAccessToken(TestUserType.SuperManager);\n const accessToken2 = await HubWrappers.getAccessToken(TestUserType.Regular);\n const accessToken3 = await HubWrappers.getAccessToken(TestUserType.Super);\n\n // Delete any existing iModels with the same name as the read-write test iModel\n const iModelName = \"TestIModel\";\n\n // Create a new empty iModel on the Hub & obtain a briefcase\n const rwIModelId = await HubMock.createNewIModel({ accessToken: accessToken1, iTwinId, iModelName, description: \"TestSubject\", noLocks: undefined });\n assert.isNotEmpty(rwIModelId);\n\n const b1 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken1, iTwinId, iModelId: rwIModelId });\n b1.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b2 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken2, iTwinId, iModelId: rwIModelId });\n b2.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b3 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken3, iTwinId, iModelId: rwIModelId });\n const b1Txn = new EditTxn(b1, \"merge conflict\");\n b1Txn.start();\n const b2Txn = new EditTxn(b2, \"merge conflict\");\n b2Txn.start();\n\n await b1.locks.acquireLocks({ shared: IModel.repositoryModelId });\n await b2.locks.acquireLocks({ shared: IModel.repositoryModelId });\n\n // create and insert a new model with code1\n const [, modelId] = IModelTestUtils.createAndInsertPhysicalPartitionAndModel(\n b1Txn,\n IModelTestUtils.getUniqueModelCode(b1, \"newPhysicalModel\"),\n true);\n\n const dictionary: DictionaryModel = b1.models.getModel<DictionaryModel>(IModel.dictionaryId);\n const newCategoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, \"ThisTestSpatialCategory\");\n\n await b1.locks.acquireLocks({ shared: dictionary.id });\n const spatialCategoryId = SpatialCategory.insert(\n b1Txn,\n dictionary.id,\n newCategoryCode.value,\n new SubCategoryAppearance({ color: 0xff0000 }),\n );\n const el1 = b1Txn.insertElement(IModelTestUtils.createPhysicalObject(b1, modelId, spatialCategoryId).toJSON());\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `inserted element ${el1}` });\n\n await b2.pullChanges();\n let aspectId: Id64String;\n const insertAspectIntoB2 = () => {\n aspectId = b2Txn.insertAspect({\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier\",\n } as ElementAspectProps);\n };\n\n /* attempt to insert aspect without a lock */\n assert.throws(insertAspectIntoB2, \"Error inserting ElementAspect [exclusive lock not held on element for insert aspect (id=0x20000000004)], class: BisCore:ExternalSourceAspect\");\n\n /* acquire lock and try again */\n await b2.locks.acquireLocks({ exclusive: el1 });\n insertAspectIntoB2();\n\n /* b1 cannot acquire lock on el1 as its already taken by b2 */\n await expect(b1.locks.acquireLocks({ exclusive: el1 })).to.be.rejectedWith(\"exclusive lock is already held\");\n\n /* push changes on b2 to release lock on el1 */\n b2Txn.saveChanges();\n await b2.pushChanges({ accessToken: accessToken2, description: `add aspect to element ${el1}` });\n\n await b1.pullChanges();\n\n const updateAspectIntoB1 = () => {\n b1Txn.updateAspect({\n id: aspectId,\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier (modified)\",\n } as ElementAspectProps);\n };\n\n /* attempt to update aspect without a lock */\n assert.throws(updateAspectIntoB1, \"Error updating ElementAspect [exclusive lock not held on element for update aspect (id=0x20000000004)], id: 0x30000000001\");\n\n /* acquire lock and try again */\n await b1.locks.acquireLocks({ exclusive: el1 });\n updateAspectIntoB1();\n\n /* delete the element */\n b1Txn.deleteElement(el1);\n b1Txn.saveChanges();\n\n await b1.pushChanges({ accessToken: accessToken1, description: `deleted element ${el1}` });\n\n const onChangesetConflictStub = sinon.stub(BriefcaseDb.prototype, \"onChangesetConflict\" as any);\n /* we should be able to apply all changesets */\n await b3.pullChanges();\n expect(onChangesetConflictStub.callCount).eq(0, \"native conflict handler should not be called BriefcaseDb.onChangesetConflict()\");\n onChangesetConflictStub.restore();\n b1.close();\n b2.close();\n b3.close();\n });\n});\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import "../TestUtils";
|
|
2
2
|
//# sourceMappingURL=SQLiteDb.test.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SQLiteDb.test.d.ts","sourceRoot":"","sources":["../../../../src/test/standalone/SQLiteDb.test.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"SQLiteDb.test.d.ts","sourceRoot":"","sources":["../../../../src/test/standalone/SQLiteDb.test.ts"],"names":[],"mappings":"AAYA,OAAO,cAAc,CAAC"}
|