@itwin/core-backend 5.14.0-dev.2 → 5.14.0-dev.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/lib/cjs/BriefcaseManager.d.ts.map +1 -1
  2. package/lib/cjs/BriefcaseManager.js +11 -5
  3. package/lib/cjs/BriefcaseManager.js.map +1 -1
  4. package/lib/cjs/CloudSqlite.d.ts.map +1 -1
  5. package/lib/cjs/CloudSqlite.js +9 -2
  6. package/lib/cjs/CloudSqlite.js.map +1 -1
  7. package/lib/cjs/ECDb.d.ts.map +1 -1
  8. package/lib/cjs/ECDb.js +1 -0
  9. package/lib/cjs/ECDb.js.map +1 -1
  10. package/lib/cjs/IModelDb.d.ts +42 -7
  11. package/lib/cjs/IModelDb.d.ts.map +1 -1
  12. package/lib/cjs/IModelDb.js +175 -74
  13. package/lib/cjs/IModelDb.js.map +1 -1
  14. package/lib/cjs/SchemaSync.d.ts +126 -18
  15. package/lib/cjs/SchemaSync.d.ts.map +1 -1
  16. package/lib/cjs/SchemaSync.js +303 -81
  17. package/lib/cjs/SchemaSync.js.map +1 -1
  18. package/lib/cjs/TxnManager.d.ts.map +1 -1
  19. package/lib/cjs/TxnManager.js +2 -5
  20. package/lib/cjs/TxnManager.js.map +1 -1
  21. package/lib/cjs/internal/SchemaSyncReservations.d.ts.map +1 -1
  22. package/lib/cjs/internal/SchemaSyncReservations.js +13 -3
  23. package/lib/cjs/internal/SchemaSyncReservations.js.map +1 -1
  24. package/lib/esm/BriefcaseManager.d.ts.map +1 -1
  25. package/lib/esm/BriefcaseManager.js +11 -5
  26. package/lib/esm/BriefcaseManager.js.map +1 -1
  27. package/lib/esm/CloudSqlite.d.ts.map +1 -1
  28. package/lib/esm/CloudSqlite.js +10 -3
  29. package/lib/esm/CloudSqlite.js.map +1 -1
  30. package/lib/esm/ECDb.d.ts.map +1 -1
  31. package/lib/esm/ECDb.js +1 -0
  32. package/lib/esm/ECDb.js.map +1 -1
  33. package/lib/esm/IModelDb.d.ts +42 -7
  34. package/lib/esm/IModelDb.d.ts.map +1 -1
  35. package/lib/esm/IModelDb.js +175 -74
  36. package/lib/esm/IModelDb.js.map +1 -1
  37. package/lib/esm/SchemaSync.d.ts +126 -18
  38. package/lib/esm/SchemaSync.d.ts.map +1 -1
  39. package/lib/esm/SchemaSync.js +304 -82
  40. package/lib/esm/SchemaSync.js.map +1 -1
  41. package/lib/esm/TxnManager.d.ts.map +1 -1
  42. package/lib/esm/TxnManager.js +2 -5
  43. package/lib/esm/TxnManager.js.map +1 -1
  44. package/lib/esm/internal/SchemaSyncReservations.d.ts.map +1 -1
  45. package/lib/esm/internal/SchemaSyncReservations.js +13 -3
  46. package/lib/esm/internal/SchemaSyncReservations.js.map +1 -1
  47. package/lib/esm/test/hubaccess/Rebase.test.js +3 -1
  48. package/lib/esm/test/hubaccess/Rebase.test.js.map +1 -1
  49. package/lib/esm/test/hubaccess/SemanticRebase.test.js +29 -28
  50. package/lib/esm/test/hubaccess/SemanticRebase.test.js.map +1 -1
  51. package/lib/esm/test/hubaccess/SemanticRebaseTestUtils.d.ts +3 -0
  52. package/lib/esm/test/hubaccess/SemanticRebaseTestUtils.d.ts.map +1 -0
  53. package/lib/esm/test/hubaccess/SemanticRebaseTestUtils.js +15 -0
  54. package/lib/esm/test/hubaccess/SemanticRebaseTestUtils.js.map +1 -0
  55. package/lib/esm/test/standalone/SchemaSyncDb.test.js +5 -25
  56. package/lib/esm/test/standalone/SchemaSyncDb.test.js.map +1 -1
  57. package/lib/esm/test/standalone/SchemaSyncElementReservation.test.js +1 -0
  58. package/lib/esm/test/standalone/SchemaSyncElementReservation.test.js.map +1 -1
  59. package/package.json +13 -13
@@ -0,0 +1,3 @@
1
+ export declare const semanticRebaseExtendedDescribe: Mocha.PendingSuiteFunction;
2
+ export declare const semanticRebaseExtendedIt: Mocha.PendingTestFunction;
3
+ //# sourceMappingURL=SemanticRebaseTestUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SemanticRebaseTestUtils.d.ts","sourceRoot":"","sources":["../../../../src/test/hubaccess/SemanticRebaseTestUtils.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,8BAA8B,4BAAgE,CAAC;AAC5G,eAAO,MAAM,wBAAwB,2BAAoD,CAAC"}
@@ -0,0 +1,15 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ /**
6
+ * The extended semantic rebase tests are opt-in because they repeat the core workflows across
7
+ * many schema, data, transaction, and briefcase arrangements.
8
+ */
9
+ const semanticRebaseExtendedTestsEnabled = (() => {
10
+ const setting = process.env.ITWIN_INCLUDE_SEMANTIC_REBASE_EXTENDED_TESTS?.trim().toLowerCase();
11
+ return setting === "1" || setting === "true" || setting === "yes";
12
+ })();
13
+ export const semanticRebaseExtendedDescribe = semanticRebaseExtendedTestsEnabled ? describe : describe.skip;
14
+ export const semanticRebaseExtendedIt = semanticRebaseExtendedTestsEnabled ? it : it.skip;
15
+ //# sourceMappingURL=SemanticRebaseTestUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SemanticRebaseTestUtils.js","sourceRoot":"","sources":["../../../../src/test/hubaccess/SemanticRebaseTestUtils.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAE/F;;;GAGG;AACH,MAAM,kCAAkC,GAAG,CAAC,GAAG,EAAE;IAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,4CAA4C,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/F,OAAO,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,KAAK,CAAC;AACpE,CAAC,CAAC,EAAE,CAAC;AAEL,MAAM,CAAC,MAAM,8BAA8B,GAAG,kCAAkC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC5G,MAAM,CAAC,MAAM,wBAAwB,GAAG,kCAAkC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/**\r\n * The extended semantic rebase tests are opt-in because they repeat the core workflows across\r\n * many schema, data, transaction, and briefcase arrangements.\r\n */\r\nconst semanticRebaseExtendedTestsEnabled = (() => {\r\n const setting = process.env.ITWIN_INCLUDE_SEMANTIC_REBASE_EXTENDED_TESTS?.trim().toLowerCase();\r\n return setting === \"1\" || setting === \"true\" || setting === \"yes\";\r\n})();\r\n\r\nexport const semanticRebaseExtendedDescribe = semanticRebaseExtendedTestsEnabled ? describe : describe.skip;\r\nexport const semanticRebaseExtendedIt = semanticRebaseExtendedTestsEnabled ? it : it.skip;\r\n"]}
@@ -2,7 +2,7 @@
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
- import { DbResult, Guid, Id64, OpenMode } from "@itwin/core-bentley";
5
+ import { Guid, Id64, OpenMode } from "@itwin/core-bentley";
6
6
  import { BriefcaseIdValue, Code, ElementReservationError } from "@itwin/core-common";
7
7
  import { expect } from "chai";
8
8
  import { IModelJsFs, SchemaSync } from "../../core-backend";
@@ -33,12 +33,7 @@ describe("SchemaSyncDb", () => {
33
33
  schemaDb.closeDb();
34
34
  IModelJsFs.removeSync(schemaDbFileName);
35
35
  });
36
- // This is a little gross, but the easiest way to test upgrading from v4.0
37
- function simulatePreviousDbSchema() {
38
- let res = schemaDb.executeSQL("DROP TABLE reserved_elements");
39
- expect(res).to.equal(DbResult.BE_SQLITE_DONE);
40
- res = schemaDb.executeSQL("DELETE FROM be_Prop WHERE namespace='schemasync'");
41
- expect(res).to.equal(DbResult.BE_SQLITE_DONE);
36
+ function simulateVersion4Db() {
42
37
  schemaDb.setRequiredVersions({ readVersion: "^4.0.0", writeVersion: "^4.0.0" });
43
38
  schemaDb.saveChanges();
44
39
  }
@@ -74,25 +69,10 @@ describe("SchemaSyncDb", () => {
74
69
  const elementIdCol = cols.find((c) => c.name === "elementId");
75
70
  expect(elementIdCol.notnull).to.equal(1);
76
71
  });
77
- it("lazily updates to new schema just before reserving elements", async () => {
78
- simulatePreviousDbSchema();
72
+ it("refuses a database from the previous major version", () => {
73
+ simulateVersion4Db();
79
74
  schemaDb.closeDb();
80
- schemaDb.openDb(schemaDbFileName, OpenMode.ReadWrite);
81
- expect(getTableInfo("reserved_elements")).to.be.empty;
82
- expect(readNextLocalId()).to.equal(1);
83
- let version = schemaDb.getRequiredVersions();
84
- expect(version.readVersion).to.equal("^4.0.0");
85
- expect(version.writeVersion).to.equal("^4.0.0");
86
- await schemaDb.reserveElements([{
87
- federationGuid: Guid.createValue(),
88
- ecClassId: "0x1",
89
- code: Code.fromJSON({ spec: "0x1", scope: "0x2", value: "foo" })
90
- }]);
91
- expect(getTableInfo("reserved_elements")).to.not.be.empty;
92
- expect(readNextLocalId()).to.equal(2);
93
- version = schemaDb.getRequiredVersions();
94
- expect(version.readVersion).to.equal("^4.1.0");
95
- expect(version.writeVersion).to.equal("^4.1.0");
75
+ expect(() => schemaDb.openDb(schemaDbFileName, OpenMode.ReadWrite)).to.throw();
96
76
  });
97
77
  });
98
78
  describe("reserveElements", () => {
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaSyncDb.test.js","sourceRoot":"","sources":["../../../../src/test/standalone/SchemaSyncDb.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { DbResult, Guid, Id64, OpenMode } from \"@itwin/core-bentley\";\r\nimport { BriefcaseIdValue, Code, ElementReservationError } from \"@itwin/core-common\";\r\nimport { expect } from \"chai\";\r\nimport { IModelJsFs, SchemaSync } from \"../../core-backend\";\r\nimport { _nativeDb } from \"../../internal/Symbols\";\r\nimport { IModelTestUtils } from \"../IModelTestUtils\";\r\n\r\n/** Assert that `promise` rejects with an `ElementReservationError` carrying the given key. */\r\nasync function expectReservationError(promise: Promise<unknown>, key: ElementReservationError.Key): Promise<void> {\r\n try {\r\n await promise;\r\n } catch (err) {\r\n expect(ElementReservationError.isError(err, key), `expected ElementReservationError '${key}', got: ${JSON.stringify(err)}`).to.be.true;\r\n return;\r\n }\r\n expect.fail(`expected promise to reject with ElementReservationError '${key}'`);\r\n}\r\n\r\ndescribe(\"SchemaSyncDb\", () => {\r\n let schemaDb: SchemaSync.SchemaSyncDb;\r\n let schemaDbFileName: string;\r\n\r\n beforeEach(() => {\r\n schemaDbFileName = IModelTestUtils.prepareOutputFile(\"SchemaSyncDb\", \"schema-sync.db\");\r\n SchemaSync.SchemaSyncDb.createNewDb(schemaDbFileName);\r\n schemaDb = new SchemaSync.SchemaSyncDb();\r\n schemaDb.openDb(schemaDbFileName, OpenMode.ReadWrite);\r\n });\r\n\r\n afterEach(() => {\r\n if (schemaDb.isOpen)\r\n schemaDb.closeDb();\r\n IModelJsFs.removeSync(schemaDbFileName);\r\n });\r\n\r\n // This is a little gross, but the easiest way to test upgrading from v4.0\r\n function simulatePreviousDbSchema() {\r\n let res = schemaDb.executeSQL(\"DROP TABLE reserved_elements\");\r\n expect(res).to.equal(DbResult.BE_SQLITE_DONE);\r\n res = schemaDb.executeSQL(\"DELETE FROM be_Prop WHERE namespace='schemasync'\");\r\n expect(res).to.equal(DbResult.BE_SQLITE_DONE);\r\n schemaDb.setRequiredVersions({ readVersion: \"^4.0.0\", writeVersion: \"^4.0.0\" });\r\n schemaDb.saveChanges();\r\n }\r\n\r\n function getTableInfo(tableName: string) {\r\n return schemaDb.withSqliteStatement(`PRAGMA table_info(${tableName})`, (stmt) => {\r\n const rows: Array<{ name: string, type: string, notnull: number }> = [];\r\n while (stmt.nextRow())\r\n rows.push({ name: stmt.getValueString(1), type: stmt.getValueString(2), notnull: stmt.getValueInteger(3) });\r\n return rows;\r\n });\r\n }\r\n\r\n function readReservedRows(): Array<{ federationGuid: string, elementId: string, ecClassId: string, codeValue: string }> {\r\n return schemaDb.withSqliteStatement(\r\n \"SELECT federationGuid, elementId, ecClassId, codeValue FROM reserved_elements ORDER BY elementId\",\r\n (stmt) => {\r\n const rows: Array<{ federationGuid: string, elementId: string, ecClassId: string, codeValue: string }> = [];\r\n while (stmt.nextRow()) {\r\n rows.push({\r\n federationGuid: stmt.getValueGuid(0),\r\n elementId: stmt.getValueId(1),\r\n ecClassId: stmt.getValueId(2),\r\n codeValue: stmt.getValueString(3),\r\n });\r\n }\r\n return rows;\r\n },\r\n );\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/dot-notation\r\n const readNextLocalId = () => schemaDb[\"getNextReservedElementLocalId\"]();\r\n\r\n describe(\"schema\", () => {\r\n it(\"creates the reserved_elements table with elementId NOT NULL UNIQUE\", () => {\r\n const cols = getTableInfo(\"reserved_elements\");\r\n const names = cols.map((c) => c.name).sort();\r\n expect(names).to.deep.equal([\"codeScope\", \"codeSpecId\", \"codeValue\", \"ecClassId\", \"elementId\", \"federationGuid\"]);\r\n const elementIdCol = cols.find((c) => c.name === \"elementId\")!;\r\n expect(elementIdCol.notnull).to.equal(1);\r\n });\r\n\r\n it(\"lazily updates to new schema just before reserving elements\", async () => {\r\n simulatePreviousDbSchema();\r\n schemaDb.closeDb();\r\n schemaDb.openDb(schemaDbFileName, OpenMode.ReadWrite);\r\n\r\n expect(getTableInfo(\"reserved_elements\")).to.be.empty;\r\n expect(readNextLocalId()).to.equal(1);\r\n let version = schemaDb.getRequiredVersions();\r\n expect(version.readVersion).to.equal(\"^4.0.0\");\r\n expect(version.writeVersion).to.equal(\"^4.0.0\");\r\n\r\n await schemaDb.reserveElements([{\r\n federationGuid: Guid.createValue(),\r\n ecClassId: \"0x1\",\r\n code: Code.fromJSON({ spec: \"0x1\", scope: \"0x2\", value: \"foo\" })\r\n }]);\r\n\r\n expect(getTableInfo(\"reserved_elements\")).to.not.be.empty;\r\n expect(readNextLocalId()).to.equal(2);\r\n version = schemaDb.getRequiredVersions();\r\n expect(version.readVersion).to.equal(\"^4.1.0\");\r\n expect(version.writeVersion).to.equal(\"^4.1.0\");\r\n });\r\n });\r\n\r\n describe(\"reserveElements\", () => {\r\n function makeReservation(federationGuid: string, codeValue: string, ecClassId = \"0x1\"): SchemaSync.ProposedElementReservation {\r\n return {\r\n federationGuid,\r\n ecClassId,\r\n code: Code.fromJSON({ spec: \"0x1\", scope: \"0x2\", value: codeValue }),\r\n };\r\n }\r\n\r\n it(\"throws when nextReservedElementLocalId file property is corrupt\", async () => {\r\n for (const corruptValue of [\"abc\", \"0\", \"-1\", \"1.5\"]) {\r\n schemaDb[_nativeDb].saveFileProperty({ namespace: \"schemasync\", name: \"nextReservedElementLocalId\" }, corruptValue);\r\n schemaDb.saveChanges();\r\n\r\n await expectReservationError(schemaDb.reserveElements([\r\n makeReservation(Guid.createValue(), \"cat\"),\r\n ]), \"corrupt-reservation-data\");\r\n }\r\n });\r\n\r\n it(\"rejects duplicate non-empty code values across different federation guids\", async () => {\r\n await expect(schemaDb.reserveElements([\r\n makeReservation(Guid.createValue(), \"Cat-X\"),\r\n makeReservation(Guid.createValue(), \"Cat-X\"),\r\n ])).to.be.rejected;\r\n });\r\n\r\n it(\"treats code values case-insensitively when enforcing uniqueness\", async () => {\r\n await expect(schemaDb.reserveElements([\r\n makeReservation(Guid.createValue(), \"Cat-A\"),\r\n makeReservation(Guid.createValue(), \"cat-a\"),\r\n ])).to.be.rejected;\r\n });\r\n\r\n it(\"persists local-id counter across reserve calls\", async () => {\r\n await schemaDb.reserveElements([\r\n makeReservation(Guid.createValue(), \"Cat-A\"),\r\n ]);\r\n expect(readNextLocalId()).to.equal(2);\r\n\r\n await schemaDb.reserveElements([\r\n makeReservation(Guid.createValue(), \"Cat-B\"),\r\n ]);\r\n expect(readNextLocalId()).to.equal(3);\r\n });\r\n\r\n it(\"allocates the elementId using the SchemaSyncElementReserved briefcase id\", async () => {\r\n await schemaDb.reserveElements([makeReservation(Guid.createValue(), \"Cat-A\")]);\r\n const elementId = readReservedRows()[0].elementId;\r\n expect(elementId).to.equal(Id64.fromLocalAndBriefcaseIds(1, BriefcaseIdValue.SchemaSyncElementReserved));\r\n expect(Id64.getBriefcaseId(elementId)).to.equal(BriefcaseIdValue.SchemaSyncElementReserved);\r\n expect(Id64.getLocalId(elementId)).to.equal(1);\r\n });\r\n\r\n it(\"assigns sequential local Ids for a batch\", async () => {\r\n await schemaDb.reserveElements([\r\n makeReservation(Guid.createValue(), \"Cat-A\"),\r\n makeReservation(Guid.createValue(), \"Cat-B\"),\r\n makeReservation(Guid.createValue(), \"Cat-C\"),\r\n ]);\r\n const rows = readReservedRows();\r\n expect(rows).to.have.lengthOf(3);\r\n expect(rows.map((r) => Id64.getLocalId(r.elementId))).to.deep.equal([1, 2, 3]);\r\n expect(readNextLocalId()).to.equal(4);\r\n });\r\n\r\n it(\"is idempotent within a single call (duplicate element props)\", async () => {\r\n const federationGuid = Guid.createValue();\r\n await schemaDb.reserveElements([\r\n makeReservation(federationGuid, \"Cat-A\"),\r\n makeReservation(federationGuid, \"Cat-A\"),\r\n ]);\r\n expect(readReservedRows()).to.have.lengthOf(1);\r\n expect(readNextLocalId()).to.equal(2);\r\n });\r\n\r\n it(\"is idempotent across calls (returns existing id, allocates no new row)\", async () => {\r\n const federationGuid = Guid.createValue();\r\n await schemaDb.reserveElements([makeReservation(federationGuid, \"Cat-A\")]);\r\n const firstId = readReservedRows()[0].elementId;\r\n\r\n await schemaDb.reserveElements([makeReservation(federationGuid, \"Cat-A\")]);\r\n expect(readReservedRows()).to.have.lengthOf(1);\r\n expect(readReservedRows()[0].elementId).to.equal(firstId);\r\n expect(readNextLocalId()).to.equal(2);\r\n });\r\n\r\n it(\"allows multiple identities with empty codes to coexist\", async () => {\r\n await schemaDb.reserveElements([\r\n makeReservation(Guid.createValue(), \"\"),\r\n makeReservation(Guid.createValue(), \"\"),\r\n makeReservation(Guid.createValue(), \"\"),\r\n ]);\r\n const rows = readReservedRows();\r\n expect(rows).to.have.lengthOf(3);\r\n expect(new Set(rows.map((r) => r.elementId)).size).to.equal(3);\r\n });\r\n\r\n it(\"throws when an existing reservation has a different class\", async () => {\r\n const federationGuid = Guid.createValue();\r\n await schemaDb.reserveElements([makeReservation(federationGuid, \"Cat-A\", \"0x1\")]);\r\n await expectReservationError(schemaDb.reserveElements([\r\n makeReservation(federationGuid, \"Cat-A\", \"0x2\"),\r\n ]), \"reservation-conflict\");\r\n });\r\n\r\n it(\"throws when federationGuid and code resolve to different existing rows\", async () => {\r\n const federationGuidA = Guid.createValue();\r\n const federationGuidB = Guid.createValue();\r\n await schemaDb.reserveElements([\r\n makeReservation(federationGuidA, \"Cat-A\"),\r\n makeReservation(federationGuidB, \"Cat-B\"),\r\n ]);\r\n // fedGuid lookup returns the A row, code lookup returns the B row.\r\n await expectReservationError(schemaDb.reserveElements([\r\n makeReservation(federationGuidA, \"Cat-B\"),\r\n ]), \"reservation-conflict\");\r\n });\r\n\r\n it(\"throws when the local-id sequence is exhausted\", async () => {\r\n // eslint-disable-next-line @typescript-eslint/dot-notation\r\n schemaDb[\"setNextReservedElementLocalId\"](Math.pow(2, 40) - 2); // Seed counter near the 2^40 ceiling.\r\n schemaDb.saveChanges();\r\n await expectReservationError(schemaDb.reserveElements([\r\n makeReservation(Guid.createValue(), \"Cat-A\"),\r\n makeReservation(Guid.createValue(), \"Cat-B\"),\r\n makeReservation(Guid.createValue(), \"Cat-C\"),\r\n ]), \"id-sequence-exhausted\");\r\n expect(readReservedRows()).to.be.empty;\r\n });\r\n\r\n it(\"throws when a federationGuid is missing\", async () => {\r\n await expectReservationError(schemaDb.reserveElements([\r\n { ecClassId: \"0x1\", code: Code.fromJSON({ spec: \"0x1\", scope: \"0x2\", value: \"Cat-A\" }) } as any,\r\n ]), \"invalid-reservation\");\r\n expect(readReservedRows()).to.be.empty;\r\n });\r\n });\r\n});\r\n"]}
1
+ {"version":3,"file":"SchemaSyncDb.test.js","sourceRoot":"","sources":["../../../../src/test/standalone/SchemaSyncDb.test.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAE/F,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,8FAA8F;AAC9F,KAAK,UAAU,sBAAsB,CAAC,OAAyB,EAAE,GAAgC;IAC/F,IAAI,CAAC;QACH,MAAM,OAAO,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,uBAAuB,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,qCAAqC,GAAG,WAAW,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QACvI,OAAO;IACT,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,4DAA4D,GAAG,GAAG,CAAC,CAAC;AAClF,CAAC;AAED,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,IAAI,QAAiC,CAAC;IACtC,IAAI,gBAAwB,CAAC;IAE7B,UAAU,CAAC,GAAG,EAAE;QACd,gBAAgB,GAAG,eAAe,CAAC,iBAAiB,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;QACvF,UAAU,CAAC,YAAY,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;QACtD,QAAQ,GAAG,IAAI,UAAU,CAAC,YAAY,EAAE,CAAC;QACzC,QAAQ,CAAC,MAAM,CAAC,gBAAgB,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,QAAQ,CAAC,MAAM;YACjB,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrB,UAAU,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,SAAS,kBAAkB;QACzB,QAAQ,CAAC,mBAAmB,CAAC,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC;QAChF,QAAQ,CAAC,WAAW,EAAE,CAAC;IACzB,CAAC;IAED,SAAS,YAAY,CAAC,SAAiB;QACrC,OAAO,QAAQ,CAAC,mBAAmB,CAAC,qBAAqB,SAAS,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE;YAC9E,MAAM,IAAI,GAA2D,EAAE,CAAC;YACxE,OAAO,IAAI,CAAC,OAAO,EAAE;gBACnB,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC9G,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS,gBAAgB;QACvB,OAAO,QAAQ,CAAC,mBAAmB,CACjC,kGAAkG,EAClG,CAAC,IAAI,EAAE,EAAE;YACP,MAAM,IAAI,GAA+F,EAAE,CAAC;YAC5G,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;gBACtB,IAAI,CAAC,IAAI,CAAC;oBACR,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;oBACpC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;oBAC7B,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;oBAC7B,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;iBAClC,CAAC,CAAC;YACL,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CACF,CAAC;IACJ,CAAC;IAED,2DAA2D;IAC3D,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC,EAAE,CAAC;IAE1E,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;YAC5E,MAAM,IAAI,GAAG,YAAY,CAAC,mBAAmB,CAAC,CAAC;YAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YAC7C,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,CAAC,CAAC,CAAC;YAClH,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAE,CAAC;YAC/D,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,kBAAkB,EAAE,CAAC;YACrB,QAAQ,CAAC,OAAO,EAAE,CAAC;YAEnB,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,gBAAgB,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QACjF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,SAAS,eAAe,CAAC,cAAsB,EAAE,SAAiB,EAAE,SAAS,GAAG,KAAK;YACnF,OAAO;gBACL,cAAc;gBACd,SAAS;gBACT,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;aACrE,CAAC;QACJ,CAAC;QAED,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;YAC/E,KAAK,MAAM,YAAY,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;gBACrD,QAAQ,CAAC,SAAS,CAAC,CAAC,gBAAgB,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,4BAA4B,EAAE,EAAE,YAAY,CAAC,CAAC;gBACpH,QAAQ,CAAC,WAAW,EAAE,CAAC;gBAEvB,MAAM,sBAAsB,CAAC,QAAQ,CAAC,eAAe,CAAC;oBACpD,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC;iBAC3C,CAAC,EAAE,0BAA0B,CAAC,CAAC;YAClC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2EAA2E,EAAE,KAAK,IAAI,EAAE;YACzF,MAAM,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC;gBACpC,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC;gBAC5C,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC;aAC7C,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;YAC/E,MAAM,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC;gBACpC,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC;gBAC5C,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC;aAC7C,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,QAAQ,CAAC,eAAe,CAAC;gBAC7B,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC;aAC7C,CAAC,CAAC;YACH,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAEtC,MAAM,QAAQ,CAAC,eAAe,CAAC;gBAC7B,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC;aAC7C,CAAC,CAAC;YACH,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;YACxF,MAAM,QAAQ,CAAC,eAAe,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;YAC/E,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAClD,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,EAAE,gBAAgB,CAAC,yBAAyB,CAAC,CAAC,CAAC;YACzG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,yBAAyB,CAAC,CAAC;YAC5F,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,QAAQ,CAAC,eAAe,CAAC;gBAC7B,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC;gBAC5C,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC;gBAC5C,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC;aAC7C,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC/E,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;YAC5E,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YAC1C,MAAM,QAAQ,CAAC,eAAe,CAAC;gBAC7B,eAAe,CAAC,cAAc,EAAE,OAAO,CAAC;gBACxC,eAAe,CAAC,cAAc,EAAE,OAAO,CAAC;aACzC,CAAC,CAAC;YACH,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC/C,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;YACtF,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YAC1C,MAAM,QAAQ,CAAC,eAAe,CAAC,CAAC,eAAe,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;YAC3E,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAEhD,MAAM,QAAQ,CAAC,eAAe,CAAC,CAAC,eAAe,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;YAC3E,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC/C,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC1D,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;YACtE,MAAM,QAAQ,CAAC,eAAe,CAAC;gBAC7B,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC;gBACvC,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC;gBACvC,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC;aACxC,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;YACzE,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YAC1C,MAAM,QAAQ,CAAC,eAAe,CAAC,CAAC,eAAe,CAAC,cAAc,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;YAClF,MAAM,sBAAsB,CAAC,QAAQ,CAAC,eAAe,CAAC;gBACpD,eAAe,CAAC,cAAc,EAAE,OAAO,EAAE,KAAK,CAAC;aAChD,CAAC,EAAE,sBAAsB,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;YACtF,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3C,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3C,MAAM,QAAQ,CAAC,eAAe,CAAC;gBAC7B,eAAe,CAAC,eAAe,EAAE,OAAO,CAAC;gBACzC,eAAe,CAAC,eAAe,EAAE,OAAO,CAAC;aAC1C,CAAC,CAAC;YACH,mEAAmE;YACnE,MAAM,sBAAsB,CAAC,QAAQ,CAAC,eAAe,CAAC;gBACpD,eAAe,CAAC,eAAe,EAAE,OAAO,CAAC;aAC1C,CAAC,EAAE,sBAAsB,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,2DAA2D;YAC3D,QAAQ,CAAC,+BAA+B,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,sCAAsC;YACtG,QAAQ,CAAC,WAAW,EAAE,CAAC;YACvB,MAAM,sBAAsB,CAAC,QAAQ,CAAC,eAAe,CAAC;gBACpD,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC;gBAC5C,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC;gBAC5C,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC;aAC7C,CAAC,EAAE,uBAAuB,CAAC,CAAC;YAC7B,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACvD,MAAM,sBAAsB,CAAC,QAAQ,CAAC,eAAe,CAAC;gBACpD,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAS;aAChG,CAAC,EAAE,qBAAqB,CAAC,CAAC;YAC3B,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { Guid, Id64, OpenMode } from \"@itwin/core-bentley\";\r\nimport { BriefcaseIdValue, Code, ElementReservationError } from \"@itwin/core-common\";\r\nimport { expect } from \"chai\";\r\nimport { IModelJsFs, SchemaSync } from \"../../core-backend\";\r\nimport { _nativeDb } from \"../../internal/Symbols\";\r\nimport { IModelTestUtils } from \"../IModelTestUtils\";\r\n\r\n/** Assert that `promise` rejects with an `ElementReservationError` carrying the given key. */\r\nasync function expectReservationError(promise: Promise<unknown>, key: ElementReservationError.Key): Promise<void> {\r\n try {\r\n await promise;\r\n } catch (err) {\r\n expect(ElementReservationError.isError(err, key), `expected ElementReservationError '${key}', got: ${JSON.stringify(err)}`).to.be.true;\r\n return;\r\n }\r\n expect.fail(`expected promise to reject with ElementReservationError '${key}'`);\r\n}\r\n\r\ndescribe(\"SchemaSyncDb\", () => {\r\n let schemaDb: SchemaSync.SchemaSyncDb;\r\n let schemaDbFileName: string;\r\n\r\n beforeEach(() => {\r\n schemaDbFileName = IModelTestUtils.prepareOutputFile(\"SchemaSyncDb\", \"schema-sync.db\");\r\n SchemaSync.SchemaSyncDb.createNewDb(schemaDbFileName);\r\n schemaDb = new SchemaSync.SchemaSyncDb();\r\n schemaDb.openDb(schemaDbFileName, OpenMode.ReadWrite);\r\n });\r\n\r\n afterEach(() => {\r\n if (schemaDb.isOpen)\r\n schemaDb.closeDb();\r\n IModelJsFs.removeSync(schemaDbFileName);\r\n });\r\n\r\n function simulateVersion4Db() {\r\n schemaDb.setRequiredVersions({ readVersion: \"^4.0.0\", writeVersion: \"^4.0.0\" });\r\n schemaDb.saveChanges();\r\n }\r\n\r\n function getTableInfo(tableName: string) {\r\n return schemaDb.withSqliteStatement(`PRAGMA table_info(${tableName})`, (stmt) => {\r\n const rows: Array<{ name: string, type: string, notnull: number }> = [];\r\n while (stmt.nextRow())\r\n rows.push({ name: stmt.getValueString(1), type: stmt.getValueString(2), notnull: stmt.getValueInteger(3) });\r\n return rows;\r\n });\r\n }\r\n\r\n function readReservedRows(): Array<{ federationGuid: string, elementId: string, ecClassId: string, codeValue: string }> {\r\n return schemaDb.withSqliteStatement(\r\n \"SELECT federationGuid, elementId, ecClassId, codeValue FROM reserved_elements ORDER BY elementId\",\r\n (stmt) => {\r\n const rows: Array<{ federationGuid: string, elementId: string, ecClassId: string, codeValue: string }> = [];\r\n while (stmt.nextRow()) {\r\n rows.push({\r\n federationGuid: stmt.getValueGuid(0),\r\n elementId: stmt.getValueId(1),\r\n ecClassId: stmt.getValueId(2),\r\n codeValue: stmt.getValueString(3),\r\n });\r\n }\r\n return rows;\r\n },\r\n );\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/dot-notation\r\n const readNextLocalId = () => schemaDb[\"getNextReservedElementLocalId\"]();\r\n\r\n describe(\"schema\", () => {\r\n it(\"creates the reserved_elements table with elementId NOT NULL UNIQUE\", () => {\r\n const cols = getTableInfo(\"reserved_elements\");\r\n const names = cols.map((c) => c.name).sort();\r\n expect(names).to.deep.equal([\"codeScope\", \"codeSpecId\", \"codeValue\", \"ecClassId\", \"elementId\", \"federationGuid\"]);\r\n const elementIdCol = cols.find((c) => c.name === \"elementId\")!;\r\n expect(elementIdCol.notnull).to.equal(1);\r\n });\r\n\r\n it(\"refuses a database from the previous major version\", () => {\r\n simulateVersion4Db();\r\n schemaDb.closeDb();\r\n\r\n expect(() => schemaDb.openDb(schemaDbFileName, OpenMode.ReadWrite)).to.throw();\r\n });\r\n });\r\n\r\n describe(\"reserveElements\", () => {\r\n function makeReservation(federationGuid: string, codeValue: string, ecClassId = \"0x1\"): SchemaSync.ProposedElementReservation {\r\n return {\r\n federationGuid,\r\n ecClassId,\r\n code: Code.fromJSON({ spec: \"0x1\", scope: \"0x2\", value: codeValue }),\r\n };\r\n }\r\n\r\n it(\"throws when nextReservedElementLocalId file property is corrupt\", async () => {\r\n for (const corruptValue of [\"abc\", \"0\", \"-1\", \"1.5\"]) {\r\n schemaDb[_nativeDb].saveFileProperty({ namespace: \"schemasync\", name: \"nextReservedElementLocalId\" }, corruptValue);\r\n schemaDb.saveChanges();\r\n\r\n await expectReservationError(schemaDb.reserveElements([\r\n makeReservation(Guid.createValue(), \"cat\"),\r\n ]), \"corrupt-reservation-data\");\r\n }\r\n });\r\n\r\n it(\"rejects duplicate non-empty code values across different federation guids\", async () => {\r\n await expect(schemaDb.reserveElements([\r\n makeReservation(Guid.createValue(), \"Cat-X\"),\r\n makeReservation(Guid.createValue(), \"Cat-X\"),\r\n ])).to.be.rejected;\r\n });\r\n\r\n it(\"treats code values case-insensitively when enforcing uniqueness\", async () => {\r\n await expect(schemaDb.reserveElements([\r\n makeReservation(Guid.createValue(), \"Cat-A\"),\r\n makeReservation(Guid.createValue(), \"cat-a\"),\r\n ])).to.be.rejected;\r\n });\r\n\r\n it(\"persists local-id counter across reserve calls\", async () => {\r\n await schemaDb.reserveElements([\r\n makeReservation(Guid.createValue(), \"Cat-A\"),\r\n ]);\r\n expect(readNextLocalId()).to.equal(2);\r\n\r\n await schemaDb.reserveElements([\r\n makeReservation(Guid.createValue(), \"Cat-B\"),\r\n ]);\r\n expect(readNextLocalId()).to.equal(3);\r\n });\r\n\r\n it(\"allocates the elementId using the SchemaSyncElementReserved briefcase id\", async () => {\r\n await schemaDb.reserveElements([makeReservation(Guid.createValue(), \"Cat-A\")]);\r\n const elementId = readReservedRows()[0].elementId;\r\n expect(elementId).to.equal(Id64.fromLocalAndBriefcaseIds(1, BriefcaseIdValue.SchemaSyncElementReserved));\r\n expect(Id64.getBriefcaseId(elementId)).to.equal(BriefcaseIdValue.SchemaSyncElementReserved);\r\n expect(Id64.getLocalId(elementId)).to.equal(1);\r\n });\r\n\r\n it(\"assigns sequential local Ids for a batch\", async () => {\r\n await schemaDb.reserveElements([\r\n makeReservation(Guid.createValue(), \"Cat-A\"),\r\n makeReservation(Guid.createValue(), \"Cat-B\"),\r\n makeReservation(Guid.createValue(), \"Cat-C\"),\r\n ]);\r\n const rows = readReservedRows();\r\n expect(rows).to.have.lengthOf(3);\r\n expect(rows.map((r) => Id64.getLocalId(r.elementId))).to.deep.equal([1, 2, 3]);\r\n expect(readNextLocalId()).to.equal(4);\r\n });\r\n\r\n it(\"is idempotent within a single call (duplicate element props)\", async () => {\r\n const federationGuid = Guid.createValue();\r\n await schemaDb.reserveElements([\r\n makeReservation(federationGuid, \"Cat-A\"),\r\n makeReservation(federationGuid, \"Cat-A\"),\r\n ]);\r\n expect(readReservedRows()).to.have.lengthOf(1);\r\n expect(readNextLocalId()).to.equal(2);\r\n });\r\n\r\n it(\"is idempotent across calls (returns existing id, allocates no new row)\", async () => {\r\n const federationGuid = Guid.createValue();\r\n await schemaDb.reserveElements([makeReservation(federationGuid, \"Cat-A\")]);\r\n const firstId = readReservedRows()[0].elementId;\r\n\r\n await schemaDb.reserveElements([makeReservation(federationGuid, \"Cat-A\")]);\r\n expect(readReservedRows()).to.have.lengthOf(1);\r\n expect(readReservedRows()[0].elementId).to.equal(firstId);\r\n expect(readNextLocalId()).to.equal(2);\r\n });\r\n\r\n it(\"allows multiple identities with empty codes to coexist\", async () => {\r\n await schemaDb.reserveElements([\r\n makeReservation(Guid.createValue(), \"\"),\r\n makeReservation(Guid.createValue(), \"\"),\r\n makeReservation(Guid.createValue(), \"\"),\r\n ]);\r\n const rows = readReservedRows();\r\n expect(rows).to.have.lengthOf(3);\r\n expect(new Set(rows.map((r) => r.elementId)).size).to.equal(3);\r\n });\r\n\r\n it(\"throws when an existing reservation has a different class\", async () => {\r\n const federationGuid = Guid.createValue();\r\n await schemaDb.reserveElements([makeReservation(federationGuid, \"Cat-A\", \"0x1\")]);\r\n await expectReservationError(schemaDb.reserveElements([\r\n makeReservation(federationGuid, \"Cat-A\", \"0x2\"),\r\n ]), \"reservation-conflict\");\r\n });\r\n\r\n it(\"throws when federationGuid and code resolve to different existing rows\", async () => {\r\n const federationGuidA = Guid.createValue();\r\n const federationGuidB = Guid.createValue();\r\n await schemaDb.reserveElements([\r\n makeReservation(federationGuidA, \"Cat-A\"),\r\n makeReservation(federationGuidB, \"Cat-B\"),\r\n ]);\r\n // fedGuid lookup returns the A row, code lookup returns the B row.\r\n await expectReservationError(schemaDb.reserveElements([\r\n makeReservation(federationGuidA, \"Cat-B\"),\r\n ]), \"reservation-conflict\");\r\n });\r\n\r\n it(\"throws when the local-id sequence is exhausted\", async () => {\r\n // eslint-disable-next-line @typescript-eslint/dot-notation\r\n schemaDb[\"setNextReservedElementLocalId\"](Math.pow(2, 40) - 2); // Seed counter near the 2^40 ceiling.\r\n schemaDb.saveChanges();\r\n await expectReservationError(schemaDb.reserveElements([\r\n makeReservation(Guid.createValue(), \"Cat-A\"),\r\n makeReservation(Guid.createValue(), \"Cat-B\"),\r\n makeReservation(Guid.createValue(), \"Cat-C\"),\r\n ]), \"id-sequence-exhausted\");\r\n expect(readReservedRows()).to.be.empty;\r\n });\r\n\r\n it(\"throws when a federationGuid is missing\", async () => {\r\n await expectReservationError(schemaDb.reserveElements([\r\n { ecClassId: \"0x1\", code: Code.fromJSON({ spec: \"0x1\", scope: \"0x2\", value: \"Cat-A\" }) } as any,\r\n ]), \"invalid-reservation\");\r\n expect(readReservedRows()).to.be.empty;\r\n });\r\n });\r\n});\r\n"]}
@@ -130,6 +130,7 @@ describe("SchemaSync element reservation", () => {
130
130
  sinon.stub(iModel[_nativeDb], "schemaSyncInit").callsFake(() => {
131
131
  schemaSyncEnabled = true;
132
132
  });
133
+ sinon.stub(iModel.locks, "isServerBased").value(true);
133
134
  sinon.stub(iModel, "acquireSchemaLock").resolves();
134
135
  sinon.stub(iModel, "pullChanges").resolves();
135
136
  sinon.stub(iModel, "pushChanges").resolves();
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaSyncElementReservation.test.js","sourceRoot":"","sources":["../../../../src/test/standalone/SchemaSyncElementReservation.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n * See LICENSE.md in the project root for license terms and full copyright notice.\r\n *--------------------------------------------------------------------------------------------*/\r\n\r\nimport { Id64, OpenMode } from \"@itwin/core-bentley\";\r\nimport { BriefcaseIdValue, ElementReservationError, IModel } from \"@itwin/core-common\";\r\nimport { expect } from \"chai\";\r\nimport * as sinon from \"sinon\";\r\nimport { CloudSqlite, IModelJsFs, SchemaSync, StandaloneDb } from \"../../core-backend\";\r\nimport { DrawingCategory } from \"../../Category\";\r\nimport { _nativeDb, _onReservedElementInsert } from \"../../internal/Symbols\";\r\nimport { EditTxn, withEditTxn } from \"../../EditTxn\";\r\nimport { IModelTestUtils } from \"../IModelTestUtils\";\r\n\r\n/** Assert that `promise` rejects with an `ElementReservationError` carrying the given key. */\r\nasync function expectReservationError(promise: Promise<unknown>, key: ElementReservationError.Key): Promise<void> {\r\n try {\r\n await promise;\r\n } catch (err) {\r\n expect(ElementReservationError.isError(err, key), `expected ElementReservationError '${key}', got: ${JSON.stringify(err)}`).to.be.true;\r\n return;\r\n }\r\n expect.fail(`expected promise to reject with ElementReservationError '${key}'`);\r\n}\r\n\r\nconst fedGuidA = \"8b33a6ec-1a6f-4ae2-8ad4-c426276d1f30\";\r\nconst fedGuidB = \"1f0e5b96-1234-4abc-9def-0123456789ab\";\r\n\r\ndescribe(\"SchemaSync element reservation\", () => {\r\n let iModel: StandaloneDb;\r\n let iModelFileName: string;\r\n let schemaDb: SchemaSync.SchemaSyncDb;\r\n let schemaDbFileName: string;\r\n\r\n beforeEach(() => {\r\n iModelFileName = IModelTestUtils.prepareOutputFile(\"SchemaSyncElementReservation\", \"element-reservation.bim\");\r\n schemaDbFileName = IModelTestUtils.prepareOutputFile(\"SchemaSyncElementReservation\", \"element-reservation-sync.db\");\r\n iModel = StandaloneDb.createEmpty(iModelFileName, { rootSubject: { name: \"SchemaSyncElementReservation\" } });\r\n SchemaSync.SchemaSyncDb.createNewDb(schemaDbFileName);\r\n schemaDb = new SchemaSync.SchemaSyncDb();\r\n schemaDb.openDb(schemaDbFileName, OpenMode.ReadWrite);\r\n });\r\n\r\n afterEach(() => {\r\n sinon.restore();\r\n if (schemaDb.isOpen)\r\n schemaDb.closeDb();\r\n if (iModel.isOpen)\r\n iModel.close();\r\n\r\n IModelJsFs.removeSync(iModelFileName);\r\n IModelJsFs.removeSync(schemaDbFileName);\r\n });\r\n\r\n // `SchemaSyncReservations` only ever obtains its access object via `SchemaSync.getCloudAccess`, so we\r\n // stub that single seam to hand back a mock that delegates every operation to the already-open\r\n // `schemaDb`. `withLockedDb` / `writeLocker` mirror the real commit-on-success, abandon-on-error\r\n // semantics without any CloudContainer.\r\n function stubCloudAccess() {\r\n // This is the minimal `SchemaSync.CloudAccess` surface that `SchemaSyncReservations` actually consumes.\r\n const access = {\r\n synchronizeWithCloud() { },\r\n close() { },\r\n getUri: () => `${schemaDbFileName}?vfs=test`,\r\n container: { hasLocalChanges: false } as CloudSqlite.CloudContainer, // these tests use local-only SchemaSyncDb, no need to mock a real CloudContainer\r\n reader: {\r\n findReservedElement: (fedGuid) => schemaDb.findReservedElement(fedGuid),\r\n },\r\n writeLocker: {\r\n reserveElements: async (ids) => {\r\n try {\r\n await schemaDb.reserveElements(ids);\r\n schemaDb.saveChanges();\r\n } catch (err) {\r\n schemaDb.abandonChanges();\r\n throw err;\r\n }\r\n },\r\n },\r\n withLockedDb: async (_args, operation) => {\r\n try {\r\n const result = await operation();\r\n schemaDb.saveChanges();\r\n return result;\r\n } catch (err) {\r\n schemaDb.abandonChanges();\r\n throw err;\r\n }\r\n },\r\n } satisfies Partial<SchemaSync.CloudAccess>;\r\n sinon.stub(SchemaSync, \"getCloudAccess\").resolves(access as SchemaSync.CloudAccess);\r\n return access;\r\n }\r\n\r\n function enableSchemaSync(): void {\r\n sinon.stub(iModel[_nativeDb], \"schemaSyncEnabled\").returns(true);\r\n }\r\n\r\n async function setupSchemaSyncReservations() {\r\n const access = stubCloudAccess();\r\n enableSchemaSync();\r\n await iModel.initializeSharedElementReservations();\r\n return access;\r\n }\r\n\r\n function readAllRows(): Array<{ federationGuid: string, elementId: string, ecClassId: string, codeSpecId: string, codeScope: string, codeValue: string }> {\r\n return schemaDb.withSqliteStatement(\r\n \"SELECT federationGuid, elementId, ecClassId, codeSpecId, codeScope, codeValue FROM reserved_elements ORDER BY elementId\",\r\n (stmt) => {\r\n const rows: Array<{ federationGuid: string, elementId: string, ecClassId: string, codeSpecId: string, codeScope: string, codeValue: string }> = [];\r\n while (stmt.nextRow()) {\r\n rows.push({\r\n federationGuid: stmt.getValueGuid(0),\r\n elementId: stmt.getValueId(1),\r\n ecClassId: stmt.getValueId(2),\r\n codeSpecId: stmt.getValueId(3),\r\n codeScope: stmt.getValueId(4),\r\n codeValue: stmt.getValueString(5),\r\n });\r\n }\r\n return rows;\r\n },\r\n );\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/dot-notation\r\n const readNextLocalId = () => schemaDb[\"getNextReservedElementLocalId\"]();\r\n const nonEmptyCode = (value: string) => ({ spec: \"0x1\", scope: \"0x2\", value });\r\n\r\n describe(\"reservation control initialization\", () => {\r\n it(\"uses NoReservations when SchemaSync is disabled\", async () => {\r\n await iModel.initializeSharedElementReservations();\r\n expect(iModel.reservations.needsElementReservation(fedGuidA)).to.be.false;\r\n await expect(iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n })).to.be.fulfilled;\r\n });\r\n\r\n it(\"initializes SchemaSync-backed reservations after initializeForIModel\", async () => {\r\n let schemaSyncEnabled = false;\r\n stubCloudAccess();\r\n sinon.stub(iModel[_nativeDb], \"schemaSyncEnabled\").callsFake(() => schemaSyncEnabled);\r\n sinon.stub(iModel[_nativeDb], \"schemaSyncInit\").callsFake(() => {\r\n schemaSyncEnabled = true;\r\n });\r\n sinon.stub(iModel, \"acquireSchemaLock\").resolves();\r\n sinon.stub(iModel, \"pullChanges\").resolves();\r\n sinon.stub(iModel, \"pushChanges\").resolves();\r\n\r\n await iModel.initializeSharedElementReservations();\r\n expect(iModel.reservations.needsElementReservation(fedGuidA)).to.be.false;\r\n\r\n const previousEnforcement = EditTxn.implicitWriteEnforcement;\r\n EditTxn.implicitWriteEnforcement = \"allow\";\r\n try {\r\n await SchemaSync.initializeForIModel({\r\n iModel,\r\n containerProps: {\r\n baseUri: \"https://example.invalid\",\r\n containerId: \"element-reservation\",\r\n storageType: \"azure\",\r\n },\r\n });\r\n } finally {\r\n EditTxn.implicitWriteEnforcement = previousEnforcement;\r\n }\r\n\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n });\r\n expect(readAllRows()).to.have.lengthOf(1);\r\n expect(readAllRows()[0].federationGuid).to.equal(fedGuidA);\r\n });\r\n\r\n it(\"reports needsElementReservation only for valid unreserved guids when SchemaSync is enabled\", async () => {\r\n await setupSchemaSyncReservations();\r\n\r\n expect(iModel.reservations.needsElementReservation(fedGuidA)).to.be.true;\r\n expect(() => iModel.reservations.needsElementReservation(\"not-a-guid\")).to.throw().that.satisfies(\r\n (err: unknown) => ElementReservationError.isError(err, \"invalid-reservation\")\r\n );\r\n\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n });\r\n\r\n expect(iModel.reservations.needsElementReservation(fedGuidA)).to.be.false;\r\n expect(iModel.reservations.needsElementReservation(fedGuidB)).to.be.true;\r\n });\r\n });\r\n\r\n describe(\"reserveElements\", () => {\r\n it(\"reserves a single ID and advances the counter\", async () => {\r\n await setupSchemaSyncReservations();\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:TypeDefinitionElement\", code: nonEmptyCode(\"TD-A\") }],\r\n });\r\n\r\n const rows = readAllRows();\r\n expect(rows).to.have.lengthOf(1);\r\n const elementId = rows[0].elementId;\r\n expect(elementId).to.equal(Id64.fromLocalAndBriefcaseIds(1, BriefcaseIdValue.SchemaSyncElementReserved));\r\n\r\n expect(rows[0].federationGuid).to.equal(fedGuidA);\r\n expect(rows[0].elementId).to.equal(elementId);\r\n expect(rows[0].codeValue).to.equal(\"TD-A\");\r\n expect(readNextLocalId()).to.equal(2);\r\n });\r\n\r\n it(\"reserves a non-definition element with an explicit federationGuid\", async () => {\r\n await setupSchemaSyncReservations();\r\n // A Subject is *not* a DefinitionElement; under the broadened rule it is still reservable.\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:Subject\" }],\r\n });\r\n const rows = readAllRows();\r\n expect(rows).to.have.lengthOf(1);\r\n expect(rows[0].federationGuid).to.equal(fedGuidA);\r\n expect(rows[0].codeValue).to.equal(\"\"); // empty code\r\n });\r\n\r\n it(\"reserves two IDs for categories and advances the counter\", async () => {\r\n await setupSchemaSyncReservations();\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n });\r\n\r\n const rows = readAllRows();\r\n expect(rows).to.have.lengthOf(1);\r\n const elementId = rows[0].elementId;\r\n expect(elementId).to.equal(Id64.fromLocalAndBriefcaseIds(1, BriefcaseIdValue.SchemaSyncElementReserved));\r\n\r\n expect(rows[0].federationGuid).to.equal(fedGuidA);\r\n expect(rows[0].elementId).to.equal(elementId);\r\n expect(rows[0].codeValue).to.equal(\"Cat-A\");\r\n expect(readNextLocalId()).to.equal(3); // +2 because category inserts always trigger a second insert for default subcategory\r\n });\r\n\r\n it(\"is idempotent when reserving the identical identity twice\", async () => {\r\n await setupSchemaSyncReservations();\r\n const args = { elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }] };\r\n await iModel.reservations.reserveElements(args);\r\n await iModel.reservations.reserveElements(args);\r\n expect(readAllRows()).to.have.lengthOf(1);\r\n });\r\n\r\n it(\"throws reservation-conflict when the same non-empty code is reserved for different guids (in one batch)\", async () => {\r\n await setupSchemaSyncReservations();\r\n await expect(iModel.reservations.reserveElements({\r\n elements: [\r\n { federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-X\") },\r\n { federationGuid: fedGuidB, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-X\") },\r\n ],\r\n })).to.be.rejected;\r\n expect(readAllRows()).to.be.empty;\r\n });\r\n\r\n it(\"throws reservation-conflict when the same non-empty code is reserved for a different guid (across batches)\", async () => {\r\n await setupSchemaSyncReservations();\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-X\") }],\r\n });\r\n await expect(iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidB, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-X\") }],\r\n })).to.be.rejected;\r\n expect(readAllRows()).to.have.lengthOf(1);\r\n });\r\n\r\n it(\"aggregates validation errors and reserves nothing on failure\", async () => {\r\n await setupSchemaSyncReservations();\r\n await expectReservationError(iModel.reservations.reserveElements({\r\n elements: [\r\n { federationGuid: \"not-a-guid\", classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat\") },\r\n { federationGuid: fedGuidA, classFullName: \"BisCore:NonexistentClassXYZ\", code: nonEmptyCode(\"Cat\") },\r\n { federationGuid: fedGuidB, classFullName: \"BisCore:DrawingCategory\", code: { spec: \"not-an-id\", scope: IModel.dictionaryId, value: \"Cat\" } },\r\n ],\r\n }), \"invalid-reservation\");\r\n expect(readAllRows()).to.be.empty;\r\n expect(readNextLocalId()).to.equal(1);\r\n });\r\n\r\n it(\"rejects entries with a missing federationGuid\", async () => {\r\n await setupSchemaSyncReservations();\r\n await expectReservationError(iModel.reservations.reserveElements({\r\n elements: [{ classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat\") } as any],\r\n }), \"invalid-reservation\");\r\n expect(readAllRows()).to.be.empty;\r\n });\r\n\r\n it(\"rolls back counter and rows when the locked-db write is abandoned\", async () => {\r\n const syncAccess = await setupSchemaSyncReservations();\r\n // First reserve advances the counter to 2 and commits.\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:TypeDefinitionElement\", code: nonEmptyCode(\"TD-A\") }],\r\n });\r\n expect(readNextLocalId()).to.equal(2);\r\n\r\n // Simulate something going wrong with the upload where the db write is abandoned instead of committed.\r\n syncAccess.writeLocker.reserveElements = async (ids) => {\r\n try {\r\n await schemaDb.reserveElements(ids);\r\n } finally {\r\n schemaDb.abandonChanges();\r\n }\r\n };\r\n\r\n // The second reserve allocates + inserts a new row, then the write is abandoned.\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidB, classFullName: \"BisCore:TypeDefinitionElement\", code: nonEmptyCode(\"TD-B\") }],\r\n });\r\n\r\n // The new row should not be visible, and the counter file-property must remain at \"2\".\r\n const rows = readAllRows();\r\n expect(rows.map((r) => r.federationGuid)).to.deep.equal([fedGuidA]);\r\n expect(readNextLocalId()).to.equal(2);\r\n });\r\n });\r\n\r\n describe(\"Reservations _onReservedElementInsert hook\", () => {\r\n it(\"is a no-op when SchemaSync is not enabled\", () => {\r\n // schemaSyncEnabled returns false by default.\r\n const arg = {\r\n iModel,\r\n props: {\r\n classFullName: \"BisCore:DrawingCategory\",\r\n federationGuid: fedGuidA,\r\n model: IModel.dictionaryId,\r\n code: nonEmptyCode(\"Cat-A\"),\r\n },\r\n options: {},\r\n };\r\n expect(() => iModel.reservations[_onReservedElementInsert](arg)).not.to.throw();\r\n expect((arg.props as any).id).to.be.undefined;\r\n expect((arg.options as any).forceUseId).to.be.undefined;\r\n });\r\n\r\n it(\"is a no-op when the schema lock is held\", async () => {\r\n await setupSchemaSyncReservations();\r\n sinon.stub(iModel, \"holdsSchemaLock\").get(() => true);\r\n\r\n expect(() => iModel.reservations[_onReservedElementInsert]({\r\n iModel,\r\n props: { classFullName: \"BisCore:DrawingCategory\" },\r\n options: {},\r\n } as any)).not.to.throw();\r\n });\r\n\r\n it(\"throws 'reservation-not-found' when reserve has never been called\", async () => {\r\n await setupSchemaSyncReservations();\r\n expect(() => iModel.reservations[_onReservedElementInsert]({\r\n iModel,\r\n props: {\r\n classFullName: \"BisCore:DrawingCategory\",\r\n federationGuid: fedGuidA,\r\n model: IModel.dictionaryId,\r\n code: nonEmptyCode(\"Cat-A\"),\r\n },\r\n options: {},\r\n })).to.throw().that.satisfies((err: unknown) => ElementReservationError.isError(err, \"reservation-not-found\"));\r\n });\r\n\r\n it(\"throws 'reservation-not-found' for an unreserved federationGuid\", async () => {\r\n await setupSchemaSyncReservations();\r\n // Reserve some other identity so the read handle is initialized.\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n });\r\n expect(() => iModel.reservations[_onReservedElementInsert]({\r\n iModel,\r\n props: {\r\n classFullName: \"BisCore:DrawingCategory\",\r\n federationGuid: fedGuidB,\r\n model: IModel.dictionaryId,\r\n code: nonEmptyCode(\"Cat-B\"),\r\n },\r\n options: {},\r\n })).to.throw().that.satisfies((err: unknown) => ElementReservationError.isError(err, \"reservation-not-found\"));\r\n });\r\n\r\n it(\"throws when federationGuid is present but malformed\", async () => {\r\n await setupSchemaSyncReservations();\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n });\r\n expect(() => iModel.reservations[_onReservedElementInsert]({\r\n iModel,\r\n props: {\r\n classFullName: \"BisCore:DrawingCategory\",\r\n federationGuid: \"not-a-valid-guid\",\r\n model: IModel.dictionaryId,\r\n code: nonEmptyCode(\"Cat-A\"),\r\n },\r\n options: {},\r\n })).to.throw().that.satisfies((err: unknown) => ElementReservationError.isError(err, \"invalid-reservation\"));\r\n });\r\n\r\n it(\"throws when SchemaSync container has local changes\", async () => {\r\n const syncAccess = await setupSchemaSyncReservations();\r\n (syncAccess.container as any).hasLocalChanges = true;\r\n\r\n expect(() => iModel.reservations[_onReservedElementInsert]({\r\n iModel,\r\n props: {\r\n classFullName: \"BisCore:DrawingCategory\",\r\n federationGuid: fedGuidA,\r\n model: IModel.dictionaryId,\r\n code: nonEmptyCode(\"Cat-A\"),\r\n },\r\n options: {},\r\n })).to.throw().that.satisfies((err: unknown) => ElementReservationError.isError(err, \"container-has-local-changes\"));\r\n });\r\n\r\n it(\"sets props.id and options.forceUseId when the reservation matches\", async () => {\r\n await setupSchemaSyncReservations();\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n });\r\n const expectedId = readAllRows()[0].elementId;\r\n\r\n const props: any = {\r\n classFullName: \"BisCore:DrawingCategory\",\r\n federationGuid: fedGuidA,\r\n model: IModel.dictionaryId,\r\n code: nonEmptyCode(\"Cat-A\"),\r\n };\r\n const options: any = {};\r\n iModel.reservations[_onReservedElementInsert]({ iModel, props, options });\r\n expect(props.id).to.equal(expectedId);\r\n expect(options.forceUseId).to.be.true;\r\n });\r\n\r\n it(\"throws when the insert's class does not match the reserved class\", async () => {\r\n await setupSchemaSyncReservations();\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n });\r\n expect(() => iModel.reservations[_onReservedElementInsert]({\r\n iModel,\r\n props: {\r\n classFullName: \"BisCore:SpatialCategory\",\r\n federationGuid: fedGuidA,\r\n model: IModel.dictionaryId,\r\n code: nonEmptyCode(\"Cat-A\"),\r\n },\r\n options: {},\r\n })).to.throw().that.satisfies((err: unknown) => ElementReservationError.isError(err, \"reservation-conflict\"));\r\n });\r\n\r\n it(\"throws when the insert's code does not match the reserved code\", async () => {\r\n await setupSchemaSyncReservations();\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n });\r\n expect(() => iModel.reservations[_onReservedElementInsert]({\r\n iModel,\r\n props: {\r\n classFullName: \"BisCore:DrawingCategory\",\r\n federationGuid: fedGuidA,\r\n model: IModel.dictionaryId,\r\n code: nonEmptyCode(\"Cat-DIFFERENT\"),\r\n },\r\n options: {},\r\n })).to.throw().that.satisfies((err: unknown) => ElementReservationError.isError(err, \"reservation-conflict\"));\r\n });\r\n\r\n it(\"applies reserved element id during a real DrawingCategory insert\", async () => {\r\n await setupSchemaSyncReservations();\r\n const categoryName = \"ReservedEndToEndCategory\";\r\n const categoryCode = DrawingCategory.createCode(iModel, IModel.dictionaryId, categoryName);\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: categoryCode }],\r\n });\r\n\r\n const expectedId = readAllRows()[0].elementId;\r\n const category = DrawingCategory.create(iModel, IModel.dictionaryId, categoryName);\r\n category.federationGuid = fedGuidA;\r\n const insertedId = withEditTxn(iModel, (txn) => category.insert(txn));\r\n expect(insertedId).to.equal(expectedId);\r\n expect(Id64.getBriefcaseId(insertedId)).to.equal(BriefcaseIdValue.SchemaSyncElementReserved);\r\n });\r\n\r\n it(\"inserts freely (no reservation) when no federationGuid is set\", async () => {\r\n await setupSchemaSyncReservations();\r\n const categoryName = \"UnreservedNoGuidCategory\";\r\n // No federationGuid on the element => ordinary element => not gated => inserts normally.\r\n const category = DrawingCategory.create(iModel, IModel.dictionaryId, categoryName);\r\n const insertedId = withEditTxn(iModel, (txn) => category.insert(txn));\r\n expect(Id64.getBriefcaseId(insertedId)).to.not.equal(BriefcaseIdValue.SchemaSyncElementReserved);\r\n });\r\n\r\n it(\"bypasses the reservation check when skipReservationCheck is set\", async () => {\r\n await setupSchemaSyncReservations();\r\n const categoryName = \"SkippedCategory\";\r\n const category = DrawingCategory.create(iModel, IModel.dictionaryId, categoryName);\r\n category.federationGuid = fedGuidA; // explicit fedGuid but no reservation exists\r\n const props = category.toJSON();\r\n const insertedId = withEditTxn(iModel, (txn) => txn.insertElement(props, { skipReservationCheck: true }));\r\n expect(Id64.getBriefcaseId(insertedId)).to.not.equal(BriefcaseIdValue.SchemaSyncElementReserved);\r\n expect(iModel.elements.getElement(insertedId).federationGuid).to.equal(fedGuidA);\r\n });\r\n\r\n it(\"throws reservation-not-found for a real insert of an unreserved element with an explicit fedGuid\", async () => {\r\n await setupSchemaSyncReservations();\r\n const categoryName = \"UnreservedGuidCategory\";\r\n const category = DrawingCategory.create(iModel, IModel.dictionaryId, categoryName);\r\n category.federationGuid = fedGuidB; // explicit fedGuid, never reserved\r\n expect(() => withEditTxn(iModel, (txn) => category.insert(txn)))\r\n .to.throw().that.satisfies((err: unknown) => ElementReservationError.isError(err, \"reservation-not-found\"));\r\n });\r\n });\r\n});\r\n"]}
1
+ {"version":3,"file":"SchemaSyncElementReservation.test.js","sourceRoot":"","sources":["../../../../src/test/standalone/SchemaSyncElementReservation.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n * See LICENSE.md in the project root for license terms and full copyright notice.\r\n *--------------------------------------------------------------------------------------------*/\r\n\r\nimport { Id64, OpenMode } from \"@itwin/core-bentley\";\r\nimport { BriefcaseIdValue, ElementReservationError, IModel } from \"@itwin/core-common\";\r\nimport { expect } from \"chai\";\r\nimport * as sinon from \"sinon\";\r\nimport { CloudSqlite, IModelJsFs, SchemaSync, StandaloneDb } from \"../../core-backend\";\r\nimport { DrawingCategory } from \"../../Category\";\r\nimport { _nativeDb, _onReservedElementInsert } from \"../../internal/Symbols\";\r\nimport { EditTxn, withEditTxn } from \"../../EditTxn\";\r\nimport { IModelTestUtils } from \"../IModelTestUtils\";\r\n\r\n/** Assert that `promise` rejects with an `ElementReservationError` carrying the given key. */\r\nasync function expectReservationError(promise: Promise<unknown>, key: ElementReservationError.Key): Promise<void> {\r\n try {\r\n await promise;\r\n } catch (err) {\r\n expect(ElementReservationError.isError(err, key), `expected ElementReservationError '${key}', got: ${JSON.stringify(err)}`).to.be.true;\r\n return;\r\n }\r\n expect.fail(`expected promise to reject with ElementReservationError '${key}'`);\r\n}\r\n\r\nconst fedGuidA = \"8b33a6ec-1a6f-4ae2-8ad4-c426276d1f30\";\r\nconst fedGuidB = \"1f0e5b96-1234-4abc-9def-0123456789ab\";\r\n\r\ndescribe(\"SchemaSync element reservation\", () => {\r\n let iModel: StandaloneDb;\r\n let iModelFileName: string;\r\n let schemaDb: SchemaSync.SchemaSyncDb;\r\n let schemaDbFileName: string;\r\n\r\n beforeEach(() => {\r\n iModelFileName = IModelTestUtils.prepareOutputFile(\"SchemaSyncElementReservation\", \"element-reservation.bim\");\r\n schemaDbFileName = IModelTestUtils.prepareOutputFile(\"SchemaSyncElementReservation\", \"element-reservation-sync.db\");\r\n iModel = StandaloneDb.createEmpty(iModelFileName, { rootSubject: { name: \"SchemaSyncElementReservation\" } });\r\n SchemaSync.SchemaSyncDb.createNewDb(schemaDbFileName);\r\n schemaDb = new SchemaSync.SchemaSyncDb();\r\n schemaDb.openDb(schemaDbFileName, OpenMode.ReadWrite);\r\n });\r\n\r\n afterEach(() => {\r\n sinon.restore();\r\n if (schemaDb.isOpen)\r\n schemaDb.closeDb();\r\n if (iModel.isOpen)\r\n iModel.close();\r\n\r\n IModelJsFs.removeSync(iModelFileName);\r\n IModelJsFs.removeSync(schemaDbFileName);\r\n });\r\n\r\n // `SchemaSyncReservations` only ever obtains its access object via `SchemaSync.getCloudAccess`, so we\r\n // stub that single seam to hand back a mock that delegates every operation to the already-open\r\n // `schemaDb`. `withLockedDb` / `writeLocker` mirror the real commit-on-success, abandon-on-error\r\n // semantics without any CloudContainer.\r\n function stubCloudAccess() {\r\n // This is the minimal `SchemaSync.CloudAccess` surface that `SchemaSyncReservations` actually consumes.\r\n const access = {\r\n synchronizeWithCloud() { },\r\n close() { },\r\n getUri: () => `${schemaDbFileName}?vfs=test`,\r\n container: { hasLocalChanges: false } as CloudSqlite.CloudContainer, // these tests use local-only SchemaSyncDb, no need to mock a real CloudContainer\r\n reader: {\r\n findReservedElement: (fedGuid) => schemaDb.findReservedElement(fedGuid),\r\n },\r\n writeLocker: {\r\n reserveElements: async (ids) => {\r\n try {\r\n await schemaDb.reserveElements(ids);\r\n schemaDb.saveChanges();\r\n } catch (err) {\r\n schemaDb.abandonChanges();\r\n throw err;\r\n }\r\n },\r\n },\r\n withLockedDb: async (_args, operation) => {\r\n try {\r\n const result = await operation();\r\n schemaDb.saveChanges();\r\n return result;\r\n } catch (err) {\r\n schemaDb.abandonChanges();\r\n throw err;\r\n }\r\n },\r\n } satisfies Partial<SchemaSync.CloudAccess>;\r\n sinon.stub(SchemaSync, \"getCloudAccess\").resolves(access as SchemaSync.CloudAccess);\r\n return access;\r\n }\r\n\r\n function enableSchemaSync(): void {\r\n sinon.stub(iModel[_nativeDb], \"schemaSyncEnabled\").returns(true);\r\n }\r\n\r\n async function setupSchemaSyncReservations() {\r\n const access = stubCloudAccess();\r\n enableSchemaSync();\r\n await iModel.initializeSharedElementReservations();\r\n return access;\r\n }\r\n\r\n function readAllRows(): Array<{ federationGuid: string, elementId: string, ecClassId: string, codeSpecId: string, codeScope: string, codeValue: string }> {\r\n return schemaDb.withSqliteStatement(\r\n \"SELECT federationGuid, elementId, ecClassId, codeSpecId, codeScope, codeValue FROM reserved_elements ORDER BY elementId\",\r\n (stmt) => {\r\n const rows: Array<{ federationGuid: string, elementId: string, ecClassId: string, codeSpecId: string, codeScope: string, codeValue: string }> = [];\r\n while (stmt.nextRow()) {\r\n rows.push({\r\n federationGuid: stmt.getValueGuid(0),\r\n elementId: stmt.getValueId(1),\r\n ecClassId: stmt.getValueId(2),\r\n codeSpecId: stmt.getValueId(3),\r\n codeScope: stmt.getValueId(4),\r\n codeValue: stmt.getValueString(5),\r\n });\r\n }\r\n return rows;\r\n },\r\n );\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/dot-notation\r\n const readNextLocalId = () => schemaDb[\"getNextReservedElementLocalId\"]();\r\n const nonEmptyCode = (value: string) => ({ spec: \"0x1\", scope: \"0x2\", value });\r\n\r\n describe(\"reservation control initialization\", () => {\r\n it(\"uses NoReservations when SchemaSync is disabled\", async () => {\r\n await iModel.initializeSharedElementReservations();\r\n expect(iModel.reservations.needsElementReservation(fedGuidA)).to.be.false;\r\n await expect(iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n })).to.be.fulfilled;\r\n });\r\n\r\n it(\"initializes SchemaSync-backed reservations after initializeForIModel\", async () => {\r\n let schemaSyncEnabled = false;\r\n stubCloudAccess();\r\n sinon.stub(iModel[_nativeDb], \"schemaSyncEnabled\").callsFake(() => schemaSyncEnabled);\r\n sinon.stub(iModel[_nativeDb], \"schemaSyncInit\").callsFake(() => {\r\n schemaSyncEnabled = true;\r\n });\r\n sinon.stub(iModel.locks, \"isServerBased\").value(true);\r\n sinon.stub(iModel, \"acquireSchemaLock\").resolves();\r\n sinon.stub(iModel, \"pullChanges\").resolves();\r\n sinon.stub(iModel, \"pushChanges\").resolves();\r\n\r\n await iModel.initializeSharedElementReservations();\r\n expect(iModel.reservations.needsElementReservation(fedGuidA)).to.be.false;\r\n\r\n const previousEnforcement = EditTxn.implicitWriteEnforcement;\r\n EditTxn.implicitWriteEnforcement = \"allow\";\r\n try {\r\n await SchemaSync.initializeForIModel({\r\n iModel,\r\n containerProps: {\r\n baseUri: \"https://example.invalid\",\r\n containerId: \"element-reservation\",\r\n storageType: \"azure\",\r\n },\r\n });\r\n } finally {\r\n EditTxn.implicitWriteEnforcement = previousEnforcement;\r\n }\r\n\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n });\r\n expect(readAllRows()).to.have.lengthOf(1);\r\n expect(readAllRows()[0].federationGuid).to.equal(fedGuidA);\r\n });\r\n\r\n it(\"reports needsElementReservation only for valid unreserved guids when SchemaSync is enabled\", async () => {\r\n await setupSchemaSyncReservations();\r\n\r\n expect(iModel.reservations.needsElementReservation(fedGuidA)).to.be.true;\r\n expect(() => iModel.reservations.needsElementReservation(\"not-a-guid\")).to.throw().that.satisfies(\r\n (err: unknown) => ElementReservationError.isError(err, \"invalid-reservation\")\r\n );\r\n\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n });\r\n\r\n expect(iModel.reservations.needsElementReservation(fedGuidA)).to.be.false;\r\n expect(iModel.reservations.needsElementReservation(fedGuidB)).to.be.true;\r\n });\r\n });\r\n\r\n describe(\"reserveElements\", () => {\r\n it(\"reserves a single ID and advances the counter\", async () => {\r\n await setupSchemaSyncReservations();\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:TypeDefinitionElement\", code: nonEmptyCode(\"TD-A\") }],\r\n });\r\n\r\n const rows = readAllRows();\r\n expect(rows).to.have.lengthOf(1);\r\n const elementId = rows[0].elementId;\r\n expect(elementId).to.equal(Id64.fromLocalAndBriefcaseIds(1, BriefcaseIdValue.SchemaSyncElementReserved));\r\n\r\n expect(rows[0].federationGuid).to.equal(fedGuidA);\r\n expect(rows[0].elementId).to.equal(elementId);\r\n expect(rows[0].codeValue).to.equal(\"TD-A\");\r\n expect(readNextLocalId()).to.equal(2);\r\n });\r\n\r\n it(\"reserves a non-definition element with an explicit federationGuid\", async () => {\r\n await setupSchemaSyncReservations();\r\n // A Subject is *not* a DefinitionElement; under the broadened rule it is still reservable.\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:Subject\" }],\r\n });\r\n const rows = readAllRows();\r\n expect(rows).to.have.lengthOf(1);\r\n expect(rows[0].federationGuid).to.equal(fedGuidA);\r\n expect(rows[0].codeValue).to.equal(\"\"); // empty code\r\n });\r\n\r\n it(\"reserves two IDs for categories and advances the counter\", async () => {\r\n await setupSchemaSyncReservations();\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n });\r\n\r\n const rows = readAllRows();\r\n expect(rows).to.have.lengthOf(1);\r\n const elementId = rows[0].elementId;\r\n expect(elementId).to.equal(Id64.fromLocalAndBriefcaseIds(1, BriefcaseIdValue.SchemaSyncElementReserved));\r\n\r\n expect(rows[0].federationGuid).to.equal(fedGuidA);\r\n expect(rows[0].elementId).to.equal(elementId);\r\n expect(rows[0].codeValue).to.equal(\"Cat-A\");\r\n expect(readNextLocalId()).to.equal(3); // +2 because category inserts always trigger a second insert for default subcategory\r\n });\r\n\r\n it(\"is idempotent when reserving the identical identity twice\", async () => {\r\n await setupSchemaSyncReservations();\r\n const args = { elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }] };\r\n await iModel.reservations.reserveElements(args);\r\n await iModel.reservations.reserveElements(args);\r\n expect(readAllRows()).to.have.lengthOf(1);\r\n });\r\n\r\n it(\"throws reservation-conflict when the same non-empty code is reserved for different guids (in one batch)\", async () => {\r\n await setupSchemaSyncReservations();\r\n await expect(iModel.reservations.reserveElements({\r\n elements: [\r\n { federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-X\") },\r\n { federationGuid: fedGuidB, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-X\") },\r\n ],\r\n })).to.be.rejected;\r\n expect(readAllRows()).to.be.empty;\r\n });\r\n\r\n it(\"throws reservation-conflict when the same non-empty code is reserved for a different guid (across batches)\", async () => {\r\n await setupSchemaSyncReservations();\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-X\") }],\r\n });\r\n await expect(iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidB, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-X\") }],\r\n })).to.be.rejected;\r\n expect(readAllRows()).to.have.lengthOf(1);\r\n });\r\n\r\n it(\"aggregates validation errors and reserves nothing on failure\", async () => {\r\n await setupSchemaSyncReservations();\r\n await expectReservationError(iModel.reservations.reserveElements({\r\n elements: [\r\n { federationGuid: \"not-a-guid\", classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat\") },\r\n { federationGuid: fedGuidA, classFullName: \"BisCore:NonexistentClassXYZ\", code: nonEmptyCode(\"Cat\") },\r\n { federationGuid: fedGuidB, classFullName: \"BisCore:DrawingCategory\", code: { spec: \"not-an-id\", scope: IModel.dictionaryId, value: \"Cat\" } },\r\n ],\r\n }), \"invalid-reservation\");\r\n expect(readAllRows()).to.be.empty;\r\n expect(readNextLocalId()).to.equal(1);\r\n });\r\n\r\n it(\"rejects entries with a missing federationGuid\", async () => {\r\n await setupSchemaSyncReservations();\r\n await expectReservationError(iModel.reservations.reserveElements({\r\n elements: [{ classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat\") } as any],\r\n }), \"invalid-reservation\");\r\n expect(readAllRows()).to.be.empty;\r\n });\r\n\r\n it(\"rolls back counter and rows when the locked-db write is abandoned\", async () => {\r\n const syncAccess = await setupSchemaSyncReservations();\r\n // First reserve advances the counter to 2 and commits.\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:TypeDefinitionElement\", code: nonEmptyCode(\"TD-A\") }],\r\n });\r\n expect(readNextLocalId()).to.equal(2);\r\n\r\n // Simulate something going wrong with the upload where the db write is abandoned instead of committed.\r\n syncAccess.writeLocker.reserveElements = async (ids) => {\r\n try {\r\n await schemaDb.reserveElements(ids);\r\n } finally {\r\n schemaDb.abandonChanges();\r\n }\r\n };\r\n\r\n // The second reserve allocates + inserts a new row, then the write is abandoned.\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidB, classFullName: \"BisCore:TypeDefinitionElement\", code: nonEmptyCode(\"TD-B\") }],\r\n });\r\n\r\n // The new row should not be visible, and the counter file-property must remain at \"2\".\r\n const rows = readAllRows();\r\n expect(rows.map((r) => r.federationGuid)).to.deep.equal([fedGuidA]);\r\n expect(readNextLocalId()).to.equal(2);\r\n });\r\n });\r\n\r\n describe(\"Reservations _onReservedElementInsert hook\", () => {\r\n it(\"is a no-op when SchemaSync is not enabled\", () => {\r\n // schemaSyncEnabled returns false by default.\r\n const arg = {\r\n iModel,\r\n props: {\r\n classFullName: \"BisCore:DrawingCategory\",\r\n federationGuid: fedGuidA,\r\n model: IModel.dictionaryId,\r\n code: nonEmptyCode(\"Cat-A\"),\r\n },\r\n options: {},\r\n };\r\n expect(() => iModel.reservations[_onReservedElementInsert](arg)).not.to.throw();\r\n expect((arg.props as any).id).to.be.undefined;\r\n expect((arg.options as any).forceUseId).to.be.undefined;\r\n });\r\n\r\n it(\"is a no-op when the schema lock is held\", async () => {\r\n await setupSchemaSyncReservations();\r\n sinon.stub(iModel, \"holdsSchemaLock\").get(() => true);\r\n\r\n expect(() => iModel.reservations[_onReservedElementInsert]({\r\n iModel,\r\n props: { classFullName: \"BisCore:DrawingCategory\" },\r\n options: {},\r\n } as any)).not.to.throw();\r\n });\r\n\r\n it(\"throws 'reservation-not-found' when reserve has never been called\", async () => {\r\n await setupSchemaSyncReservations();\r\n expect(() => iModel.reservations[_onReservedElementInsert]({\r\n iModel,\r\n props: {\r\n classFullName: \"BisCore:DrawingCategory\",\r\n federationGuid: fedGuidA,\r\n model: IModel.dictionaryId,\r\n code: nonEmptyCode(\"Cat-A\"),\r\n },\r\n options: {},\r\n })).to.throw().that.satisfies((err: unknown) => ElementReservationError.isError(err, \"reservation-not-found\"));\r\n });\r\n\r\n it(\"throws 'reservation-not-found' for an unreserved federationGuid\", async () => {\r\n await setupSchemaSyncReservations();\r\n // Reserve some other identity so the read handle is initialized.\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n });\r\n expect(() => iModel.reservations[_onReservedElementInsert]({\r\n iModel,\r\n props: {\r\n classFullName: \"BisCore:DrawingCategory\",\r\n federationGuid: fedGuidB,\r\n model: IModel.dictionaryId,\r\n code: nonEmptyCode(\"Cat-B\"),\r\n },\r\n options: {},\r\n })).to.throw().that.satisfies((err: unknown) => ElementReservationError.isError(err, \"reservation-not-found\"));\r\n });\r\n\r\n it(\"throws when federationGuid is present but malformed\", async () => {\r\n await setupSchemaSyncReservations();\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n });\r\n expect(() => iModel.reservations[_onReservedElementInsert]({\r\n iModel,\r\n props: {\r\n classFullName: \"BisCore:DrawingCategory\",\r\n federationGuid: \"not-a-valid-guid\",\r\n model: IModel.dictionaryId,\r\n code: nonEmptyCode(\"Cat-A\"),\r\n },\r\n options: {},\r\n })).to.throw().that.satisfies((err: unknown) => ElementReservationError.isError(err, \"invalid-reservation\"));\r\n });\r\n\r\n it(\"throws when SchemaSync container has local changes\", async () => {\r\n const syncAccess = await setupSchemaSyncReservations();\r\n (syncAccess.container as any).hasLocalChanges = true;\r\n\r\n expect(() => iModel.reservations[_onReservedElementInsert]({\r\n iModel,\r\n props: {\r\n classFullName: \"BisCore:DrawingCategory\",\r\n federationGuid: fedGuidA,\r\n model: IModel.dictionaryId,\r\n code: nonEmptyCode(\"Cat-A\"),\r\n },\r\n options: {},\r\n })).to.throw().that.satisfies((err: unknown) => ElementReservationError.isError(err, \"container-has-local-changes\"));\r\n });\r\n\r\n it(\"sets props.id and options.forceUseId when the reservation matches\", async () => {\r\n await setupSchemaSyncReservations();\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n });\r\n const expectedId = readAllRows()[0].elementId;\r\n\r\n const props: any = {\r\n classFullName: \"BisCore:DrawingCategory\",\r\n federationGuid: fedGuidA,\r\n model: IModel.dictionaryId,\r\n code: nonEmptyCode(\"Cat-A\"),\r\n };\r\n const options: any = {};\r\n iModel.reservations[_onReservedElementInsert]({ iModel, props, options });\r\n expect(props.id).to.equal(expectedId);\r\n expect(options.forceUseId).to.be.true;\r\n });\r\n\r\n it(\"throws when the insert's class does not match the reserved class\", async () => {\r\n await setupSchemaSyncReservations();\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n });\r\n expect(() => iModel.reservations[_onReservedElementInsert]({\r\n iModel,\r\n props: {\r\n classFullName: \"BisCore:SpatialCategory\",\r\n federationGuid: fedGuidA,\r\n model: IModel.dictionaryId,\r\n code: nonEmptyCode(\"Cat-A\"),\r\n },\r\n options: {},\r\n })).to.throw().that.satisfies((err: unknown) => ElementReservationError.isError(err, \"reservation-conflict\"));\r\n });\r\n\r\n it(\"throws when the insert's code does not match the reserved code\", async () => {\r\n await setupSchemaSyncReservations();\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: nonEmptyCode(\"Cat-A\") }],\r\n });\r\n expect(() => iModel.reservations[_onReservedElementInsert]({\r\n iModel,\r\n props: {\r\n classFullName: \"BisCore:DrawingCategory\",\r\n federationGuid: fedGuidA,\r\n model: IModel.dictionaryId,\r\n code: nonEmptyCode(\"Cat-DIFFERENT\"),\r\n },\r\n options: {},\r\n })).to.throw().that.satisfies((err: unknown) => ElementReservationError.isError(err, \"reservation-conflict\"));\r\n });\r\n\r\n it(\"applies reserved element id during a real DrawingCategory insert\", async () => {\r\n await setupSchemaSyncReservations();\r\n const categoryName = \"ReservedEndToEndCategory\";\r\n const categoryCode = DrawingCategory.createCode(iModel, IModel.dictionaryId, categoryName);\r\n await iModel.reservations.reserveElements({\r\n elements: [{ federationGuid: fedGuidA, classFullName: \"BisCore:DrawingCategory\", code: categoryCode }],\r\n });\r\n\r\n const expectedId = readAllRows()[0].elementId;\r\n const category = DrawingCategory.create(iModel, IModel.dictionaryId, categoryName);\r\n category.federationGuid = fedGuidA;\r\n const insertedId = withEditTxn(iModel, (txn) => category.insert(txn));\r\n expect(insertedId).to.equal(expectedId);\r\n expect(Id64.getBriefcaseId(insertedId)).to.equal(BriefcaseIdValue.SchemaSyncElementReserved);\r\n });\r\n\r\n it(\"inserts freely (no reservation) when no federationGuid is set\", async () => {\r\n await setupSchemaSyncReservations();\r\n const categoryName = \"UnreservedNoGuidCategory\";\r\n // No federationGuid on the element => ordinary element => not gated => inserts normally.\r\n const category = DrawingCategory.create(iModel, IModel.dictionaryId, categoryName);\r\n const insertedId = withEditTxn(iModel, (txn) => category.insert(txn));\r\n expect(Id64.getBriefcaseId(insertedId)).to.not.equal(BriefcaseIdValue.SchemaSyncElementReserved);\r\n });\r\n\r\n it(\"bypasses the reservation check when skipReservationCheck is set\", async () => {\r\n await setupSchemaSyncReservations();\r\n const categoryName = \"SkippedCategory\";\r\n const category = DrawingCategory.create(iModel, IModel.dictionaryId, categoryName);\r\n category.federationGuid = fedGuidA; // explicit fedGuid but no reservation exists\r\n const props = category.toJSON();\r\n const insertedId = withEditTxn(iModel, (txn) => txn.insertElement(props, { skipReservationCheck: true }));\r\n expect(Id64.getBriefcaseId(insertedId)).to.not.equal(BriefcaseIdValue.SchemaSyncElementReserved);\r\n expect(iModel.elements.getElement(insertedId).federationGuid).to.equal(fedGuidA);\r\n });\r\n\r\n it(\"throws reservation-not-found for a real insert of an unreserved element with an explicit fedGuid\", async () => {\r\n await setupSchemaSyncReservations();\r\n const categoryName = \"UnreservedGuidCategory\";\r\n const category = DrawingCategory.create(iModel, IModel.dictionaryId, categoryName);\r\n category.federationGuid = fedGuidB; // explicit fedGuid, never reserved\r\n expect(() => withEditTxn(iModel, (txn) => category.insert(txn)))\r\n .to.throw().that.satisfies((err: unknown) => ElementReservationError.isError(err, \"reservation-not-found\"));\r\n });\r\n });\r\n});\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/core-backend",
3
- "version": "5.14.0-dev.2",
3
+ "version": "5.14.0-dev.4",
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-common": "5.14.0-dev.2",
31
- "@itwin/core-bentley": "5.14.0-dev.2",
32
- "@itwin/ecschema-metadata": "5.14.0-dev.2",
33
- "@itwin/core-geometry": "5.14.0-dev.2"
30
+ "@itwin/core-bentley": "5.14.0-dev.4",
31
+ "@itwin/ecschema-metadata": "5.14.0-dev.4",
32
+ "@itwin/core-geometry": "5.14.0-dev.4",
33
+ "@itwin/core-common": "5.14.0-dev.4"
34
34
  },
35
35
  "peerDependenciesMeta": {
36
36
  "@opentelemetry/api": {
@@ -71,17 +71,17 @@
71
71
  "marked": "^14.1.3",
72
72
  "sql-formatter": "^15.4.6",
73
73
  "vite": "^6.4.3",
74
- "@itwin/core-geometry": "5.14.0-dev.2",
75
- "@itwin/build-tools": "5.14.0-dev.2",
76
- "@itwin/core-bentley": "5.14.0-dev.2",
77
- "@itwin/ecschema-locaters": "5.14.0-dev.2",
78
- "@itwin/ecschema-metadata": "5.14.0-dev.2",
79
- "@itwin/core-common": "5.14.0-dev.2",
80
- "@itwin/ecsql-common": "5.14.0-dev.2",
74
+ "@itwin/build-tools": "5.14.0-dev.4",
75
+ "@itwin/core-bentley": "5.14.0-dev.4",
76
+ "@itwin/core-common": "5.14.0-dev.4",
77
+ "@itwin/ecschema-locaters": "5.14.0-dev.4",
78
+ "@itwin/core-geometry": "5.14.0-dev.4",
79
+ "@itwin/ecsql-common": "5.14.0-dev.4",
80
+ "@itwin/ecschema-metadata": "5.14.0-dev.4",
81
81
  "internal-tools": "3.0.0-dev.69"
82
82
  },
83
83
  "dependencies": {
84
- "@bentley/imodeljs-native": "5.14.6",
84
+ "@bentley/imodeljs-native": "5.14.10",
85
85
  "@itwin/object-storage-azure": "^3.0.4",
86
86
  "@azure/storage-blob": "^12.28.0",
87
87
  "form-data": "^4.0.6",