@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
|
@@ -2,10 +2,65 @@
|
|
|
2
2
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
3
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
6
|
+
if (value !== null && value !== void 0) {
|
|
7
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
8
|
+
var dispose, inner;
|
|
9
|
+
if (async) {
|
|
10
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
11
|
+
dispose = value[Symbol.asyncDispose];
|
|
12
|
+
}
|
|
13
|
+
if (dispose === void 0) {
|
|
14
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
15
|
+
dispose = value[Symbol.dispose];
|
|
16
|
+
if (async) inner = dispose;
|
|
17
|
+
}
|
|
18
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
19
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
20
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
21
|
+
}
|
|
22
|
+
else if (async) {
|
|
23
|
+
env.stack.push({ async: true });
|
|
24
|
+
}
|
|
25
|
+
return value;
|
|
26
|
+
};
|
|
27
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
28
|
+
return function (env) {
|
|
29
|
+
function fail(e) {
|
|
30
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
31
|
+
env.hasError = true;
|
|
32
|
+
}
|
|
33
|
+
var r, s = 0;
|
|
34
|
+
function next() {
|
|
35
|
+
while (r = env.stack.pop()) {
|
|
36
|
+
try {
|
|
37
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
38
|
+
if (r.dispose) {
|
|
39
|
+
var result = r.dispose.call(r.value);
|
|
40
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
41
|
+
}
|
|
42
|
+
else s |= 1;
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
fail(e);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
49
|
+
if (env.hasError) throw env.error;
|
|
50
|
+
}
|
|
51
|
+
return next();
|
|
52
|
+
};
|
|
53
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
54
|
+
var e = new Error(message);
|
|
55
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
56
|
+
});
|
|
5
57
|
import { expect } from "chai";
|
|
6
58
|
import { BeDuration, DbResult, OpenMode } from "@itwin/core-bentley";
|
|
7
|
-
import {
|
|
59
|
+
import { IModelJsFs } from "../../IModelJsFs";
|
|
8
60
|
import { IModelTestUtils } from "../IModelTestUtils";
|
|
61
|
+
import { SQLiteDb } from "../../SQLiteDb";
|
|
62
|
+
import { SqliteChangesetReader } from "../../SqliteChangesetReader";
|
|
63
|
+
import "../TestUtils"; // registers the global mocha before/after hooks that start/stop the backend
|
|
9
64
|
describe("SQLiteDb", () => {
|
|
10
65
|
it("should create new SQLiteDb", async () => {
|
|
11
66
|
const fileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "db1.db");
|
|
@@ -59,5 +114,95 @@ describe("SQLiteDb", () => {
|
|
|
59
114
|
});
|
|
60
115
|
});
|
|
61
116
|
});
|
|
117
|
+
describe("applyChangeset", () => {
|
|
118
|
+
const readRows = (db, tableName) => {
|
|
119
|
+
const rows = [];
|
|
120
|
+
db.withSqliteStatement(`SELECT id,val FROM ${tableName} ORDER BY id`, (stmt) => {
|
|
121
|
+
while (stmt.step() === DbResult.BE_SQLITE_ROW)
|
|
122
|
+
rows.push({ id: stmt.getValue(0).getInteger(), val: stmt.getValue(1).getString() });
|
|
123
|
+
});
|
|
124
|
+
return rows;
|
|
125
|
+
};
|
|
126
|
+
it("should apply a changeset containing DDL and data changes", () => {
|
|
127
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
128
|
+
try {
|
|
129
|
+
const sourceFileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "applyChangeset-source.db");
|
|
130
|
+
const targetFileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "applyChangeset-target.db");
|
|
131
|
+
const changesetFileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "applyChangeset-1.changeset");
|
|
132
|
+
// create the source db, and capture a changeset that creates a table and inserts some rows
|
|
133
|
+
const source = new SQLiteDb();
|
|
134
|
+
source.createDb(sourceFileName, undefined, { rawSQLite: true });
|
|
135
|
+
source.startChangeTracking();
|
|
136
|
+
source.executeDdl("CREATE TABLE test1(id INTEGER PRIMARY KEY,val TEXT)");
|
|
137
|
+
source.executeSQL(`INSERT INTO test1(id,val) VALUES (1,'val1')`);
|
|
138
|
+
source.executeSQL(`INSERT INTO test1(id,val) VALUES (2,'val2')`);
|
|
139
|
+
source.saveChanges();
|
|
140
|
+
source.createChangeset(changesetFileName);
|
|
141
|
+
// verify the changeset's ddl/data via the existing SqliteChangesetReader
|
|
142
|
+
const reader = __addDisposableResource(env_1, SqliteChangesetReader.openFile({ fileName: changesetFileName, db: source, disableSchemaCheck: true }), false);
|
|
143
|
+
let dataChangeCount = 0;
|
|
144
|
+
while (reader.step())
|
|
145
|
+
++dataChangeCount;
|
|
146
|
+
expect(dataChangeCount).equal(2);
|
|
147
|
+
// apply the changeset (from scratch - no header validation should be required) to a brand new, empty db
|
|
148
|
+
const target = new SQLiteDb();
|
|
149
|
+
target.createDb(targetFileName, undefined, { rawSQLite: true });
|
|
150
|
+
target.applyChangeset(changesetFileName);
|
|
151
|
+
target.saveChanges();
|
|
152
|
+
expect(readRows(target, "test1")).deep.equal([{ id: 1, val: "val1" }, { id: 2, val: "val2" }]);
|
|
153
|
+
source.closeDb();
|
|
154
|
+
target.closeDb();
|
|
155
|
+
}
|
|
156
|
+
catch (e_1) {
|
|
157
|
+
env_1.error = e_1;
|
|
158
|
+
env_1.hasError = true;
|
|
159
|
+
}
|
|
160
|
+
finally {
|
|
161
|
+
__disposeResources(env_1);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
it("should fail if applying a changeset produces a conflict, leaving it to the caller to abandon the partially-applied changes", () => {
|
|
165
|
+
const baseFileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "applyChangeset-base.db");
|
|
166
|
+
const sourceFileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "applyChangeset-conflict-source.db");
|
|
167
|
+
const targetFileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "applyChangeset-conflict-target.db");
|
|
168
|
+
const changesetFileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "applyChangeset-2.changeset");
|
|
169
|
+
// create a common base db with two rows, then clone it so source and target start out identical
|
|
170
|
+
const base = new SQLiteDb();
|
|
171
|
+
base.createDb(baseFileName, undefined, { rawSQLite: true });
|
|
172
|
+
base.executeSQL("CREATE TABLE test1(id INTEGER PRIMARY KEY,val TEXT)");
|
|
173
|
+
base.executeSQL(`INSERT INTO test1(id,val) VALUES (1,'base1')`);
|
|
174
|
+
base.executeSQL(`INSERT INTO test1(id,val) VALUES (2,'base2')`);
|
|
175
|
+
base.saveChanges();
|
|
176
|
+
base.closeDb();
|
|
177
|
+
IModelJsFs.copySync(baseFileName, sourceFileName);
|
|
178
|
+
IModelJsFs.copySync(baseFileName, targetFileName);
|
|
179
|
+
// diverge source: update both rows and capture that as a single changeset. Only the second row will
|
|
180
|
+
// conflict with target's divergence below - the first row's change would apply cleanly on its own.
|
|
181
|
+
const source = new SQLiteDb();
|
|
182
|
+
source.openDb(sourceFileName, { openMode: OpenMode.ReadWrite, rawSQLite: true });
|
|
183
|
+
source.startChangeTracking();
|
|
184
|
+
source.executeSQL(`UPDATE test1 SET val='fromSource1' WHERE id=1`);
|
|
185
|
+
source.executeSQL(`UPDATE test1 SET val='fromSource2' WHERE id=2`);
|
|
186
|
+
source.saveChanges();
|
|
187
|
+
source.createChangeset(changesetFileName);
|
|
188
|
+
source.closeDb();
|
|
189
|
+
// diverge target independently - only on the second row - so applying source's changeset conflicts partway through
|
|
190
|
+
const target = new SQLiteDb();
|
|
191
|
+
target.openDb(targetFileName, { openMode: OpenMode.ReadWrite, rawSQLite: true });
|
|
192
|
+
target.executeSQL(`UPDATE test1 SET val='fromTarget2' WHERE id=2`);
|
|
193
|
+
target.saveChanges();
|
|
194
|
+
// confirm the pre-apply baseline: id=1 was never touched by target, id=2 diverged from source
|
|
195
|
+
expect(readRows(target, "test1")).deep.equal([{ id: 1, val: "base1" }, { id: 2, val: "fromTarget2" }]);
|
|
196
|
+
// applyChangeset only throws on failure - it does not commit or abandon changes itself. Since the first
|
|
197
|
+
// row's change didn't conflict, it may already have been applied to the current transaction by the time
|
|
198
|
+
// the second row's conflict causes the throw.
|
|
199
|
+
expect(() => target.applyChangeset(changesetFileName)).throws();
|
|
200
|
+
expect(readRows(target, "test1")).deep.equal([{ id: 1, val: "fromSource1" }, { id: 2, val: "fromTarget2" }]);
|
|
201
|
+
// it is the caller's responsibility to abandon (or save) the partially-applied changes after catching the error
|
|
202
|
+
target.abandonChanges();
|
|
203
|
+
expect(readRows(target, "test1")).deep.equal([{ id: 1, val: "base1" }, { id: 2, val: "fromTarget2" }]);
|
|
204
|
+
target.closeDb();
|
|
205
|
+
});
|
|
206
|
+
});
|
|
62
207
|
});
|
|
63
208
|
//# sourceMappingURL=SQLiteDb.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SQLiteDb.test.js","sourceRoot":"","sources":["../../../../src/test/standalone/SQLiteDb.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 { expect } from \"chai\";\nimport { BeDuration, DbResult, OpenMode } from \"@itwin/core-bentley\";\nimport { SQLiteDb } from \"../../SQLiteDb\";\nimport { IModelTestUtils } from \"../IModelTestUtils\";\n\ndescribe(\"SQLiteDb\", () => {\n\n it(\"should create new SQLiteDb\", async () => {\n const fileName = IModelTestUtils.prepareOutputFile(\"SQLiteDb\", \"db1.db\");\n const db = new SQLiteDb();\n db.createDb(fileName, undefined, { rawSQLite: true, pageSize: 8 * 1024 });\n db.executeSQL(\"CREATE TABLE test1(id INTEGER PRIMARY KEY,val TEXT)\");\n db.executeSQL(`INSERT INTO test1(id,val) VALUES (1,\"val1\")`);\n db.executeSQL(`INSERT INTO test1(id,val) VALUES (2,\"val2\")`);\n db.saveChanges();\n\n const testDb = () => {\n db.withSqliteStatement(\"SELECT id,val from test1\", (stmt) => {\n stmt.step();\n expect(stmt.getValue(0).getInteger()).equal(1);\n expect(stmt.getValue(1).getString()).equal(\"val1\");\n stmt.step();\n expect(stmt.getValue(0).getInteger()).equal(2);\n expect(stmt.getValue(1).getString()).equal(\"val2\");\n });\n db.closeDb();\n };\n testDb();\n\n // now test immutable flag\n db.openDb(fileName, { openMode: OpenMode.Readonly, skipFileCheck: true, immutable: true, defaultTxn: SQLiteDb.DefaultTxnMode.None, rawSQLite: true });\n testDb();\n\n expect(db.isOpen).false;\n expect(() => db.vacuum()).throws(\"not open\");\n\n let val = db.withOpenDb({ dbName: fileName, openMode: { openMode: OpenMode.ReadWrite, rawSQLite: true } }, () => {\n expect(db.isOpen);\n db.vacuum();\n return 22;\n });\n expect(val).equal(22);\n expect(db.isOpen).false;\n\n val = await db.withOpenDb({ dbName: fileName, openMode: { openMode: OpenMode.ReadWrite, rawSQLite: true } }, async () => {\n expect(db.isOpen);\n await BeDuration.fromMilliseconds(10).wait();\n return 100;\n });\n expect(val).equal(100);\n expect(db.isOpen).false;\n });\n\n it(\"should be able to open existing .bim file with SQLiteDb\", () => {\n const testFileName = IModelTestUtils.resolveAssetFile(\"test.bim\");\n const db = new SQLiteDb();\n db.withOpenDb({ dbName: testFileName }, () => {\n db.withSqliteStatement(`SELECT StrData FROM be_Prop WHERE Namespace=\"ec_Db\" AND Name=\"SchemaVersion\"`, (stmt) => {\n expect(stmt.step()).equal(DbResult.BE_SQLITE_ROW);\n const val = JSON.parse(stmt.getValue(0).getString());\n expect(val.major).equal(4, \"read major version\");\n expect(val.minor).equal(0, \"read minor version\");\n });\n });\n });\n\n});\n"]}
|
|
1
|
+
{"version":3,"file":"SQLiteDb.test.js","sourceRoot":"","sources":["../../../../src/test/standalone/SQLiteDb.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 { expect } from \"chai\";\nimport { BeDuration, DbResult, OpenMode } from \"@itwin/core-bentley\";\nimport type { IModelDb } from \"../../IModelDb\";\nimport { IModelJsFs } from \"../../IModelJsFs\";\nimport { IModelTestUtils } from \"../IModelTestUtils\";\nimport { SQLiteDb } from \"../../SQLiteDb\";\nimport { SqliteChangesetReader } from \"../../SqliteChangesetReader\";\nimport \"../TestUtils\"; // registers the global mocha before/after hooks that start/stop the backend\n\ndescribe(\"SQLiteDb\", () => {\n\n it(\"should create new SQLiteDb\", async () => {\n const fileName = IModelTestUtils.prepareOutputFile(\"SQLiteDb\", \"db1.db\");\n const db = new SQLiteDb();\n db.createDb(fileName, undefined, { rawSQLite: true, pageSize: 8 * 1024 });\n db.executeSQL(\"CREATE TABLE test1(id INTEGER PRIMARY KEY,val TEXT)\");\n db.executeSQL(`INSERT INTO test1(id,val) VALUES (1,\"val1\")`);\n db.executeSQL(`INSERT INTO test1(id,val) VALUES (2,\"val2\")`);\n db.saveChanges();\n\n const testDb = () => {\n db.withSqliteStatement(\"SELECT id,val from test1\", (stmt) => {\n stmt.step();\n expect(stmt.getValue(0).getInteger()).equal(1);\n expect(stmt.getValue(1).getString()).equal(\"val1\");\n stmt.step();\n expect(stmt.getValue(0).getInteger()).equal(2);\n expect(stmt.getValue(1).getString()).equal(\"val2\");\n });\n db.closeDb();\n };\n testDb();\n\n // now test immutable flag\n db.openDb(fileName, { openMode: OpenMode.Readonly, skipFileCheck: true, immutable: true, defaultTxn: SQLiteDb.DefaultTxnMode.None, rawSQLite: true });\n testDb();\n\n expect(db.isOpen).false;\n expect(() => db.vacuum()).throws(\"not open\");\n\n let val = db.withOpenDb({ dbName: fileName, openMode: { openMode: OpenMode.ReadWrite, rawSQLite: true } }, () => {\n expect(db.isOpen);\n db.vacuum();\n return 22;\n });\n expect(val).equal(22);\n expect(db.isOpen).false;\n\n val = await db.withOpenDb({ dbName: fileName, openMode: { openMode: OpenMode.ReadWrite, rawSQLite: true } }, async () => {\n expect(db.isOpen);\n await BeDuration.fromMilliseconds(10).wait();\n return 100;\n });\n expect(val).equal(100);\n expect(db.isOpen).false;\n });\n\n it(\"should be able to open existing .bim file with SQLiteDb\", () => {\n const testFileName = IModelTestUtils.resolveAssetFile(\"test.bim\");\n const db = new SQLiteDb();\n db.withOpenDb({ dbName: testFileName }, () => {\n db.withSqliteStatement(`SELECT StrData FROM be_Prop WHERE Namespace=\"ec_Db\" AND Name=\"SchemaVersion\"`, (stmt) => {\n expect(stmt.step()).equal(DbResult.BE_SQLITE_ROW);\n const val = JSON.parse(stmt.getValue(0).getString());\n expect(val.major).equal(4, \"read major version\");\n expect(val.minor).equal(0, \"read minor version\");\n });\n });\n });\n\n describe(\"applyChangeset\", () => {\n const readRows = (db: SQLiteDb, tableName: string) => {\n const rows: Array<{ id: number, val: string }> = [];\n db.withSqliteStatement(`SELECT id,val FROM ${tableName} ORDER BY id`, (stmt) => {\n while (stmt.step() === DbResult.BE_SQLITE_ROW)\n rows.push({ id: stmt.getValue(0).getInteger(), val: stmt.getValue(1).getString() });\n });\n return rows;\n };\n\n it(\"should apply a changeset containing DDL and data changes\", () => {\n const sourceFileName = IModelTestUtils.prepareOutputFile(\"SQLiteDb\", \"applyChangeset-source.db\");\n const targetFileName = IModelTestUtils.prepareOutputFile(\"SQLiteDb\", \"applyChangeset-target.db\");\n const changesetFileName = IModelTestUtils.prepareOutputFile(\"SQLiteDb\", \"applyChangeset-1.changeset\");\n\n // create the source db, and capture a changeset that creates a table and inserts some rows\n const source = new SQLiteDb();\n source.createDb(sourceFileName, undefined, { rawSQLite: true });\n source.startChangeTracking();\n source.executeDdl(\"CREATE TABLE test1(id INTEGER PRIMARY KEY,val TEXT)\");\n source.executeSQL(`INSERT INTO test1(id,val) VALUES (1,'val1')`);\n source.executeSQL(`INSERT INTO test1(id,val) VALUES (2,'val2')`);\n source.saveChanges();\n source.createChangeset(changesetFileName);\n\n // verify the changeset's ddl/data via the existing SqliteChangesetReader\n using reader = SqliteChangesetReader.openFile({ fileName: changesetFileName, db: source as unknown as IModelDb, disableSchemaCheck: true });\n let dataChangeCount = 0;\n while (reader.step())\n ++dataChangeCount;\n expect(dataChangeCount).equal(2);\n\n // apply the changeset (from scratch - no header validation should be required) to a brand new, empty db\n const target = new SQLiteDb();\n target.createDb(targetFileName, undefined, { rawSQLite: true });\n target.applyChangeset(changesetFileName);\n target.saveChanges();\n\n expect(readRows(target, \"test1\")).deep.equal([{ id: 1, val: \"val1\" }, { id: 2, val: \"val2\" }]);\n\n source.closeDb();\n target.closeDb();\n });\n\n it(\"should fail if applying a changeset produces a conflict, leaving it to the caller to abandon the partially-applied changes\", () => {\n const baseFileName = IModelTestUtils.prepareOutputFile(\"SQLiteDb\", \"applyChangeset-base.db\");\n const sourceFileName = IModelTestUtils.prepareOutputFile(\"SQLiteDb\", \"applyChangeset-conflict-source.db\");\n const targetFileName = IModelTestUtils.prepareOutputFile(\"SQLiteDb\", \"applyChangeset-conflict-target.db\");\n const changesetFileName = IModelTestUtils.prepareOutputFile(\"SQLiteDb\", \"applyChangeset-2.changeset\");\n\n // create a common base db with two rows, then clone it so source and target start out identical\n const base = new SQLiteDb();\n base.createDb(baseFileName, undefined, { rawSQLite: true });\n base.executeSQL(\"CREATE TABLE test1(id INTEGER PRIMARY KEY,val TEXT)\");\n base.executeSQL(`INSERT INTO test1(id,val) VALUES (1,'base1')`);\n base.executeSQL(`INSERT INTO test1(id,val) VALUES (2,'base2')`);\n base.saveChanges();\n base.closeDb();\n\n IModelJsFs.copySync(baseFileName, sourceFileName);\n IModelJsFs.copySync(baseFileName, targetFileName);\n\n // diverge source: update both rows and capture that as a single changeset. Only the second row will\n // conflict with target's divergence below - the first row's change would apply cleanly on its own.\n const source = new SQLiteDb();\n source.openDb(sourceFileName, { openMode: OpenMode.ReadWrite, rawSQLite: true });\n source.startChangeTracking();\n source.executeSQL(`UPDATE test1 SET val='fromSource1' WHERE id=1`);\n source.executeSQL(`UPDATE test1 SET val='fromSource2' WHERE id=2`);\n source.saveChanges();\n source.createChangeset(changesetFileName);\n source.closeDb();\n\n // diverge target independently - only on the second row - so applying source's changeset conflicts partway through\n const target = new SQLiteDb();\n target.openDb(targetFileName, { openMode: OpenMode.ReadWrite, rawSQLite: true });\n target.executeSQL(`UPDATE test1 SET val='fromTarget2' WHERE id=2`);\n target.saveChanges();\n\n // confirm the pre-apply baseline: id=1 was never touched by target, id=2 diverged from source\n expect(readRows(target, \"test1\")).deep.equal([{ id: 1, val: \"base1\" }, { id: 2, val: \"fromTarget2\" }]);\n\n // applyChangeset only throws on failure - it does not commit or abandon changes itself. Since the first\n // row's change didn't conflict, it may already have been applied to the current transaction by the time\n // the second row's conflict causes the throw.\n expect(() => target.applyChangeset(changesetFileName)).throws();\n expect(readRows(target, \"test1\")).deep.equal([{ id: 1, val: \"fromSource1\" }, { id: 2, val: \"fromTarget2\" }]);\n\n // it is the caller's responsibility to abandon (or save) the partially-applied changes after catching the error\n target.abandonChanges();\n expect(readRows(target, \"test1\")).deep.equal([{ id: 1, val: \"base1\" }, { id: 2, val: \"fromTarget2\" }]);\n\n target.closeDb();\n });\n });\n\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itwin/core-backend",
|
|
3
|
-
"version": "5.12.0-dev.
|
|
3
|
+
"version": "5.12.0-dev.13",
|
|
4
4
|
"description": "iTwin.js backend components",
|
|
5
5
|
"main": "lib/cjs/core-backend.js",
|
|
6
6
|
"module": "lib/esm/core-backend.js",
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
29
|
"@opentelemetry/api": "^1.0.4",
|
|
30
|
-
"@itwin/core-
|
|
31
|
-
"@itwin/
|
|
32
|
-
"@itwin/core-
|
|
33
|
-
"@itwin/
|
|
30
|
+
"@itwin/core-common": "5.12.0-dev.13",
|
|
31
|
+
"@itwin/core-bentley": "5.12.0-dev.13",
|
|
32
|
+
"@itwin/core-geometry": "5.12.0-dev.13",
|
|
33
|
+
"@itwin/ecschema-metadata": "5.12.0-dev.13"
|
|
34
34
|
},
|
|
35
35
|
"peerDependenciesMeta": {
|
|
36
36
|
"@opentelemetry/api": {
|
|
@@ -77,17 +77,17 @@
|
|
|
77
77
|
"marked": "^14.1.3",
|
|
78
78
|
"sql-formatter": "^15.4.6",
|
|
79
79
|
"webpack": "^5.97.1",
|
|
80
|
-
"@itwin/build-tools": "5.12.0-dev.
|
|
81
|
-
"@itwin/
|
|
82
|
-
"@itwin/core-bentley": "5.12.0-dev.
|
|
83
|
-
"@itwin/
|
|
84
|
-
"@itwin/
|
|
85
|
-
"@itwin/core-geometry": "5.12.0-dev.11",
|
|
80
|
+
"@itwin/build-tools": "5.12.0-dev.13",
|
|
81
|
+
"@itwin/ecschema-locaters": "5.12.0-dev.13",
|
|
82
|
+
"@itwin/core-bentley": "5.12.0-dev.13",
|
|
83
|
+
"@itwin/ecschema-metadata": "5.12.0-dev.13",
|
|
84
|
+
"@itwin/core-common": "5.12.0-dev.13",
|
|
86
85
|
"internal-tools": "3.0.0-dev.69",
|
|
87
|
-
"@itwin/
|
|
86
|
+
"@itwin/ecsql-common": "5.12.0-dev.13",
|
|
87
|
+
"@itwin/core-geometry": "5.12.0-dev.13"
|
|
88
88
|
},
|
|
89
89
|
"dependencies": {
|
|
90
|
-
"@bentley/imodeljs-native": "5.12.
|
|
90
|
+
"@bentley/imodeljs-native": "5.12.18",
|
|
91
91
|
"@itwin/object-storage-azure": "^3.0.4",
|
|
92
92
|
"@azure/storage-blob": "^12.28.0",
|
|
93
93
|
"form-data": "^4.0.6",
|