@itwin/core-backend 5.12.0-dev.8 → 5.13.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/lib/cjs/ClassRegistry.d.ts.map +1 -1
  3. package/lib/cjs/ClassRegistry.js +1 -2
  4. package/lib/cjs/ClassRegistry.js.map +1 -1
  5. package/lib/cjs/ECDb.d.ts.map +1 -1
  6. package/lib/cjs/ECDb.js +8 -3
  7. package/lib/cjs/ECDb.js.map +1 -1
  8. package/lib/cjs/ECSqlRowExecutor.d.ts +23 -10
  9. package/lib/cjs/ECSqlRowExecutor.d.ts.map +1 -1
  10. package/lib/cjs/ECSqlRowExecutor.js +77 -15
  11. package/lib/cjs/ECSqlRowExecutor.js.map +1 -1
  12. package/lib/cjs/IModelDb.d.ts +20 -8
  13. package/lib/cjs/IModelDb.d.ts.map +1 -1
  14. package/lib/cjs/IModelDb.js +83 -54
  15. package/lib/cjs/IModelDb.js.map +1 -1
  16. package/lib/cjs/IpcHost.d.ts +26 -0
  17. package/lib/cjs/IpcHost.d.ts.map +1 -1
  18. package/lib/cjs/IpcHost.js +68 -61
  19. package/lib/cjs/IpcHost.js.map +1 -1
  20. package/lib/cjs/Relationship.d.ts.map +1 -1
  21. package/lib/cjs/Relationship.js +13 -7
  22. package/lib/cjs/Relationship.js.map +1 -1
  23. package/lib/cjs/SQLiteDb.d.ts +43 -0
  24. package/lib/cjs/SQLiteDb.d.ts.map +1 -1
  25. package/lib/cjs/SQLiteDb.js +51 -0
  26. package/lib/cjs/SQLiteDb.js.map +1 -1
  27. package/lib/cjs/ViewStore.js +1 -1
  28. package/lib/cjs/ViewStore.js.map +1 -1
  29. package/lib/cjs/internal/ECSqlInstanceReshaper.d.ts +23 -0
  30. package/lib/cjs/internal/ECSqlInstanceReshaper.d.ts.map +1 -0
  31. package/lib/cjs/internal/ECSqlInstanceReshaper.js +125 -0
  32. package/lib/cjs/internal/ECSqlInstanceReshaper.js.map +1 -0
  33. package/lib/cjs/internal/annotations/fields.d.ts.map +1 -1
  34. package/lib/cjs/internal/annotations/fields.js +9 -4
  35. package/lib/cjs/internal/annotations/fields.js.map +1 -1
  36. package/lib/esm/ClassRegistry.d.ts.map +1 -1
  37. package/lib/esm/ClassRegistry.js +1 -2
  38. package/lib/esm/ClassRegistry.js.map +1 -1
  39. package/lib/esm/ECDb.d.ts.map +1 -1
  40. package/lib/esm/ECDb.js +9 -4
  41. package/lib/esm/ECDb.js.map +1 -1
  42. package/lib/esm/ECSqlRowExecutor.d.ts +23 -10
  43. package/lib/esm/ECSqlRowExecutor.d.ts.map +1 -1
  44. package/lib/esm/ECSqlRowExecutor.js +77 -16
  45. package/lib/esm/ECSqlRowExecutor.js.map +1 -1
  46. package/lib/esm/IModelDb.d.ts +20 -8
  47. package/lib/esm/IModelDb.d.ts.map +1 -1
  48. package/lib/esm/IModelDb.js +85 -56
  49. package/lib/esm/IModelDb.js.map +1 -1
  50. package/lib/esm/IpcHost.d.ts +26 -0
  51. package/lib/esm/IpcHost.d.ts.map +1 -1
  52. package/lib/esm/IpcHost.js +70 -63
  53. package/lib/esm/IpcHost.js.map +1 -1
  54. package/lib/esm/Relationship.d.ts.map +1 -1
  55. package/lib/esm/Relationship.js +13 -7
  56. package/lib/esm/Relationship.js.map +1 -1
  57. package/lib/esm/SQLiteDb.d.ts +43 -0
  58. package/lib/esm/SQLiteDb.d.ts.map +1 -1
  59. package/lib/esm/SQLiteDb.js +51 -0
  60. package/lib/esm/SQLiteDb.js.map +1 -1
  61. package/lib/esm/ViewStore.js +1 -1
  62. package/lib/esm/ViewStore.js.map +1 -1
  63. package/lib/esm/internal/ECSqlInstanceReshaper.d.ts +23 -0
  64. package/lib/esm/internal/ECSqlInstanceReshaper.d.ts.map +1 -0
  65. package/lib/esm/internal/ECSqlInstanceReshaper.js +120 -0
  66. package/lib/esm/internal/ECSqlInstanceReshaper.js.map +1 -0
  67. package/lib/esm/internal/annotations/fields.d.ts.map +1 -1
  68. package/lib/esm/internal/annotations/fields.js +9 -4
  69. package/lib/esm/internal/annotations/fields.js.map +1 -1
  70. package/lib/esm/test/IpcHost.test.js +232 -1
  71. package/lib/esm/test/IpcHost.test.js.map +1 -1
  72. package/lib/esm/test/ecdb/ECSqlSyncReader.test.js +139 -1
  73. package/lib/esm/test/ecdb/ECSqlSyncReader.test.js.map +1 -1
  74. package/lib/esm/test/imodel/IModel.test.js +20 -0
  75. package/lib/esm/test/imodel/IModel.test.js.map +1 -1
  76. package/lib/esm/test/internal/ECSqlInstanceReshaper.test.d.ts +2 -0
  77. package/lib/esm/test/internal/ECSqlInstanceReshaper.test.d.ts.map +1 -0
  78. package/lib/esm/test/internal/ECSqlInstanceReshaper.test.js +289 -0
  79. package/lib/esm/test/internal/ECSqlInstanceReshaper.test.js.map +1 -0
  80. package/lib/esm/test/schema/ClassRegistry.test.js +2 -2
  81. package/lib/esm/test/schema/ClassRegistry.test.js.map +1 -1
  82. package/lib/esm/test/schema/SchemaViewFragmentLoading.test.d.ts +2 -0
  83. package/lib/esm/test/schema/SchemaViewFragmentLoading.test.d.ts.map +1 -0
  84. package/lib/esm/test/schema/SchemaViewFragmentLoading.test.js +546 -0
  85. package/lib/esm/test/schema/SchemaViewFragmentLoading.test.js.map +1 -0
  86. package/lib/esm/test/schema/SchemaViewLifecycle.test.js +2 -2
  87. package/lib/esm/test/schema/SchemaViewLifecycle.test.js.map +1 -1
  88. package/lib/esm/test/standalone/MergeConflict.test.js +1 -1
  89. package/lib/esm/test/standalone/MergeConflict.test.js.map +1 -1
  90. package/lib/esm/test/standalone/SQLiteDb.test.d.ts +1 -1
  91. package/lib/esm/test/standalone/SQLiteDb.test.d.ts.map +1 -1
  92. package/lib/esm/test/standalone/SQLiteDb.test.js +93 -1
  93. package/lib/esm/test/standalone/SQLiteDb.test.js.map +1 -1
  94. package/lib/esm/test/standalone/ViewStoreDb.test.js +30 -0
  95. package/lib/esm/test/standalone/ViewStoreDb.test.js.map +1 -1
  96. package/package.json +13 -13
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaViewFragmentLoading.test.js","sourceRoot":"","sources":["../../../../src/test/schema/SchemaViewFragmentLoading.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 { Guid, Logger, LogLevel, OpenMode } from \"@itwin/core-bentley\";\nimport { GenericSchema, IModelHost, IModelJsFs, StandaloneDb } from \"../../core-backend\";\nimport { SchemaView, schemaViewFormatVersion, SchemaViewPrimitiveType } from \"@itwin/ecschema-metadata\";\nimport { expect } from \"chai\";\nimport * as path from \"path\";\nimport * as sinon from \"sinon\";\nimport { KnownTestLocations } from \"../KnownTestLocations\";\nimport { TestUtils } from \"../TestUtils\";\n\n/** Categories of native log messages worth treating as a test failure. Native code routes through\n * `Logger`, so a C++ `warningv`/`errorv` surfaces here once the category level is raised. */\nconst monitoredNativeCategories = [\"ECDb\", \"ECObjectsNative\"];\n\n/** A captured native log message. */\ninterface CapturedNativeLog {\n level: \"Warning\" | \"Error\";\n category: string;\n message: string;\n}\n\n/** Run `body` while capturing native warnings and errors from the monitored categories.\n *\n * The test harness initializes the logger with all categories off, so native warnings/errors are\n * dropped before they ever reach JS. To observe them we must (1) raise each monitored category to\n * Warning - which fires onLogLevelChanged, prompting the native side to re-read levels and start\n * emitting (Warning and anything more severe, i.e. Error too) - and (2) install sinks to collect\n * what arrives. Returns the captured logs so the caller can assert none were produced.\n */\nasync function captureNativeLogs(body: () => Promise<void>): Promise<CapturedNativeLog[]> {\n const logs: CapturedNativeLog[] = [];\n const previousLevels = new Map(monitoredNativeCategories.map((category) => [category, Logger.getLevel(category)]));\n\n const warningStub = sinon.stub(Logger, \"logWarning\").callsFake((category: string, message: string) => {\n if (monitoredNativeCategories.includes(category))\n logs.push({ level: \"Warning\", category, message });\n });\n const errorStub = sinon.stub(Logger, \"logError\").callsFake((category: string, messageOrError: unknown) => {\n if (monitoredNativeCategories.includes(category))\n logs.push({ level: \"Error\", category, message: typeof messageOrError === \"string\" ? messageOrError : String(messageOrError) });\n });\n\n for (const category of monitoredNativeCategories)\n Logger.setLevel(category, LogLevel.Warning);\n\n try {\n await body();\n } finally {\n warningStub.restore();\n errorStub.restore();\n for (const [category, previousLevel] of previousLevels)\n Logger.setLevel(category, previousLevel ?? LogLevel.None);\n }\n return logs;\n}\n\n/** SchemaB references BisCore and defines BElement deriving from a BisCore class. */\nconst schemaB = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <ECSchema schemaName=\"FragB\" alias=\"fb\" version=\"01.00.00\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\n <ECSchemaReference name=\"BisCore\" version=\"01.00.00\" alias=\"bis\"/>\n <ECEntityClass typeName=\"BElement\">\n <BaseClass>bis:PhysicalElement</BaseClass>\n <ECProperty propertyName=\"BProp\" typeName=\"string\"/>\n </ECEntityClass>\n </ECSchema>`;\n\n/** SchemaA references FragB and derives AElement from FragB:BElement.\n * So loading FragA must transitively pull FragB (and, through it, BisCore). */\nconst schemaA = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <ECSchema schemaName=\"FragA\" alias=\"fa\" version=\"01.00.00\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\n <ECSchemaReference name=\"FragB\" version=\"01.00.00\" alias=\"fb\"/>\n <ECEntityClass typeName=\"AElement\">\n <BaseClass>fb:BElement</BaseClass>\n <ECProperty propertyName=\"AProp\" typeName=\"int\"/>\n </ECEntityClass>\n </ECSchema>`;\n\n/** A third schema imported after the first load, to exercise cache invalidation. */\nconst schemaC = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <ECSchema schemaName=\"FragC\" alias=\"fc\" version=\"01.00.00\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\n <ECSchemaReference name=\"BisCore\" version=\"01.00.00\" alias=\"bis\"/>\n <ECEntityClass typeName=\"CElement\">\n <BaseClass>bis:PhysicalElement</BaseClass>\n <ECProperty propertyName=\"CProp\" typeName=\"string\"/>\n </ECEntityClass>\n </ECSchema>`;\n\n/**\n * Tests the incremental (\"husk\") schema-view path: `getSchemaView({ schemas: [...] })` loads only\n * the requested schemas plus their references via `PRAGMA schema_view_fragment`, accumulating\n * across calls. These run against a real iModel - the blob is exercised end to end (native writer ->\n * TS reader/merge), which is where the fragment mechanism actually has to work. The blob format\n * itself is an internal C++-writer-to-TS-reader contract.\n */\ndescribe(\"SchemaView fragment loading\", () => {\n // Building an empty iModel and importing schemas into it dominates this suite's runtime, so each\n // seed below is created once in `before`. Each test then just needs a writable file of its own -\n // a raw file copy plus `StandaloneDb.openFile` - rather than paying for createEmpty + schema import\n // again, or for the checkpoint/vacuum overhead that `SnapshotDb.createFrom` adds on top of the copy.\n let fragSeedDb: StandaloneDb;\n let genericSeedDb: StandaloneDb;\n\n before(async () => {\n if (!IModelHost.isValid)\n await TestUtils.startBackend();\n\n const fragSeedPath = path.join(KnownTestLocations.outputDir, `SchemaViewFragmentSeed-${Guid.createValue()}.bim`);\n fragSeedDb = StandaloneDb.createEmpty(fragSeedPath, { rootSubject: { name: \"SchemaViewFragmentLoadingSeed\" } });\n await fragSeedDb.importSchemaStrings([schemaB, schemaA]);\n fragSeedDb.performCheckpoint(); // flush + truncate the WAL so the raw file copy below is consistent\n\n GenericSchema.registerSchema();\n const genericSeedPath = path.join(KnownTestLocations.outputDir, `SchemaViewFragmentGenericSeed-${Guid.createValue()}.bim`);\n genericSeedDb = StandaloneDb.createEmpty(genericSeedPath, { rootSubject: { name: \"SchemaViewFragmentGenericSeed\" } });\n await genericSeedDb.importSchemas([GenericSchema.schemaFilePath]);\n genericSeedDb.performCheckpoint();\n });\n\n after(() => {\n fragSeedDb.close();\n genericSeedDb.close();\n });\n\n /** Clone a writable iModel from a seed's file via a raw file copy - no checkpoint/vacuum. Only\n * needed by the handful of tests that mutate the iModel (e.g. importing another schema); every\n * other test just opens a second read-only connection directly onto the seed's file below. */\n function cloneSeed(seedDb: StandaloneDb, namePrefix: string): StandaloneDb {\n const filePath = path.join(KnownTestLocations.outputDir, `${namePrefix}-${Guid.createValue()}.bim`);\n IModelJsFs.copySync(seedDb.pathName, filePath);\n return StandaloneDb.openFile(filePath, OpenMode.ReadWrite);\n }\n\n /** Get an iModel backed by the FragA/FragB (and BisCore) seed. Read-only by default - just another\n * connection onto the same file, no copy - since most tests only read a `SchemaView` off it. Pass\n * `writable: true` for the rare test that needs to mutate the iModel (e.g. import another schema),\n * which gets its own private copy so it can't affect the shared seed or other tests. */\n async function createIModelWithFragSchemas(options?: { writable?: boolean }): Promise<StandaloneDb> {\n if (options?.writable)\n return cloneSeed(fragSeedDb, \"SchemaViewFragment\");\n return StandaloneDb.openFile(fragSeedDb.pathName, OpenMode.Readonly);\n }\n\n /** Every schema name in the iModel, straight from ECDbMeta - the same source the schema manifest\n * is built from - so tests never hardcode the schema inventory of an empty snapshot. */\n async function queryAllSchemaNames(iModel: StandaloneDb): Promise<string[]> {\n const schemaNames: string[] = [];\n for await (const row of iModel.createQueryReader(\"SELECT Name FROM meta.ECSchemaDef\"))\n schemaNames.push(row[0] as string);\n return schemaNames;\n }\n\n /** The sorted names of every schema present in a view. */\n function getSortedViewSchemaNames(view: SchemaView): string[] {\n return [...view.getSchemas()].map((schema) => schema.name).sort();\n }\n\n it(\"loads a requested schema and its reference closure, leaving unrequested schemas absent\", async () => {\n const iModel = await createIModelWithFragSchemas();\n try {\n // Request only FragB. It references BisCore, so both must be present; FragA must not be.\n const view = await iModel.getSchemaView({ schemas: [\"FragB\"] });\n\n expect(view.getSchema(\"FragB\"), \"FragB was requested\").to.not.be.undefined;\n expect(view.getSchema(\"BisCore\"), \"BisCore is in FragB's closure\").to.not.be.undefined;\n expect(view.getSchema(\"FragA\"), \"FragA was not requested and nothing pulled it in\").to.be.undefined;\n\n expect(view.findClass(\"FragB:BElement\")).to.not.be.undefined;\n expect(view.findClass(\"FragA:AElement\")).to.be.undefined;\n } finally {\n iModel.close();\n }\n });\n\n it(\"pulls transitive dependencies when loading a dependent schema\", async () => {\n const iModel = await createIModelWithFragSchemas();\n try {\n // FragA -> FragB -> BisCore. Requesting FragA alone must make the whole chain resolvable.\n const view = await iModel.getSchemaView({ schemas: [\"FragA\"] });\n\n expect(view.getSchema(\"FragA\")).to.not.be.undefined;\n expect(view.getSchema(\"FragB\")).to.not.be.undefined;\n expect(view.getSchema(\"BisCore\")).to.not.be.undefined;\n\n const aElement = view.findClass(\"FragA:AElement\");\n expect(aElement).to.not.be.undefined;\n // Cross-schema base class resolves across the closure.\n expect(aElement!.baseClass?.fullName).to.equal(\"FragB:BElement\");\n // And transitively up into BisCore.\n expect(aElement!.is(\"BisCore:PhysicalElement\")).to.be.true;\n } finally {\n iModel.close();\n }\n });\n\n it(\"accumulates schemas across calls into one view\", async () => {\n const iModel = await createIModelWithFragSchemas();\n try {\n const view1 = await iModel.getSchemaView({ schemas: [\"FragB\"] });\n expect(view1.getSchema(\"FragA\")).to.be.undefined;\n\n // A second call for FragA merges into the same accumulating view.\n const view2 = await iModel.getSchemaView({ schemas: [\"FragA\"] });\n expect(view2, \"subset view is a single accumulating instance\").to.equal(view1);\n\n // Both schemas are now resolvable on the one view.\n expect(view2.findClass(\"FragA:AElement\")).to.not.be.undefined;\n expect(view2.findClass(\"FragB:BElement\")).to.not.be.undefined;\n } finally {\n iModel.close();\n }\n });\n\n it(\"is idempotent when re-requesting an already-loaded schema\", async () => {\n const iModel = await createIModelWithFragSchemas();\n try {\n const view1 = await iModel.getSchemaView({ schemas: [\"FragA\"] });\n const aElement1 = view1.findClass(\"FragA:AElement\");\n expect(aElement1).to.not.be.undefined;\n\n // Re-requesting loads nothing new and returns the same instance with stable indices.\n const view2 = await iModel.getSchemaView({ schemas: [\"FragA\", \"FragB\"] });\n expect(view2).to.equal(view1);\n expect(view2.findClass(\"FragA:AElement\")!.idx).to.equal(aElement1!.idx);\n } finally {\n iModel.close();\n }\n });\n\n it(\"ignores schema names the iModel does not contain\", async () => {\n const iModel = await createIModelWithFragSchemas();\n try {\n const view = await iModel.getSchemaView({ schemas: [\"DoesNotExist\"] });\n expect(view.getSchema(\"DoesNotExist\")).to.be.undefined;\n // No real schemas requested; the view is a valid, empty husk.\n expect(view.schemaCount).to.equal(0);\n } finally {\n iModel.close();\n }\n });\n\n it(\"serializes overlapping concurrent loads without double-merging\", async () => {\n const iModel = await createIModelWithFragSchemas();\n try {\n // Fire overlapping requests whose closures share BisCore. The merge queue must coalesce so no\n // schema is merged twice (which would surface as duplicate classes).\n const [v1, v2] = await Promise.all([\n iModel.getSchemaView({ schemas: [\"FragA\"] }),\n iModel.getSchemaView({ schemas: [\"FragB\"] }),\n ]);\n expect(v2).to.equal(v1);\n\n // Exactly one BElement and one AElement - no duplicates from a double merge.\n let bElementCount = 0;\n let aElementCount = 0;\n for (const schema of v1.getSchemas()) {\n for (const cls of schema.getClasses()) {\n if (cls.fullName === \"FragB:BElement\") bElementCount++;\n if (cls.fullName === \"FragA:AElement\") aElementCount++;\n }\n }\n expect(bElementCount, \"BElement merged exactly once\").to.equal(1);\n expect(aElementCount, \"AElement merged exactly once\").to.equal(1);\n } finally {\n iModel.close();\n }\n });\n\n it(\"invalidates the subset husk after a schema import\", async () => {\n const iModel = await createIModelWithFragSchemas({ writable: true });\n try {\n const view1 = await iModel.getSchemaView({ schemas: [\"FragB\"] });\n expect(view1.getSchema(\"FragB\")).to.not.be.undefined;\n expect(view1.isOutdated).to.be.false;\n\n // Importing a schema calls clearCaches, which drops the husk and its loaded-set.\n await iModel.importSchemaStrings([schemaC]);\n expect(view1.isOutdated, \"the old husk is marked outdated\").to.be.true;\n\n // A fresh request rebuilds against the new schema state - a different instance that can now\n // load the newly imported schema.\n const view2 = await iModel.getSchemaView({ schemas: [\"FragC\"] });\n expect(view2, \"a new husk is built after invalidation\").to.not.equal(view1);\n expect(view2.findClass(\"FragC:CElement\")).to.not.be.undefined;\n } finally {\n iModel.close();\n }\n });\n\n it(\"the full view (no args) still contains everything the subset path can load\", async () => {\n const iModel = await createIModelWithFragSchemas();\n try {\n const full = await iModel.getSchemaView();\n expect(full.findClass(\"FragA:AElement\"), \"full view has the domain class\").to.not.be.undefined;\n expect(full.findClass(\"FragB:BElement\")).to.not.be.undefined;\n } finally {\n iModel.close();\n }\n });\n\n it(\"an unfiltered call after a filtered one merges the remaining schemas into the same view and collapses to full mode\", async () => {\n const iModel = await createIModelWithFragSchemas();\n try {\n // Start incremental: only FragB (+ BisCore) is loaded.\n const subsetView = await iModel.getSchemaView({ schemas: [\"FragB\"] });\n expect(subsetView.getSchema(\"FragA\")).to.be.undefined;\n\n // The unfiltered call means \"I need everything\": it must merge the rest into the SAME instance.\n const fullView = await iModel.getSchemaView();\n expect(fullView, \"the husk accumulates; no new instance\").to.equal(subsetView);\n expect(fullView.findClass(\"FragA:AElement\"), \"previously missing schema is now merged\").to.not.be.undefined;\n expect(fullView.findClass(\"FragB:BElement\"), \"earlier schemas remain available\").to.not.be.undefined;\n\n // The unfiltered merge must have collapsed the incremental bookkeeping into full mode: any\n // further request - filtered or not - is a synchronous no-op that issues no queries.\n const queryReaderSpy = sinon.spy(iModel, \"createQueryReader\");\n try {\n const filteredAgain = await iModel.getSchemaView({ schemas: [\"FragA\"] });\n const unfilteredAgain = await iModel.getSchemaView();\n expect(filteredAgain).to.equal(fullView);\n expect(unfilteredAgain).to.equal(fullView);\n expect(queryReaderSpy.notCalled, \"fully loaded view is served without any queries\").to.be.true;\n } finally {\n queryReaderSpy.restore();\n }\n } finally {\n iModel.close();\n }\n });\n\n it(\"filling the view schema-by-schema via filters collapses to full mode and matches a full load\", async () => {\n const iModel = await createIModelWithFragSchemas();\n try {\n // Request every schema the iModel contains, one filtered call at a time. The names come from\n // ECDbMeta (the manifest's own source), so nothing about the snapshot's schema inventory is\n // hardcoded - this also exercises requesting excluded schemas (e.g. CoreCustomAttributes)\n // directly, which must be tolerated and contribute nothing.\n const allSchemaNames = await queryAllSchemaNames(iModel);\n expect(allSchemaNames.length, \"snapshot contains more schemas than the two imported ones\").to.be.greaterThan(2);\n\n let accumulatingView: SchemaView | undefined;\n for (const schemaName of allSchemaNames) {\n const view = await iModel.getSchemaView({ schemas: [schemaName] });\n if (accumulatingView === undefined)\n accumulatingView = view;\n else\n expect(view, \"every filtered call returns the one accumulating instance\").to.equal(accumulatingView);\n }\n if (accumulatingView === undefined)\n expect.fail(\"no schema view was obtained\");\n\n // Once every schema has been requested, the view must have collapsed to full mode: an\n // unfiltered request is a synchronous no-op on the same instance, with no queries issued.\n const queryReaderSpy = sinon.spy(iModel, \"createQueryReader\");\n try {\n const fullRequest = await iModel.getSchemaView();\n expect(fullRequest).to.equal(accumulatingView);\n expect(queryReaderSpy.notCalled, \"collapsed view is served without any queries\").to.be.true;\n } finally {\n queryReaderSpy.restore();\n }\n\n // The fragment-filled view must be equivalent to a from-scratch full load of the same iModel:\n // same schemas present (both paths apply the same exclusion list in the native writer).\n const rebuiltFullView = await iModel.getSchemaView({ forceReload: true });\n expect(rebuiltFullView).to.not.equal(accumulatingView);\n expect(getSortedViewSchemaNames(accumulatingView), \"fragment fill and full load agree on the schema set\")\n .to.deep.equal(getSortedViewSchemaNames(rebuiltFullView));\n } finally {\n iModel.close();\n }\n });\n\n describe(\"forceReload\", () => {\n it(\"discards an accumulated husk and rebuilds from scratch\", async () => {\n const iModel = await createIModelWithFragSchemas();\n try {\n // Accumulate FragA + FragB into one husk.\n const view1 = await iModel.getSchemaView({ schemas: [\"FragA\"] });\n expect(view1.getSchema(\"FragB\")).to.not.be.undefined;\n expect(view1.isOutdated).to.be.false;\n\n // forceReload with a narrower filter: the old husk is dropped and marked outdated, and the\n // rebuilt view contains only the newly requested closure - FragA is gone.\n const view2 = await iModel.getSchemaView({ schemas: [\"FragB\"], forceReload: true });\n expect(view2).to.not.equal(view1);\n expect(view1.isOutdated, \"the discarded husk is marked outdated\").to.be.true;\n expect(view2.isOutdated).to.be.false;\n expect(view2.getSchema(\"FragB\")).to.not.be.undefined;\n expect(view2.getSchema(\"FragA\"), \"rebuild starts from scratch; earlier schemas are not carried over\").to.be.undefined;\n } finally {\n iModel.close();\n }\n });\n\n it(\"rebuilds a fully loaded view\", async () => {\n const iModel = await createIModelWithFragSchemas();\n try {\n const view1 = await iModel.getSchemaView();\n const view2 = await iModel.getSchemaView({ forceReload: true });\n expect(view2).to.not.equal(view1);\n expect(view1.isOutdated).to.be.true;\n expect(view2.isOutdated).to.be.false;\n // The rebuilt view is complete again.\n expect(getSortedViewSchemaNames(view2)).to.deep.equal(getSortedViewSchemaNames(view1));\n } finally {\n iModel.close();\n }\n });\n\n it(\"is serialized behind an in-flight load\", async () => {\n const iModel = await createIModelWithFragSchemas();\n try {\n // Fire a load and a forceReload without awaiting in between. The reload must wait for the\n // first load to finish, then discard its result - never tearing down state mid-load.\n const [view1, view2] = await Promise.all([\n iModel.getSchemaView({ schemas: [\"FragA\"] }),\n iModel.getSchemaView({ schemas: [\"FragA\"], forceReload: true }),\n ]);\n expect(view2).to.not.equal(view1);\n expect(view1.isOutdated, \"the first load's view was discarded by the reload\").to.be.true;\n expect(view2.isOutdated).to.be.false;\n expect(view2.findClass(\"FragA:AElement\"), \"the rebuilt view is fully usable\").to.not.be.undefined;\n } finally {\n iModel.close();\n }\n });\n });\n\n describe(\"PRAGMA schema_view_fragment version prefix\", () => {\n // The frontend must pin the blob format version (frontend and backend can be version-skewed),\n // so it will issue the pragma with the `v<N>;` prefix. These tests prove the prefix contract\n // works end to end through ConcurrentQuery, not just in the native unit tests.\n\n /** Fetch one fragment blob directly via the pragma. Calls `next()` exactly once - PRAGMA\n * results must not be iterated, since ConcurrentQuery cannot paginate them. */\n async function fetchFragmentBlob(iModel: StandaloneDb, argument: string): Promise<{ data: Uint8Array, formatVersion: number }> {\n const reader = iModel.createQueryReader(`PRAGMA schema_view_fragment('${argument}')`);\n const result = await reader.next();\n expect(result.done, \"pragma returned a row\").to.be.false;\n const data = result.value.data as Uint8Array | undefined;\n if (data === undefined || data === null)\n expect.fail(\"pragma returned no data column\");\n return { data, formatVersion: result.value.formatVersion as number };\n }\n\n it(\"accepts a v1; prefix and returns the same blob as the unprefixed form\", async () => {\n const iModel = await createIModelWithFragSchemas();\n try {\n const nameList = (await queryAllSchemaNames(iModel)).join(\",\");\n\n const prefixed = await fetchFragmentBlob(iModel, `v${schemaViewFormatVersion};${nameList}`);\n expect(prefixed.formatVersion, \"reported format version matches the requested one\").to.equal(schemaViewFormatVersion);\n\n // Omitting the prefix means \"latest\", which today is the same version - identical blob bytes.\n const unprefixed = await fetchFragmentBlob(iModel, nameList);\n expect(unprefixed.formatVersion).to.equal(schemaViewFormatVersion);\n expect(Buffer.from(prefixed.data).equals(Buffer.from(unprefixed.data)), \"explicit version and latest produce identical blobs\").to.be.true;\n\n // The prefixed blob is a valid fragment end to end: it merges into a husk and resolves classes.\n const husk = SchemaView.createMergeable();\n husk.mergeFragment(prefixed.data);\n expect(husk.findClass(\"FragA:AElement\")).to.not.be.undefined;\n expect(husk.findClass(\"FragB:BElement\")).to.not.be.undefined;\n } finally {\n iModel.close();\n }\n });\n\n it(\"rejects malformed and unsupported version prefixes\", async () => {\n const iModel = await createIModelWithFragSchemas();\n try {\n const nameList = (await queryAllSchemaNames(iModel)).join(\",\");\n const invalidArguments = [\n `v99;${nameList}`, // unsupported version\n `v;${nameList}`, // malformed version token (no digits)\n `vx;${nameList}`, // malformed version token (non-digit)\n \"v1;\", // version present, empty name list\n ];\n // Native rejects these at prepare time; ConcurrentQuery surfaces that as a rejected read.\n for (const argument of invalidArguments) {\n const reader = iModel.createQueryReader(`PRAGMA schema_view_fragment('${argument}')`);\n let rejected = false;\n try {\n await reader.next();\n } catch {\n rejected = true;\n }\n expect(rejected, `'${argument}' is rejected`).to.be.true;\n }\n } finally {\n iModel.close();\n }\n });\n });\n\n it(\"loads a real domain schema's reference closure, dropping references that are excluded\", async () => {\n // Walk against real schemas. Generic references BisCore plus three schemas that are all on SchemaView's\n // exclusion list. BisCore in turn references four schemas that are ALL excluded.\n // So requesting Generic must yield a view containing exactly Generic + BisCore - the walk\n // pulls BisCore, and every excluded reference contributes no rows.\n const iModel = StandaloneDb.openFile(genericSeedDb.pathName, OpenMode.Readonly);\n try {\n // Capture native warnings and errors while the fragment blob is written + parsed.\n // assert nothing was logged as a safeguard against regressions.\n let schemaView: Awaited<ReturnType<typeof iModel.getSchemaView>> | undefined;\n const nativeLogs = await captureNativeLogs(async () => {\n schemaView = await iModel.getSchemaView({ schemas: [\"Generic\"] });\n });\n expect(\n nativeLogs,\n `native warnings/errors during getSchemaView:\\n${nativeLogs.map((l) => `${l.level} | ${l.category} | ${l.message}`).join(\"\\n\")}`,\n ).to.be.empty;\n expect(schemaView, \"schema view was obtained\").to.not.be.undefined;\n if (!schemaView)\n return;\n\n // The requested schema and its one non-excluded reference are present.\n expect(schemaView.getSchema(\"Generic\"), \"Generic was requested\").to.not.be.undefined;\n expect(schemaView.getSchema(\"BisCore\"), \"BisCore is Generic's only non-excluded reference\").to.not.be.undefined;\n\n // Every excluded reference in the closure contributes nothing to the view.\n for (const excluded of [\"CoreCustomAttributes\", \"BisCustomAttributes\", \"ECDbMap\", \"ECDbSchemaPolicies\"])\n expect(schemaView.getSchema(excluded), `${excluded} is excluded from SchemaView`).to.be.undefined;\n\n // The view contains exactly the two non-excluded schemas - nothing leaked in from the closure.\n expect(schemaView.schemaCount, \"view holds exactly Generic + BisCore\").to.equal(2);\n\n // A cross-schema base-class reference resolves across the loaded closure.\n const physicalObject = schemaView.findClass(\"Generic:PhysicalObject\");\n expect(physicalObject, \"Generic:PhysicalObject is loaded\").to.not.be.undefined;\n expect(physicalObject!.is(\"BisCore:PhysicalElement\"), \"resolves up into BisCore\").to.be.true;\n\n // PhysicalObject's immediate base is bis:PhysicalElement, resolved across the schema boundary.\n const baseClass = physicalObject!.baseClass;\n expect(baseClass, \"PhysicalObject has a base class\").to.not.be.undefined;\n expect(baseClass!.fullName, \"base class is bis:PhysicalElement\").to.equal(\"BisCore:PhysicalElement\");\n\n // PhysicalObject defines no own properties, so walking its properties must surface only the\n // ones inherited from the BisCore ancestor chain (PhysicalElement -> ... -> Element). This\n // proves the cross-schema property inheritance walk is hydrated correctly.\n expect(physicalObject!.getOwnProperties(), \"PhysicalObject has no own properties\").to.have.lengthOf(0);\n\n // Expected primitive type for a sampling of inherited primitive properties, one (or more) from\n // each ancestor.\n const expectedPrimitiveTypes = new Map<string, SchemaViewPrimitiveType>([\n [\"FederationGuid\", SchemaViewPrimitiveType.Binary], // Element, binary\n [\"CodeValue\", SchemaViewPrimitiveType.String], // Element, string\n [\"UserLabel\", SchemaViewPrimitiveType.String], // Element, string\n [\"LastMod\", SchemaViewPrimitiveType.DateTime], // Element, dateTime\n [\"InSpatialIndex\", SchemaViewPrimitiveType.Boolean], // GeometricElement3d, boolean\n [\"Origin\", SchemaViewPrimitiveType.Point3d], // GeometricElement3d, point3d\n [\"Yaw\", SchemaViewPrimitiveType.Double], // GeometricElement3d, double\n [\"GeometryStream\", SchemaViewPrimitiveType.Binary], // GeometricElement3d, binary\n ]);\n // Navigation properties contributed by the chain\n const expectedNavProperties = [\"Model\", \"CodeSpec\", \"Category\", \"PhysicalMaterial\"];\n\n // First walk: getProperties() returns the full inherited set. Verify each expected property is\n // present and, for primitives, that its primitive type survived hydration intact.\n const propertiesByName = new Map(physicalObject!.getProperties().map((p) => [p.name, p]));\n for (const [name, primitiveType] of expectedPrimitiveTypes) {\n const property = propertiesByName.get(name);\n expect(property, `inherited property \"${name}\" is present`).to.not.be.undefined;\n if (!property) continue; // narrows for the type checker; expect already failed if undefined\n if (!property.isPrimitive())\n expect.fail(`inherited property \"${name}\" should be primitive`);\n expect(property.primitiveType, `\"${name}\" primitive type`).to.equal(primitiveType);\n }\n for (const name of expectedNavProperties) {\n const property = propertiesByName.get(name);\n expect(property, `inherited navigation property \"${name}\" is present`).to.not.be.undefined;\n if (!property) continue;\n expect(property.isNavigation(), `\"${name}\" is a navigation property`).to.be.true;\n }\n\n // Second walk: the single getProperty(name) accessor resolves the same inherited properties\n // (case-insensitively) and reports the same primitive types.\n for (const [name, primitiveType] of expectedPrimitiveTypes) {\n const property = physicalObject!.getProperty(name);\n expect(property, `getProperty(\"${name}\") resolves`).to.not.be.undefined;\n if (!property) continue;\n if (!property.isPrimitive())\n expect.fail(`getProperty(\"${name}\") should be primitive`);\n expect(property.primitiveType, `getProperty(\"${name}\") primitive type`).to.equal(primitiveType);\n }\n } finally {\n iModel.close();\n }\n });\n});\n"]}
@@ -54,7 +54,7 @@ describe("SchemaView lifecycle", () => {
54
54
  expect(ctx1.findClass("SchemaViewLifecycleTest:TestElement")).to.be.undefined;
55
55
  expect(ctx1.isOutdated).to.be.false;
56
56
  // Import v1 schema - adds TestElement with PropA
57
- // importSchemaStrings calls clearCaches which immediately invalidates _schemasPromise.
57
+ // importSchemaStrings calls clearCaches which immediately invalidates the cached schema view.
58
58
  await bc.importSchemaStrings([testSchemaV1]);
59
59
  // importSchemaStrings calls clearCaches which immediately invalidates the cached view
60
60
  const ctx2 = await bc.getSchemaView();
@@ -105,7 +105,7 @@ describe("SchemaView lifecycle", () => {
105
105
  await bc1.pushChanges({ accessToken: "user1", description: "push v1" });
106
106
  // bc2: pull changes
107
107
  await bc2.pullChanges();
108
- // After pulling a schema changeset, clearCaches is called which immediately nulls _schemasPromise.
108
+ // After pulling a schema changeset, clearCaches is called which immediately drops the cached schema view.
109
109
  const ctxAfterPull = await bc2.getSchemaView();
110
110
  expect(ctxBefore.isOutdated).to.be.true;
111
111
  const testClass = ctxAfterPull.findClass("SchemaViewLifecycleTest:TestElement");
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaViewLifecycle.test.js","sourceRoot":"","sources":["../../../../src/test/schema/SchemaViewLifecycle.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 { Guid } from \"@itwin/core-bentley\";\nimport { expect } from \"chai\";\nimport { ChannelControl } from \"../../ChannelControl\";\nimport { HubMock } from \"../../internal/HubMock\";\nimport { HubWrappers } from \"../IModelTestUtils\";\nimport { KnownTestLocations } from \"../KnownTestLocations\";\nimport { TestUtils } from \"../TestUtils\";\n\n/** Simple test schema that will be imported to test cache lifecycle. */\nconst testSchemaV1 = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <ECSchema schemaName=\"SchemaViewLifecycleTest\" alias=\"rslt\" version=\"01.00.00\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\n <ECSchemaReference name=\"BisCore\" version=\"01.00.00\" alias=\"bis\"/>\n <ECEntityClass typeName=\"TestElement\">\n <BaseClass>bis:PhysicalElement</BaseClass>\n <ECProperty propertyName=\"PropA\" typeName=\"string\"/>\n </ECEntityClass>\n </ECSchema>`;\n\n/** Updated schema with an additional property. */\nconst testSchemaV2 = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <ECSchema schemaName=\"SchemaViewLifecycleTest\" alias=\"rslt\" version=\"01.00.01\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\n <ECSchemaReference name=\"BisCore\" version=\"01.00.00\" alias=\"bis\"/>\n <ECEntityClass typeName=\"TestElement\">\n <BaseClass>bis:PhysicalElement</BaseClass>\n <ECProperty propertyName=\"PropA\" typeName=\"string\"/>\n <ECProperty propertyName=\"PropB\" typeName=\"int\"/>\n </ECEntityClass>\n </ECSchema>`;\n\ndescribe(\"SchemaView lifecycle\", () => {\n let iModelId: string;\n\n before(async () => {\n HubMock.startup(\"SchemaViewLifecycle\", KnownTestLocations.outputDir);\n await TestUtils.shutdownBackend();\n await TestUtils.startBackend();\n });\n\n after(async () => {\n HubMock.shutdown();\n await TestUtils.shutdownBackend();\n await TestUtils.startBackend();\n });\n\n beforeEach(async () => {\n iModelId = await HubWrappers.createIModel(\"user1\", HubMock.iTwinId, `RSLifecycle-${Guid.createValue()}`);\n });\n\n afterEach(async () => {\n await HubMock.deleteIModel({ accessToken: \"user1\", iTwinId: HubMock.iTwinId, iModelId });\n });\n\n it(\"getSchemaView reflects imported schema after importSchemaStrings\", async () => {\n // Open a briefcase, get initial context\n const bc = await HubWrappers.downloadAndOpenBriefcase({ accessToken: \"user1\", iTwinId: HubMock.iTwinId, iModelId });\n bc.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n\n const ctx1 = await bc.getSchemaView();\n expect(ctx1.findClass(\"SchemaViewLifecycleTest:TestElement\")).to.be.undefined;\n expect(ctx1.isOutdated).to.be.false;\n\n // Import v1 schema - adds TestElement with PropA\n // importSchemaStrings calls clearCaches which immediately invalidates _schemasPromise.\n await bc.importSchemaStrings([testSchemaV1]);\n\n // importSchemaStrings calls clearCaches which immediately invalidates the cached view\n const ctx2 = await bc.getSchemaView();\n expect(ctx1.isOutdated).to.be.true;\n expect(ctx2.isOutdated).to.be.false;\n\n const testClass1 = ctx2.findClass(\"SchemaViewLifecycleTest:TestElement\");\n expect(testClass1).to.not.be.undefined;\n expect(testClass1!.getOwnProperties().find((p) => p.name === \"PropA\")).to.not.be.undefined;\n expect(testClass1!.getOwnProperties().find((p) => p.name === \"PropB\")).to.be.undefined;\n\n // Import v2 schema - adds PropB\n await bc.importSchemaStrings([testSchemaV2]);\n\n // cache is again invalidated automatically\n const ctx3 = await bc.getSchemaView();\n expect(ctx2.isOutdated).to.be.true;\n expect(ctx3.isOutdated).to.be.false;\n\n const testClass2 = ctx3.findClass(\"SchemaViewLifecycleTest:TestElement\");\n expect(testClass2).to.not.be.undefined;\n expect(testClass2!.getOwnProperties().find((p) => p.name === \"PropB\")).to.not.be.undefined;\n\n bc.close();\n });\n\n it(\"getSchemas on second briefcase reflects schema pushed from first\", async () => {\n // bc1 imports a schema and pushes\n const bc1 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: \"user1\", iTwinId: HubMock.iTwinId, iModelId });\n bc1.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n\n await bc1.importSchemaStrings([testSchemaV1]);\n await bc1.pushChanges({ accessToken: \"user1\", description: \"push v1 schema\" });\n\n // bc2 pulls and should see the new schema\n const bc2 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: \"user1\", iTwinId: HubMock.iTwinId, iModelId });\n bc2.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n\n const ctx = await bc2.getSchemaView();\n const testClass = ctx.findClass(\"SchemaViewLifecycleTest:TestElement\");\n expect(testClass).to.not.be.undefined;\n expect(testClass!.getOwnProperties().find((p) => p.name === \"PropA\")).to.not.be.undefined;\n\n bc1.close();\n bc2.close();\n });\n\n it(\"pullChanges invalidates cached SchemaView\", async () => {\n // bc1 will push schema changes; bc2 will pull them\n const bc1 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: \"user1\", iTwinId: HubMock.iTwinId, iModelId });\n bc1.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const bc2 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: \"user1\", iTwinId: HubMock.iTwinId, iModelId });\n bc2.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n\n // bc2 gets initial context (no test schema)\n const ctxBefore = await bc2.getSchemaView();\n expect(ctxBefore.findClass(\"SchemaViewLifecycleTest:TestElement\")).to.be.undefined;\n\n // bc1: import v1 + push\n await bc1.importSchemaStrings([testSchemaV1]);\n await bc1.pushChanges({ accessToken: \"user1\", description: \"push v1\" });\n\n // bc2: pull changes\n await bc2.pullChanges();\n\n // After pulling a schema changeset, clearCaches is called which immediately nulls _schemasPromise.\n const ctxAfterPull = await bc2.getSchemaView();\n expect(ctxBefore.isOutdated).to.be.true;\n const testClass = ctxAfterPull.findClass(\"SchemaViewLifecycleTest:TestElement\");\n expect(testClass).to.not.be.undefined;\n\n // bc1: import v2 + push\n await bc1.importSchemaStrings([testSchemaV2]);\n await bc1.pushChanges({ accessToken: \"user1\", description: \"push v2\" });\n\n // bc2: pull again\n await bc2.pullChanges();\n const ctxAfterPull2 = await bc2.getSchemaView();\n expect(ctxAfterPull.isOutdated).to.be.true;\n const updated = ctxAfterPull2.findClass(\"SchemaViewLifecycleTest:TestElement\");\n expect(updated).to.not.be.undefined;\n expect(updated!.getOwnProperties().find((p) => p.name === \"PropB\")).to.not.be.undefined;\n\n bc1.close();\n bc2.close();\n });\n\n it(\"concurrent getSchemaView calls share a single hydration\", async () => {\n const bc = await HubWrappers.downloadAndOpenBriefcase({ accessToken: \"user1\", iTwinId: HubMock.iTwinId, iModelId });\n bc.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n\n // Fire multiple concurrent getSchemaView calls - they should all resolve to the same context\n const [ctx1, ctx2, ctx3] = await Promise.all([\n bc.getSchemaView(),\n bc.getSchemaView(),\n bc.getSchemaView(),\n ]);\n\n expect(ctx1).to.equal(ctx2);\n expect(ctx2).to.equal(ctx3);\n expect(ctx1.isOutdated).to.be.false;\n\n bc.close();\n });\n});\n"]}
1
+ {"version":3,"file":"SchemaViewLifecycle.test.js","sourceRoot":"","sources":["../../../../src/test/schema/SchemaViewLifecycle.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 { Guid } from \"@itwin/core-bentley\";\nimport { expect } from \"chai\";\nimport { ChannelControl } from \"../../ChannelControl\";\nimport { HubMock } from \"../../internal/HubMock\";\nimport { HubWrappers } from \"../IModelTestUtils\";\nimport { KnownTestLocations } from \"../KnownTestLocations\";\nimport { TestUtils } from \"../TestUtils\";\n\n/** Simple test schema that will be imported to test cache lifecycle. */\nconst testSchemaV1 = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <ECSchema schemaName=\"SchemaViewLifecycleTest\" alias=\"rslt\" version=\"01.00.00\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\n <ECSchemaReference name=\"BisCore\" version=\"01.00.00\" alias=\"bis\"/>\n <ECEntityClass typeName=\"TestElement\">\n <BaseClass>bis:PhysicalElement</BaseClass>\n <ECProperty propertyName=\"PropA\" typeName=\"string\"/>\n </ECEntityClass>\n </ECSchema>`;\n\n/** Updated schema with an additional property. */\nconst testSchemaV2 = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <ECSchema schemaName=\"SchemaViewLifecycleTest\" alias=\"rslt\" version=\"01.00.01\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\n <ECSchemaReference name=\"BisCore\" version=\"01.00.00\" alias=\"bis\"/>\n <ECEntityClass typeName=\"TestElement\">\n <BaseClass>bis:PhysicalElement</BaseClass>\n <ECProperty propertyName=\"PropA\" typeName=\"string\"/>\n <ECProperty propertyName=\"PropB\" typeName=\"int\"/>\n </ECEntityClass>\n </ECSchema>`;\n\ndescribe(\"SchemaView lifecycle\", () => {\n let iModelId: string;\n\n before(async () => {\n HubMock.startup(\"SchemaViewLifecycle\", KnownTestLocations.outputDir);\n await TestUtils.shutdownBackend();\n await TestUtils.startBackend();\n });\n\n after(async () => {\n HubMock.shutdown();\n await TestUtils.shutdownBackend();\n await TestUtils.startBackend();\n });\n\n beforeEach(async () => {\n iModelId = await HubWrappers.createIModel(\"user1\", HubMock.iTwinId, `RSLifecycle-${Guid.createValue()}`);\n });\n\n afterEach(async () => {\n await HubMock.deleteIModel({ accessToken: \"user1\", iTwinId: HubMock.iTwinId, iModelId });\n });\n\n it(\"getSchemaView reflects imported schema after importSchemaStrings\", async () => {\n // Open a briefcase, get initial context\n const bc = await HubWrappers.downloadAndOpenBriefcase({ accessToken: \"user1\", iTwinId: HubMock.iTwinId, iModelId });\n bc.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n\n const ctx1 = await bc.getSchemaView();\n expect(ctx1.findClass(\"SchemaViewLifecycleTest:TestElement\")).to.be.undefined;\n expect(ctx1.isOutdated).to.be.false;\n\n // Import v1 schema - adds TestElement with PropA\n // importSchemaStrings calls clearCaches which immediately invalidates the cached schema view.\n await bc.importSchemaStrings([testSchemaV1]);\n\n // importSchemaStrings calls clearCaches which immediately invalidates the cached view\n const ctx2 = await bc.getSchemaView();\n expect(ctx1.isOutdated).to.be.true;\n expect(ctx2.isOutdated).to.be.false;\n\n const testClass1 = ctx2.findClass(\"SchemaViewLifecycleTest:TestElement\");\n expect(testClass1).to.not.be.undefined;\n expect(testClass1!.getOwnProperties().find((p) => p.name === \"PropA\")).to.not.be.undefined;\n expect(testClass1!.getOwnProperties().find((p) => p.name === \"PropB\")).to.be.undefined;\n\n // Import v2 schema - adds PropB\n await bc.importSchemaStrings([testSchemaV2]);\n\n // cache is again invalidated automatically\n const ctx3 = await bc.getSchemaView();\n expect(ctx2.isOutdated).to.be.true;\n expect(ctx3.isOutdated).to.be.false;\n\n const testClass2 = ctx3.findClass(\"SchemaViewLifecycleTest:TestElement\");\n expect(testClass2).to.not.be.undefined;\n expect(testClass2!.getOwnProperties().find((p) => p.name === \"PropB\")).to.not.be.undefined;\n\n bc.close();\n });\n\n it(\"getSchemas on second briefcase reflects schema pushed from first\", async () => {\n // bc1 imports a schema and pushes\n const bc1 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: \"user1\", iTwinId: HubMock.iTwinId, iModelId });\n bc1.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n\n await bc1.importSchemaStrings([testSchemaV1]);\n await bc1.pushChanges({ accessToken: \"user1\", description: \"push v1 schema\" });\n\n // bc2 pulls and should see the new schema\n const bc2 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: \"user1\", iTwinId: HubMock.iTwinId, iModelId });\n bc2.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n\n const ctx = await bc2.getSchemaView();\n const testClass = ctx.findClass(\"SchemaViewLifecycleTest:TestElement\");\n expect(testClass).to.not.be.undefined;\n expect(testClass!.getOwnProperties().find((p) => p.name === \"PropA\")).to.not.be.undefined;\n\n bc1.close();\n bc2.close();\n });\n\n it(\"pullChanges invalidates cached SchemaView\", async () => {\n // bc1 will push schema changes; bc2 will pull them\n const bc1 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: \"user1\", iTwinId: HubMock.iTwinId, iModelId });\n bc1.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const bc2 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: \"user1\", iTwinId: HubMock.iTwinId, iModelId });\n bc2.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n\n // bc2 gets initial context (no test schema)\n const ctxBefore = await bc2.getSchemaView();\n expect(ctxBefore.findClass(\"SchemaViewLifecycleTest:TestElement\")).to.be.undefined;\n\n // bc1: import v1 + push\n await bc1.importSchemaStrings([testSchemaV1]);\n await bc1.pushChanges({ accessToken: \"user1\", description: \"push v1\" });\n\n // bc2: pull changes\n await bc2.pullChanges();\n\n // After pulling a schema changeset, clearCaches is called which immediately drops the cached schema view.\n const ctxAfterPull = await bc2.getSchemaView();\n expect(ctxBefore.isOutdated).to.be.true;\n const testClass = ctxAfterPull.findClass(\"SchemaViewLifecycleTest:TestElement\");\n expect(testClass).to.not.be.undefined;\n\n // bc1: import v2 + push\n await bc1.importSchemaStrings([testSchemaV2]);\n await bc1.pushChanges({ accessToken: \"user1\", description: \"push v2\" });\n\n // bc2: pull again\n await bc2.pullChanges();\n const ctxAfterPull2 = await bc2.getSchemaView();\n expect(ctxAfterPull.isOutdated).to.be.true;\n const updated = ctxAfterPull2.findClass(\"SchemaViewLifecycleTest:TestElement\");\n expect(updated).to.not.be.undefined;\n expect(updated!.getOwnProperties().find((p) => p.name === \"PropB\")).to.not.be.undefined;\n\n bc1.close();\n bc2.close();\n });\n\n it(\"concurrent getSchemaView calls share a single hydration\", async () => {\n const bc = await HubWrappers.downloadAndOpenBriefcase({ accessToken: \"user1\", iTwinId: HubMock.iTwinId, iModelId });\n bc.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n\n // Fire multiple concurrent getSchemaView calls - they should all resolve to the same context\n const [ctx1, ctx2, ctx3] = await Promise.all([\n bc.getSchemaView(),\n bc.getSchemaView(),\n bc.getSchemaView(),\n ]);\n\n expect(ctx1).to.equal(ctx2);\n expect(ctx2).to.equal(ctx3);\n expect(ctx1.isOutdated).to.be.false;\n\n bc.close();\n });\n});\n"]}
@@ -37,7 +37,7 @@ async function assertThrowsAsync(test, msg) {
37
37
  }
38
38
  throw new Error(`Failed to throw error with message: "${msg}"`);
39
39
  }
40
- describe.skip("Merge conflict & locking", () => {
40
+ describe("Merge conflict & locking", () => {
41
41
  let iTwinId;
42
42
  before(() => {
43
43
  HubMock.startup("MergeConflictTest", KnownTestLocations.outputDir);
@@ -1 +1 @@
1
- {"version":3,"file":"MergeConflict.test.js","sourceRoot":"","sources":["../../../../src/test/standalone/MergeConflict.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\nimport { GuidString, Id64String } from \"@itwin/core-bentley\";\nimport { EditTxn, withEditTxn } from \"../../EditTxn\";\nimport {\n ElementAspectProps,\n IModel,\n SubCategoryAppearance,\n} from \"@itwin/core-common\";\nimport * as chai from \"chai\";\nimport { assert, expect } from \"chai\";\nimport * as chaiAsPromised from \"chai-as-promised\";\nimport { HubWrappers, KnownTestLocations } from \"../\";\nimport { HubMock } from \"../../internal/HubMock\";\nimport {\n BriefcaseDb,\n ChannelControl,\n DictionaryModel,\n ExternalSourceAspect,\n SpatialCategory,\n SqliteChangeOp,\n} from \"../../core-backend\";\nimport { IModelTestUtils, TestUserType } from \"../IModelTestUtils\";\nimport { RebaseChangesetConflictArgs, SqliteConflictCause } from \"../../internal/ChangesetConflictArgs\";\nchai.use(chaiAsPromised);\nimport * as sinon from \"sinon\";\n\nexport async function createNewModelAndCategory(txn: EditTxn, parent?: Id64String) {\n const rwIModel = txn.iModel as BriefcaseDb;\n // Create a new physical model.\n const [, modelId] = await IModelTestUtils.createAndInsertPhysicalPartitionAndModelAsync(txn, IModelTestUtils.getUniqueModelCode(rwIModel, \"newPhysicalModel\"), true, parent);\n\n // Find or create a SpatialCategory.\n const dictionary: DictionaryModel = rwIModel.models.getModel<DictionaryModel>(IModel.dictionaryId);\n const newCategoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, \"ThisTestSpatialCategory\");\n const category = SpatialCategory.create(rwIModel, IModel.dictionaryId, newCategoryCode.value);\n const spatialCategoryId = txn.insertElement(category.toJSON());\n category.setDefaultAppearance(txn, new SubCategoryAppearance({ color: 0xff0000 }));\n\n return { modelId, spatialCategoryId };\n}\n\nasync function assertThrowsAsync<T>(test: () => Promise<T>, msg?: string) {\n try {\n await test();\n } catch (e) {\n if (e instanceof Error && msg) {\n assert.equal(e.message, msg);\n }\n return;\n }\n throw new Error(`Failed to throw error with message: \"${msg}\"`);\n}\n\ndescribe.skip(\"Merge conflict & locking\", () => { // ###TODO FLAKY https://github.com/iTwin/itwinjs-core/issues/7730\n let iTwinId: GuidString;\n\n before(() => {\n HubMock.startup(\"MergeConflictTest\", KnownTestLocations.outputDir);\n iTwinId = HubMock.iTwinId;\n });\n after(() => HubMock.shutdown());\n\n it(\"pull/merge causing update conflict - dirty read/modify (with no lock)\", async () => {\n /**\n * To simulate a a data conflict for dirty read we update same aspect from two different briefcases\n * and when the second briefcase try to push its changes it will fail with following error.\n * \"UPDATE/DELETE before value do not match with one in db or CASCADE action was triggered.\"\n */\n const accessToken1 = await HubWrappers.getAccessToken(TestUserType.SuperManager);\n const accessToken2 = await HubWrappers.getAccessToken(TestUserType.Regular);\n const accessToken3 = await HubWrappers.getAccessToken(TestUserType.Super);\n\n // Delete any existing iModels with the same name as the read-write test iModel\n const iModelName = \"TestIModel\";\n\n // Create a new empty iModel on the Hub & obtain a briefcase\n const rwIModelId = await HubMock.createNewIModel({ accessToken: accessToken1, iTwinId, iModelName, description: \"TestSubject\", noLocks: undefined });\n assert.isNotEmpty(rwIModelId);\n\n // to reproduce the issue we will disable locks altogether.\n const b1 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken1, iTwinId, iModelId: rwIModelId, noLock: true });\n b1.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b2 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken2, iTwinId, iModelId: rwIModelId, noLock: true });\n b2.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b3 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken3, iTwinId, iModelId: rwIModelId, noLock: true });\n const b1Txn = new EditTxn(b1, \"merge conflict\");\n b1Txn.start();\n const b2Txn = new EditTxn(b2, \"merge conflict\");\n b2Txn.start();\n\n // create and insert a new model with code1\n const [, modelId] = IModelTestUtils.createAndInsertPhysicalPartitionAndModel(\n b1Txn,\n IModelTestUtils.getUniqueModelCode(b1, \"newPhysicalModel\"),\n true);\n\n const dictionary: DictionaryModel = b1.models.getModel<DictionaryModel>(IModel.dictionaryId);\n const newCategoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, \"ThisTestSpatialCategory\");\n\n const spatialCategoryId = SpatialCategory.insert(\n b1Txn,\n dictionary.id,\n newCategoryCode.value,\n new SubCategoryAppearance({ color: 0xff0000 }),\n );\n\n // insert element and aspect\n const el1 = b1Txn.insertElement(IModelTestUtils.createPhysicalObject(b1, modelId, spatialCategoryId).toJSON());\n await b1.pullChanges();\n const aspectId1 = b1Txn.insertAspect({\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier\",\n } as ElementAspectProps);\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `inserted element with aspect ${el1}` });\n\n // b1 same as b2 and now both will modify same aspect\n await b2.pullChanges();\n\n // b1 will change identifier from \"test identifier\" to \"test identifier (modified by b1)\"\n b1Txn.updateAspect({\n id: aspectId1,\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier (modified by b1)\",\n } as ElementAspectProps);\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `modify aspect ${aspectId1} with no lock` });\n\n // b2 will change identifier from \"test identifier\" to \"test identifier (modified by b2)\"\n b2Txn.updateAspect({\n id: aspectId1,\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier (modified by b2)\",\n } as ElementAspectProps);\n b2Txn.saveChanges();\n\n const conflicts: {\n cause: SqliteConflictCause,\n tableName: string,\n opcode?: SqliteChangeOp,\n id: Id64String,\n }[] = [];\n\n // we will not handle conflict and let the default conflict handler deal with it.\n b2.txns.rebaser.addConflictHandler({\n id: \"custom\", handler: (arg: RebaseChangesetConflictArgs) => {\n conflicts.push({\n cause: arg.cause,\n tableName: arg.tableName,\n opcode: arg.opcode,\n id: arg.getValueId(0, arg.opcode === \"Inserted\" ? \"New\" : \"Old\") as Id64String,\n });\n return undefined;\n }\n });\n\n await b2.pushChanges({ accessToken: accessToken1, description: `modify aspect ${aspectId1} with no lock` });\n\n expect(conflicts.length).to.be.equals(3);\n\n chai.expect(\n [\n {\n \"cause\": \"Data\",\n \"tableName\": \"bis_Element\",\n \"opcode\": \"Updated\",\n \"id\": \"0x20000000004\"\n },\n {\n \"cause\": \"Data\",\n \"tableName\": \"bis_ElementMultiAspect\",\n \"opcode\": \"Updated\",\n \"id\": \"0x20000000001\"\n },\n {\n \"cause\": \"Data\",\n \"tableName\": \"bis_Model\",\n \"opcode\": \"Updated\",\n \"id\": \"0x20000000001\"\n }\n ]).to.be.deep.equals(conflicts);\n\n await b3.pullChanges();\n await b1.pullChanges();\n\n // b2 win as default conflict handler choose Replace to override local changes over master.\n (b2.elements.getAspect(aspectId1) as ExternalSourceAspect).identifier = \"test identifier (modified by b2)\";\n (b3.elements.getAspect(aspectId1) as ExternalSourceAspect).identifier = \"test identifier (modified by b2)\";\n (b1.elements.getAspect(aspectId1) as ExternalSourceAspect).identifier = \"test identifier (modified by b2)\";\n\n b1.close();\n b2.close();\n b3.close();\n });\n it(\"pull/merge causing update conflict - update causing local changes (with no lock)\", async () => {\n /**\n * To simulate a a data conflict for dirty read we update same aspect from two different briefcases\n * and when the second briefcase try to push its changes it will fail with following error.\n * \"UPDATE/DELETE before value do not match with one in db or CASCADE action was triggered.\"\n */\n const accessToken1 = await HubWrappers.getAccessToken(TestUserType.SuperManager);\n const accessToken2 = await HubWrappers.getAccessToken(TestUserType.Regular);\n const accessToken3 = await HubWrappers.getAccessToken(TestUserType.Super);\n\n // Delete any existing iModels with the same name as the read-write test iModel\n const iModelName = \"TestIModel\";\n\n // Create a new empty iModel on the Hub & obtain a briefcase\n const rwIModelId = await HubMock.createNewIModel({ accessToken: accessToken1, iTwinId, iModelName, description: \"TestSubject\", noLocks: undefined });\n assert.isNotEmpty(rwIModelId);\n\n // to reproduce the issue we will disable locks altogether.\n const b1 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken1, iTwinId, iModelId: rwIModelId, noLock: true });\n b1.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b2 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken2, iTwinId, iModelId: rwIModelId, noLock: true });\n b2.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b3 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken3, iTwinId, iModelId: rwIModelId, noLock: true });\n const b1Txn = new EditTxn(b1, \"merge conflict\");\n b1Txn.start();\n const b2Txn = new EditTxn(b2, \"merge conflict\");\n b2Txn.start();\n\n // create and insert a new model with code1\n const [, modelId] = IModelTestUtils.createAndInsertPhysicalPartitionAndModel(\n b1Txn,\n IModelTestUtils.getUniqueModelCode(b1, \"newPhysicalModel\"),\n true);\n\n const dictionary: DictionaryModel = b1.models.getModel<DictionaryModel>(IModel.dictionaryId);\n const newCategoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, \"ThisTestSpatialCategory\");\n\n const spatialCategoryId = SpatialCategory.insert(\n b1Txn,\n dictionary.id,\n newCategoryCode.value,\n new SubCategoryAppearance({ color: 0xff0000 }),\n );\n\n // insert element and aspect\n const el1 = b1Txn.insertElement(IModelTestUtils.createPhysicalObject(b1, modelId, spatialCategoryId).toJSON());\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `inserted element with aspect ${el1}` });\n\n await b2.pullChanges();\n const aspectId1 = b2Txn.insertAspect({\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier\",\n } as ElementAspectProps);\n b2Txn.saveChanges();\n\n b1Txn.deleteElement(el1);\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `deleted element ${el1}` });\n\n const conflicts: {\n cause: SqliteConflictCause,\n tableName: string,\n opcode?: SqliteChangeOp,\n id: Id64String | undefined,\n }[] = [];\n\n // we will not handle conflict and let the default conflict handler deal with it.\n b2.txns.rebaser.addConflictHandler({\n id: \"custom\", handler: (arg: RebaseChangesetConflictArgs) => {\n let id;\n if (arg.cause !== \"ForeignKey\") {\n id = arg.getValueId(0, arg.opcode === \"Inserted\" ? \"New\" : \"Old\") as Id64String;\n }\n conflicts.push({\n cause: arg.cause,\n tableName: arg.tableName,\n opcode: arg.opcode,\n id,\n });\n return undefined;\n }\n });\n\n\n await assertThrowsAsync(\n async () => b2.pushChanges({ accessToken: accessToken1, description: `inserted element with aspect ${el1}` }),\n \"Foreign key conflicts in ChangeSet. Aborting rebase.\");\n\n expect(conflicts.length).to.be.equals(3);\n expect(conflicts).to.deep.equal([\n {\n cause: \"NotFound\",\n tableName: \"bis_Element\",\n opcode: \"Updated\",\n id: \"0x20000000004\"\n },\n {\n cause: \"Data\",\n tableName: \"bis_Model\",\n opcode: \"Updated\",\n id: \"0x20000000001\"\n },\n {\n cause: \"ForeignKey\",\n tableName: \"\",\n opcode: undefined,\n id: undefined\n }\n ]);\n\n b2.txns.rebaser.addConflictHandler({\n id: \"delete_aspect_when_element_is_deleted\", handler: (arg: RebaseChangesetConflictArgs) => {\n if (arg.cause === \"NotFound\" && arg.tableName === \"bis_Element\") {\n // if element does not exist any more let delete the aspects as well.\n const elId = arg.getValueId(0, arg.opcode === \"Inserted\" ? \"New\" : \"Old\") as Id64String;\n withEditTxn(b2, (txn) => {\n b2.elements.getAspects(elId).forEach((aspect) => {\n txn.deleteAspect(aspect.id);\n });\n });\n }\n return undefined;\n }\n });\n\n b2Txn.saveChanges();\n conflicts.length = 0;\n\n await b2.pushChanges({ accessToken: accessToken1, description: `nothing is pushed as the only change we made is reverted` });\n await b3.pullChanges();\n await b1.pullChanges();\n\n expect(() => b1.elements.getElement(el1)).throws(`Element=${el1}`);\n expect(() => b2.elements.getElement(el1)).throws(`Element=${el1}`);\n expect(() => b3.elements.getElement(el1)).throws(`Element=${el1}`);\n\n expect(() => b1.elements.getAspect(aspectId1)).throws(`ElementAspect not found ${aspectId1}`);\n expect(() => b2.elements.getAspect(aspectId1)).throws(`ElementAspect not found ${aspectId1}`);\n expect(() => b3.elements.getAspect(aspectId1)).throws(`ElementAspect not found ${aspectId1}`);\n\n b1.close();\n b2.close();\n b3.close();\n });\n\n it(\"aspect insert, update & delete requires exclusive lock\", async () => {\n const accessToken1 = await HubWrappers.getAccessToken(TestUserType.SuperManager);\n const accessToken2 = await HubWrappers.getAccessToken(TestUserType.Regular);\n const accessToken3 = await HubWrappers.getAccessToken(TestUserType.Super);\n\n // Delete any existing iModels with the same name as the read-write test iModel\n const iModelName = \"TestIModel\";\n\n // Create a new empty iModel on the Hub & obtain a briefcase\n const rwIModelId = await HubMock.createNewIModel({ accessToken: accessToken1, iTwinId, iModelName, description: \"TestSubject\", noLocks: undefined });\n assert.isNotEmpty(rwIModelId);\n\n const b1 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken1, iTwinId, iModelId: rwIModelId });\n b1.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b2 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken2, iTwinId, iModelId: rwIModelId });\n b2.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b3 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken3, iTwinId, iModelId: rwIModelId });\n const b1Txn = new EditTxn(b1, \"merge conflict\");\n b1Txn.start();\n const b2Txn = new EditTxn(b2, \"merge conflict\");\n b2Txn.start();\n\n await b1.locks.acquireLocks({ shared: IModel.repositoryModelId });\n await b2.locks.acquireLocks({ shared: IModel.repositoryModelId });\n\n // create and insert a new model with code1\n const [, modelId] = IModelTestUtils.createAndInsertPhysicalPartitionAndModel(\n b1Txn,\n IModelTestUtils.getUniqueModelCode(b1, \"newPhysicalModel\"),\n true);\n\n const dictionary: DictionaryModel = b1.models.getModel<DictionaryModel>(IModel.dictionaryId);\n const newCategoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, \"ThisTestSpatialCategory\");\n\n await b1.locks.acquireLocks({ shared: dictionary.id });\n const spatialCategoryId = SpatialCategory.insert(\n b1Txn,\n dictionary.id,\n newCategoryCode.value,\n new SubCategoryAppearance({ color: 0xff0000 }),\n );\n const el1 = b1Txn.insertElement(IModelTestUtils.createPhysicalObject(b1, modelId, spatialCategoryId).toJSON());\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `inserted element ${el1}` });\n\n await b2.pullChanges();\n let aspectId: Id64String;\n const insertAspectIntoB2 = () => {\n aspectId = b2Txn.insertAspect({\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier\",\n } as ElementAspectProps);\n };\n\n /* attempt to insert aspect without a lock */\n assert.throws(insertAspectIntoB2, \"Error inserting ElementAspect [exclusive lock not held on element for insert aspect (id=0x20000000004)], class: BisCore:ExternalSourceAspect\");\n\n /* acquire lock and try again */\n await b2.locks.acquireLocks({ exclusive: el1 });\n insertAspectIntoB2();\n\n /* b1 cannot acquire lock on el1 as its already taken by b2 */\n await expect(b1.locks.acquireLocks({ exclusive: el1 })).to.be.rejectedWith(\"exclusive lock is already held\");\n\n /* push changes on b2 to release lock on el1 */\n b2Txn.saveChanges();\n await b2.pushChanges({ accessToken: accessToken2, description: `add aspect to element ${el1}` });\n\n await b1.pullChanges();\n\n const updateAspectIntoB1 = () => {\n b1Txn.updateAspect({\n id: aspectId,\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier (modified)\",\n } as ElementAspectProps);\n };\n\n /* attempt to update aspect without a lock */\n assert.throws(updateAspectIntoB1, \"Error updating ElementAspect [exclusive lock not held on element for update aspect (id=0x20000000004)], id: 0x30000000001\");\n\n /* acquire lock and try again */\n await b1.locks.acquireLocks({ exclusive: el1 });\n updateAspectIntoB1();\n\n /* delete the element */\n b1Txn.deleteElement(el1);\n b1Txn.saveChanges();\n\n await b1.pushChanges({ accessToken: accessToken1, description: `deleted element ${el1}` });\n\n const onChangesetConflictStub = sinon.stub(BriefcaseDb.prototype, \"onChangesetConflict\" as any);\n /* we should be able to apply all changesets */\n await b3.pullChanges();\n expect(onChangesetConflictStub.callCount).eq(0, \"native conflict handler should not be called BriefcaseDb.onChangesetConflict()\");\n onChangesetConflictStub.restore();\n b1.close();\n b2.close();\n b3.close();\n });\n});\n"]}
1
+ {"version":3,"file":"MergeConflict.test.js","sourceRoot":"","sources":["../../../../src/test/standalone/MergeConflict.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\nimport { GuidString, Id64String } from \"@itwin/core-bentley\";\nimport { EditTxn, withEditTxn } from \"../../EditTxn\";\nimport {\n ElementAspectProps,\n IModel,\n SubCategoryAppearance,\n} from \"@itwin/core-common\";\nimport * as chai from \"chai\";\nimport { assert, expect } from \"chai\";\nimport * as chaiAsPromised from \"chai-as-promised\";\nimport { HubWrappers, KnownTestLocations } from \"../\";\nimport { HubMock } from \"../../internal/HubMock\";\nimport {\n BriefcaseDb,\n ChannelControl,\n DictionaryModel,\n ExternalSourceAspect,\n SpatialCategory,\n SqliteChangeOp,\n} from \"../../core-backend\";\nimport { IModelTestUtils, TestUserType } from \"../IModelTestUtils\";\nimport { RebaseChangesetConflictArgs, SqliteConflictCause } from \"../../internal/ChangesetConflictArgs\";\nchai.use(chaiAsPromised);\nimport * as sinon from \"sinon\";\n\nexport async function createNewModelAndCategory(txn: EditTxn, parent?: Id64String) {\n const rwIModel = txn.iModel as BriefcaseDb;\n // Create a new physical model.\n const [, modelId] = await IModelTestUtils.createAndInsertPhysicalPartitionAndModelAsync(txn, IModelTestUtils.getUniqueModelCode(rwIModel, \"newPhysicalModel\"), true, parent);\n\n // Find or create a SpatialCategory.\n const dictionary: DictionaryModel = rwIModel.models.getModel<DictionaryModel>(IModel.dictionaryId);\n const newCategoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, \"ThisTestSpatialCategory\");\n const category = SpatialCategory.create(rwIModel, IModel.dictionaryId, newCategoryCode.value);\n const spatialCategoryId = txn.insertElement(category.toJSON());\n category.setDefaultAppearance(txn, new SubCategoryAppearance({ color: 0xff0000 }));\n\n return { modelId, spatialCategoryId };\n}\n\nasync function assertThrowsAsync<T>(test: () => Promise<T>, msg?: string) {\n try {\n await test();\n } catch (e) {\n if (e instanceof Error && msg) {\n assert.equal(e.message, msg);\n }\n return;\n }\n throw new Error(`Failed to throw error with message: \"${msg}\"`);\n}\n\ndescribe(\"Merge conflict & locking\", () => { \n let iTwinId: GuidString;\n\n before(() => {\n HubMock.startup(\"MergeConflictTest\", KnownTestLocations.outputDir);\n iTwinId = HubMock.iTwinId;\n });\n after(() => HubMock.shutdown());\n\n it(\"pull/merge causing update conflict - dirty read/modify (with no lock)\", async () => {\n /**\n * To simulate a a data conflict for dirty read we update same aspect from two different briefcases\n * and when the second briefcase try to push its changes it will fail with following error.\n * \"UPDATE/DELETE before value do not match with one in db or CASCADE action was triggered.\"\n */\n const accessToken1 = await HubWrappers.getAccessToken(TestUserType.SuperManager);\n const accessToken2 = await HubWrappers.getAccessToken(TestUserType.Regular);\n const accessToken3 = await HubWrappers.getAccessToken(TestUserType.Super);\n\n // Delete any existing iModels with the same name as the read-write test iModel\n const iModelName = \"TestIModel\";\n\n // Create a new empty iModel on the Hub & obtain a briefcase\n const rwIModelId = await HubMock.createNewIModel({ accessToken: accessToken1, iTwinId, iModelName, description: \"TestSubject\", noLocks: undefined });\n assert.isNotEmpty(rwIModelId);\n\n // to reproduce the issue we will disable locks altogether.\n const b1 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken1, iTwinId, iModelId: rwIModelId, noLock: true });\n b1.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b2 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken2, iTwinId, iModelId: rwIModelId, noLock: true });\n b2.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b3 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken3, iTwinId, iModelId: rwIModelId, noLock: true });\n const b1Txn = new EditTxn(b1, \"merge conflict\");\n b1Txn.start();\n const b2Txn = new EditTxn(b2, \"merge conflict\");\n b2Txn.start();\n\n // create and insert a new model with code1\n const [, modelId] = IModelTestUtils.createAndInsertPhysicalPartitionAndModel(\n b1Txn,\n IModelTestUtils.getUniqueModelCode(b1, \"newPhysicalModel\"),\n true);\n\n const dictionary: DictionaryModel = b1.models.getModel<DictionaryModel>(IModel.dictionaryId);\n const newCategoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, \"ThisTestSpatialCategory\");\n\n const spatialCategoryId = SpatialCategory.insert(\n b1Txn,\n dictionary.id,\n newCategoryCode.value,\n new SubCategoryAppearance({ color: 0xff0000 }),\n );\n\n // insert element and aspect\n const el1 = b1Txn.insertElement(IModelTestUtils.createPhysicalObject(b1, modelId, spatialCategoryId).toJSON());\n await b1.pullChanges();\n const aspectId1 = b1Txn.insertAspect({\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier\",\n } as ElementAspectProps);\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `inserted element with aspect ${el1}` });\n\n // b1 same as b2 and now both will modify same aspect\n await b2.pullChanges();\n\n // b1 will change identifier from \"test identifier\" to \"test identifier (modified by b1)\"\n b1Txn.updateAspect({\n id: aspectId1,\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier (modified by b1)\",\n } as ElementAspectProps);\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `modify aspect ${aspectId1} with no lock` });\n\n // b2 will change identifier from \"test identifier\" to \"test identifier (modified by b2)\"\n b2Txn.updateAspect({\n id: aspectId1,\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier (modified by b2)\",\n } as ElementAspectProps);\n b2Txn.saveChanges();\n\n const conflicts: {\n cause: SqliteConflictCause,\n tableName: string,\n opcode?: SqliteChangeOp,\n id: Id64String,\n }[] = [];\n\n // we will not handle conflict and let the default conflict handler deal with it.\n b2.txns.rebaser.addConflictHandler({\n id: \"custom\", handler: (arg: RebaseChangesetConflictArgs) => {\n conflicts.push({\n cause: arg.cause,\n tableName: arg.tableName,\n opcode: arg.opcode,\n id: arg.getValueId(0, arg.opcode === \"Inserted\" ? \"New\" : \"Old\") as Id64String,\n });\n return undefined;\n }\n });\n\n await b2.pushChanges({ accessToken: accessToken1, description: `modify aspect ${aspectId1} with no lock` });\n\n expect(conflicts.length).to.be.equals(3);\n\n chai.expect(\n [\n {\n \"cause\": \"Data\",\n \"tableName\": \"bis_Element\",\n \"opcode\": \"Updated\",\n \"id\": \"0x20000000004\"\n },\n {\n \"cause\": \"Data\",\n \"tableName\": \"bis_ElementMultiAspect\",\n \"opcode\": \"Updated\",\n \"id\": \"0x20000000001\"\n },\n {\n \"cause\": \"Data\",\n \"tableName\": \"bis_Model\",\n \"opcode\": \"Updated\",\n \"id\": \"0x20000000001\"\n }\n ]).to.be.deep.equals(conflicts);\n\n await b3.pullChanges();\n await b1.pullChanges();\n\n // b2 win as default conflict handler choose Replace to override local changes over master.\n (b2.elements.getAspect(aspectId1) as ExternalSourceAspect).identifier = \"test identifier (modified by b2)\";\n (b3.elements.getAspect(aspectId1) as ExternalSourceAspect).identifier = \"test identifier (modified by b2)\";\n (b1.elements.getAspect(aspectId1) as ExternalSourceAspect).identifier = \"test identifier (modified by b2)\";\n\n b1.close();\n b2.close();\n b3.close();\n });\n it(\"pull/merge causing update conflict - update causing local changes (with no lock)\", async () => {\n /**\n * To simulate a a data conflict for dirty read we update same aspect from two different briefcases\n * and when the second briefcase try to push its changes it will fail with following error.\n * \"UPDATE/DELETE before value do not match with one in db or CASCADE action was triggered.\"\n */\n const accessToken1 = await HubWrappers.getAccessToken(TestUserType.SuperManager);\n const accessToken2 = await HubWrappers.getAccessToken(TestUserType.Regular);\n const accessToken3 = await HubWrappers.getAccessToken(TestUserType.Super);\n\n // Delete any existing iModels with the same name as the read-write test iModel\n const iModelName = \"TestIModel\";\n\n // Create a new empty iModel on the Hub & obtain a briefcase\n const rwIModelId = await HubMock.createNewIModel({ accessToken: accessToken1, iTwinId, iModelName, description: \"TestSubject\", noLocks: undefined });\n assert.isNotEmpty(rwIModelId);\n\n // to reproduce the issue we will disable locks altogether.\n const b1 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken1, iTwinId, iModelId: rwIModelId, noLock: true });\n b1.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b2 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken2, iTwinId, iModelId: rwIModelId, noLock: true });\n b2.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b3 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken3, iTwinId, iModelId: rwIModelId, noLock: true });\n const b1Txn = new EditTxn(b1, \"merge conflict\");\n b1Txn.start();\n const b2Txn = new EditTxn(b2, \"merge conflict\");\n b2Txn.start();\n\n // create and insert a new model with code1\n const [, modelId] = IModelTestUtils.createAndInsertPhysicalPartitionAndModel(\n b1Txn,\n IModelTestUtils.getUniqueModelCode(b1, \"newPhysicalModel\"),\n true);\n\n const dictionary: DictionaryModel = b1.models.getModel<DictionaryModel>(IModel.dictionaryId);\n const newCategoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, \"ThisTestSpatialCategory\");\n\n const spatialCategoryId = SpatialCategory.insert(\n b1Txn,\n dictionary.id,\n newCategoryCode.value,\n new SubCategoryAppearance({ color: 0xff0000 }),\n );\n\n // insert element and aspect\n const el1 = b1Txn.insertElement(IModelTestUtils.createPhysicalObject(b1, modelId, spatialCategoryId).toJSON());\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `inserted element with aspect ${el1}` });\n\n await b2.pullChanges();\n const aspectId1 = b2Txn.insertAspect({\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier\",\n } as ElementAspectProps);\n b2Txn.saveChanges();\n\n b1Txn.deleteElement(el1);\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `deleted element ${el1}` });\n\n const conflicts: {\n cause: SqliteConflictCause,\n tableName: string,\n opcode?: SqliteChangeOp,\n id: Id64String | undefined,\n }[] = [];\n\n // we will not handle conflict and let the default conflict handler deal with it.\n b2.txns.rebaser.addConflictHandler({\n id: \"custom\", handler: (arg: RebaseChangesetConflictArgs) => {\n let id;\n if (arg.cause !== \"ForeignKey\") {\n id = arg.getValueId(0, arg.opcode === \"Inserted\" ? \"New\" : \"Old\") as Id64String;\n }\n conflicts.push({\n cause: arg.cause,\n tableName: arg.tableName,\n opcode: arg.opcode,\n id,\n });\n return undefined;\n }\n });\n\n\n await assertThrowsAsync(\n async () => b2.pushChanges({ accessToken: accessToken1, description: `inserted element with aspect ${el1}` }),\n \"Foreign key conflicts in ChangeSet. Aborting rebase.\");\n\n expect(conflicts.length).to.be.equals(3);\n expect(conflicts).to.deep.equal([\n {\n cause: \"NotFound\",\n tableName: \"bis_Element\",\n opcode: \"Updated\",\n id: \"0x20000000004\"\n },\n {\n cause: \"Data\",\n tableName: \"bis_Model\",\n opcode: \"Updated\",\n id: \"0x20000000001\"\n },\n {\n cause: \"ForeignKey\",\n tableName: \"\",\n opcode: undefined,\n id: undefined\n }\n ]);\n\n b2.txns.rebaser.addConflictHandler({\n id: \"delete_aspect_when_element_is_deleted\", handler: (arg: RebaseChangesetConflictArgs) => {\n if (arg.cause === \"NotFound\" && arg.tableName === \"bis_Element\") {\n // if element does not exist any more let delete the aspects as well.\n const elId = arg.getValueId(0, arg.opcode === \"Inserted\" ? \"New\" : \"Old\") as Id64String;\n withEditTxn(b2, (txn) => {\n b2.elements.getAspects(elId).forEach((aspect) => {\n txn.deleteAspect(aspect.id);\n });\n });\n }\n return undefined;\n }\n });\n\n b2Txn.saveChanges();\n conflicts.length = 0;\n\n await b2.pushChanges({ accessToken: accessToken1, description: `nothing is pushed as the only change we made is reverted` });\n await b3.pullChanges();\n await b1.pullChanges();\n\n expect(() => b1.elements.getElement(el1)).throws(`Element=${el1}`);\n expect(() => b2.elements.getElement(el1)).throws(`Element=${el1}`);\n expect(() => b3.elements.getElement(el1)).throws(`Element=${el1}`);\n\n expect(() => b1.elements.getAspect(aspectId1)).throws(`ElementAspect not found ${aspectId1}`);\n expect(() => b2.elements.getAspect(aspectId1)).throws(`ElementAspect not found ${aspectId1}`);\n expect(() => b3.elements.getAspect(aspectId1)).throws(`ElementAspect not found ${aspectId1}`);\n\n b1.close();\n b2.close();\n b3.close();\n });\n\n it(\"aspect insert, update & delete requires exclusive lock\", async () => {\n const accessToken1 = await HubWrappers.getAccessToken(TestUserType.SuperManager);\n const accessToken2 = await HubWrappers.getAccessToken(TestUserType.Regular);\n const accessToken3 = await HubWrappers.getAccessToken(TestUserType.Super);\n\n // Delete any existing iModels with the same name as the read-write test iModel\n const iModelName = \"TestIModel\";\n\n // Create a new empty iModel on the Hub & obtain a briefcase\n const rwIModelId = await HubMock.createNewIModel({ accessToken: accessToken1, iTwinId, iModelName, description: \"TestSubject\", noLocks: undefined });\n assert.isNotEmpty(rwIModelId);\n\n const b1 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken1, iTwinId, iModelId: rwIModelId });\n b1.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b2 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken2, iTwinId, iModelId: rwIModelId });\n b2.channels.addAllowedChannel(ChannelControl.sharedChannelName);\n const b3 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken3, iTwinId, iModelId: rwIModelId });\n const b1Txn = new EditTxn(b1, \"merge conflict\");\n b1Txn.start();\n const b2Txn = new EditTxn(b2, \"merge conflict\");\n b2Txn.start();\n\n await b1.locks.acquireLocks({ shared: IModel.repositoryModelId });\n await b2.locks.acquireLocks({ shared: IModel.repositoryModelId });\n\n // create and insert a new model with code1\n const [, modelId] = IModelTestUtils.createAndInsertPhysicalPartitionAndModel(\n b1Txn,\n IModelTestUtils.getUniqueModelCode(b1, \"newPhysicalModel\"),\n true);\n\n const dictionary: DictionaryModel = b1.models.getModel<DictionaryModel>(IModel.dictionaryId);\n const newCategoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, \"ThisTestSpatialCategory\");\n\n await b1.locks.acquireLocks({ shared: dictionary.id });\n const spatialCategoryId = SpatialCategory.insert(\n b1Txn,\n dictionary.id,\n newCategoryCode.value,\n new SubCategoryAppearance({ color: 0xff0000 }),\n );\n const el1 = b1Txn.insertElement(IModelTestUtils.createPhysicalObject(b1, modelId, spatialCategoryId).toJSON());\n b1Txn.saveChanges();\n await b1.pushChanges({ accessToken: accessToken1, description: `inserted element ${el1}` });\n\n await b2.pullChanges();\n let aspectId: Id64String;\n const insertAspectIntoB2 = () => {\n aspectId = b2Txn.insertAspect({\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier\",\n } as ElementAspectProps);\n };\n\n /* attempt to insert aspect without a lock */\n assert.throws(insertAspectIntoB2, \"Error inserting ElementAspect [exclusive lock not held on element for insert aspect (id=0x20000000004)], class: BisCore:ExternalSourceAspect\");\n\n /* acquire lock and try again */\n await b2.locks.acquireLocks({ exclusive: el1 });\n insertAspectIntoB2();\n\n /* b1 cannot acquire lock on el1 as its already taken by b2 */\n await expect(b1.locks.acquireLocks({ exclusive: el1 })).to.be.rejectedWith(\"exclusive lock is already held\");\n\n /* push changes on b2 to release lock on el1 */\n b2Txn.saveChanges();\n await b2.pushChanges({ accessToken: accessToken2, description: `add aspect to element ${el1}` });\n\n await b1.pullChanges();\n\n const updateAspectIntoB1 = () => {\n b1Txn.updateAspect({\n id: aspectId,\n classFullName: \"BisCore:ExternalSourceAspect\",\n element: {\n relClassName: \"BisCore:ElementOwnsExternalSourceAspects\",\n id: el1,\n },\n kind: \"\",\n identifier: \"test identifier (modified)\",\n } as ElementAspectProps);\n };\n\n /* attempt to update aspect without a lock */\n assert.throws(updateAspectIntoB1, \"Error updating ElementAspect [exclusive lock not held on element for update aspect (id=0x20000000004)], id: 0x30000000001\");\n\n /* acquire lock and try again */\n await b1.locks.acquireLocks({ exclusive: el1 });\n updateAspectIntoB1();\n\n /* delete the element */\n b1Txn.deleteElement(el1);\n b1Txn.saveChanges();\n\n await b1.pushChanges({ accessToken: accessToken1, description: `deleted element ${el1}` });\n\n const onChangesetConflictStub = sinon.stub(BriefcaseDb.prototype, \"onChangesetConflict\" as any);\n /* we should be able to apply all changesets */\n await b3.pullChanges();\n expect(onChangesetConflictStub.callCount).eq(0, \"native conflict handler should not be called BriefcaseDb.onChangesetConflict()\");\n onChangesetConflictStub.restore();\n b1.close();\n b2.close();\n b3.close();\n });\n});\n"]}
@@ -1,2 +1,2 @@
1
- export {};
1
+ import "../TestUtils";
2
2
  //# sourceMappingURL=SQLiteDb.test.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SQLiteDb.test.d.ts","sourceRoot":"","sources":["../../../../src/test/standalone/SQLiteDb.test.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"SQLiteDb.test.d.ts","sourceRoot":"","sources":["../../../../src/test/standalone/SQLiteDb.test.ts"],"names":[],"mappings":"AAUA,OAAO,cAAc,CAAC"}
@@ -4,8 +4,10 @@
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import { expect } from "chai";
6
6
  import { BeDuration, DbResult, OpenMode } from "@itwin/core-bentley";
7
- import { SQLiteDb } from "../../SQLiteDb";
7
+ import { IModelJsFs } from "../../IModelJsFs";
8
8
  import { IModelTestUtils } from "../IModelTestUtils";
9
+ import { SQLiteDb } from "../../SQLiteDb";
10
+ import "../TestUtils"; // registers the global mocha before/after hooks that start/stop the backend
9
11
  describe("SQLiteDb", () => {
10
12
  it("should create new SQLiteDb", async () => {
11
13
  const fileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "db1.db");
@@ -59,5 +61,95 @@ describe("SQLiteDb", () => {
59
61
  });
60
62
  });
61
63
  });
64
+ describe("applyChangeset", () => {
65
+ const readRows = (db, tableName) => {
66
+ const rows = [];
67
+ db.withSqliteStatement(`SELECT id,val FROM ${tableName} ORDER BY id`, (stmt) => {
68
+ while (stmt.step() === DbResult.BE_SQLITE_ROW)
69
+ rows.push({ id: stmt.getValue(0).getInteger(), val: stmt.getValue(1).getString() });
70
+ });
71
+ return rows;
72
+ };
73
+ it("should apply a changeset containing data changes", () => {
74
+ const sourceFileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "applyChangeset-source.db");
75
+ const targetFileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "applyChangeset-target.db");
76
+ const changesetFileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "applyChangeset-1.changeset");
77
+ // create the source db (with the table already present - raw sqlite changesets cannot capture DDL),
78
+ // then capture a changeset that inserts some rows
79
+ const source = new SQLiteDb();
80
+ source.createDb(sourceFileName, undefined, { rawSQLite: true });
81
+ source.executeSQL("CREATE TABLE test1(id INTEGER PRIMARY KEY,val TEXT)");
82
+ source.saveChanges();
83
+ source.startChangeTracking();
84
+ source.executeSQL(`INSERT INTO test1(id,val) VALUES (1,'val1')`);
85
+ source.executeSQL(`INSERT INTO test1(id,val) VALUES (2,'val2')`);
86
+ source.saveChanges();
87
+ source.createChangeset(changesetFileName);
88
+ // apply the changeset (raw sqlite changesets have no header to validate) to a db with the same schema
89
+ const target = new SQLiteDb();
90
+ target.createDb(targetFileName, undefined, { rawSQLite: true });
91
+ target.executeSQL("CREATE TABLE test1(id INTEGER PRIMARY KEY,val TEXT)");
92
+ target.saveChanges();
93
+ target.applyChangeset(changesetFileName);
94
+ target.saveChanges();
95
+ expect(readRows(target, "test1")).deep.equal([{ id: 1, val: "val1" }, { id: 2, val: "val2" }]);
96
+ source.closeDb();
97
+ target.closeDb();
98
+ });
99
+ it("should throw when creating a changeset containing DDL/schema changes", () => {
100
+ const sourceFileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "applyChangeset-ddl-source.db");
101
+ const changesetFileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "applyChangeset-ddl.changeset");
102
+ const source = new SQLiteDb();
103
+ source.createDb(sourceFileName, undefined, { rawSQLite: true });
104
+ source.startChangeTracking();
105
+ source.executeDdl("CREATE TABLE test1(id INTEGER PRIMARY KEY,val TEXT)");
106
+ source.saveChanges();
107
+ // raw sqlite changesets cannot represent DDL/schema changes
108
+ expect(() => source.createChangeset(changesetFileName)).throws();
109
+ source.closeDb();
110
+ });
111
+ it("should fail if applying a changeset produces a conflict, leaving it to the caller to abandon the partially-applied changes", () => {
112
+ const baseFileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "applyChangeset-base.db");
113
+ const sourceFileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "applyChangeset-conflict-source.db");
114
+ const targetFileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "applyChangeset-conflict-target.db");
115
+ const changesetFileName = IModelTestUtils.prepareOutputFile("SQLiteDb", "applyChangeset-2.changeset");
116
+ // create a common base db with two rows, then clone it so source and target start out identical
117
+ const base = new SQLiteDb();
118
+ base.createDb(baseFileName, undefined, { rawSQLite: true });
119
+ base.executeSQL("CREATE TABLE test1(id INTEGER PRIMARY KEY,val TEXT)");
120
+ base.executeSQL(`INSERT INTO test1(id,val) VALUES (1,'base1')`);
121
+ base.executeSQL(`INSERT INTO test1(id,val) VALUES (2,'base2')`);
122
+ base.saveChanges();
123
+ base.closeDb();
124
+ IModelJsFs.copySync(baseFileName, sourceFileName);
125
+ IModelJsFs.copySync(baseFileName, targetFileName);
126
+ // diverge source: update both rows and capture that as a single changeset. Only the second row will
127
+ // conflict with target's divergence below - the first row's change would apply cleanly on its own.
128
+ const source = new SQLiteDb();
129
+ source.openDb(sourceFileName, { openMode: OpenMode.ReadWrite, rawSQLite: true });
130
+ source.startChangeTracking();
131
+ source.executeSQL(`UPDATE test1 SET val='fromSource1' WHERE id=1`);
132
+ source.executeSQL(`UPDATE test1 SET val='fromSource2' WHERE id=2`);
133
+ source.saveChanges();
134
+ source.createChangeset(changesetFileName);
135
+ source.closeDb();
136
+ // diverge target independently - only on the second row - so applying source's changeset conflicts partway through
137
+ const target = new SQLiteDb();
138
+ target.openDb(targetFileName, { openMode: OpenMode.ReadWrite, rawSQLite: true });
139
+ target.executeSQL(`UPDATE test1 SET val='fromTarget2' WHERE id=2`);
140
+ target.saveChanges();
141
+ // confirm the pre-apply baseline: id=1 was never touched by target, id=2 diverged from source
142
+ expect(readRows(target, "test1")).deep.equal([{ id: 1, val: "base1" }, { id: 2, val: "fromTarget2" }]);
143
+ // applyChangeset only throws on failure - it does not commit or abandon changes itself. Since the first
144
+ // row's change didn't conflict, it may already have been applied to the current transaction by the time
145
+ // the second row's conflict causes the throw.
146
+ expect(() => target.applyChangeset(changesetFileName)).throws();
147
+ expect(readRows(target, "test1")).deep.equal([{ id: 1, val: "fromSource1" }, { id: 2, val: "fromTarget2" }]);
148
+ // it is the caller's responsibility to abandon (or save) the partially-applied changes after catching the error
149
+ target.abandonChanges();
150
+ expect(readRows(target, "test1")).deep.equal([{ id: 1, val: "base1" }, { id: 2, val: "fromTarget2" }]);
151
+ target.closeDb();
152
+ });
153
+ });
62
154
  });
63
155
  //# 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":"AAAA;;;+FAG+F;AAE/F,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,cAAc,CAAC,CAAC,4EAA4E;AAEnG,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IAExB,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,QAAQ,GAAG,eAAe,CAAC,iBAAiB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACzE,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC1B,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;QAC1E,EAAE,CAAC,UAAU,CAAC,qDAAqD,CAAC,CAAC;QACrE,EAAE,CAAC,UAAU,CAAC,6CAA6C,CAAC,CAAC;QAC7D,EAAE,CAAC,UAAU,CAAC,6CAA6C,CAAC,CAAC;QAC7D,EAAE,CAAC,WAAW,EAAE,CAAC;QAEjB,MAAM,MAAM,GAAG,GAAG,EAAE;YAClB,EAAE,CAAC,mBAAmB,CAAC,0BAA0B,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC1D,IAAI,CAAC,IAAI,EAAE,CAAC;gBACZ,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC/C,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACnD,IAAI,CAAC,IAAI,EAAE,CAAC;gBACZ,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC/C,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACrD,CAAC,CAAC,CAAC;YACH,EAAE,CAAC,OAAO,EAAE,CAAC;QACf,CAAC,CAAC;QACF,MAAM,EAAE,CAAC;QAET,0BAA0B;QAC1B,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtJ,MAAM,EAAE,CAAC;QAET,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC;QACxB,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAE7C,IAAI,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE;YAC9G,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;YAClB,EAAE,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACtB,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC;QAExB,GAAG,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,IAAI,EAAE;YACtH,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;YAClB,MAAM,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC7C,OAAO,GAAG,CAAC;QACb,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACvB,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,YAAY,GAAG,eAAe,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAClE,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC1B,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,GAAG,EAAE;YAC3C,EAAE,CAAC,mBAAmB,CAAC,8EAA8E,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC9G,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;gBAClD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;gBACrD,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;gBACjD,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;YACnD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,MAAM,QAAQ,GAAG,CAAC,EAAY,EAAE,SAAiB,EAAE,EAAE;YACnD,MAAM,IAAI,GAAuC,EAAE,CAAC;YACpD,EAAE,CAAC,mBAAmB,CAAC,sBAAsB,SAAS,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC7E,OAAO,IAAI,CAAC,IAAI,EAAE,KAAK,QAAQ,CAAC,aAAa;oBAC3C,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YACxF,CAAC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,MAAM,cAAc,GAAG,eAAe,CAAC,iBAAiB,CAAC,UAAU,EAAE,0BAA0B,CAAC,CAAC;YACjG,MAAM,cAAc,GAAG,eAAe,CAAC,iBAAiB,CAAC,UAAU,EAAE,0BAA0B,CAAC,CAAC;YACjG,MAAM,iBAAiB,GAAG,eAAe,CAAC,iBAAiB,CAAC,UAAU,EAAE,4BAA4B,CAAC,CAAC;YAEtG,oGAAoG;YACpG,kDAAkD;YAClD,MAAM,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAChE,MAAM,CAAC,UAAU,CAAC,qDAAqD,CAAC,CAAC;YACzE,MAAM,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAC7B,MAAM,CAAC,UAAU,CAAC,6CAA6C,CAAC,CAAC;YACjE,MAAM,CAAC,UAAU,CAAC,6CAA6C,CAAC,CAAC;YACjE,MAAM,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,CAAC,eAAe,CAAC,iBAAiB,CAAC,CAAC;YAE1C,sGAAsG;YACtG,MAAM,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAChE,MAAM,CAAC,UAAU,CAAC,qDAAqD,CAAC,CAAC;YACzE,MAAM,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;YACzC,MAAM,CAAC,WAAW,EAAE,CAAC;YAErB,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;YAE/F,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;YAC9E,MAAM,cAAc,GAAG,eAAe,CAAC,iBAAiB,CAAC,UAAU,EAAE,8BAA8B,CAAC,CAAC;YACrG,MAAM,iBAAiB,GAAG,eAAe,CAAC,iBAAiB,CAAC,UAAU,EAAE,8BAA8B,CAAC,CAAC;YAExG,MAAM,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAChE,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAC7B,MAAM,CAAC,UAAU,CAAC,qDAAqD,CAAC,CAAC;YACzE,MAAM,CAAC,WAAW,EAAE,CAAC;YAErB,4DAA4D;YAC5D,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;YAEjE,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4HAA4H,EAAE,GAAG,EAAE;YACpI,MAAM,YAAY,GAAG,eAAe,CAAC,iBAAiB,CAAC,UAAU,EAAE,wBAAwB,CAAC,CAAC;YAC7F,MAAM,cAAc,GAAG,eAAe,CAAC,iBAAiB,CAAC,UAAU,EAAE,mCAAmC,CAAC,CAAC;YAC1G,MAAM,cAAc,GAAG,eAAe,CAAC,iBAAiB,CAAC,UAAU,EAAE,mCAAmC,CAAC,CAAC;YAC1G,MAAM,iBAAiB,GAAG,eAAe,CAAC,iBAAiB,CAAC,UAAU,EAAE,4BAA4B,CAAC,CAAC;YAEtG,gGAAgG;YAChG,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC5B,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5D,IAAI,CAAC,UAAU,CAAC,qDAAqD,CAAC,CAAC;YACvE,IAAI,CAAC,UAAU,CAAC,8CAA8C,CAAC,CAAC;YAChE,IAAI,CAAC,UAAU,CAAC,8CAA8C,CAAC,CAAC;YAChE,IAAI,CAAC,WAAW,EAAE,CAAC;YACnB,IAAI,CAAC,OAAO,EAAE,CAAC;YAEf,UAAU,CAAC,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;YAClD,UAAU,CAAC,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;YAElD,oGAAoG;YACpG,mGAAmG;YACnG,MAAM,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACjF,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAC7B,MAAM,CAAC,UAAU,CAAC,+CAA+C,CAAC,CAAC;YACnE,MAAM,CAAC,UAAU,CAAC,+CAA+C,CAAC,CAAC;YACnE,MAAM,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,CAAC,eAAe,CAAC,iBAAiB,CAAC,CAAC;YAC1C,MAAM,CAAC,OAAO,EAAE,CAAC;YAEjB,mHAAmH;YACnH,MAAM,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACjF,MAAM,CAAC,UAAU,CAAC,+CAA+C,CAAC,CAAC;YACnE,MAAM,CAAC,WAAW,EAAE,CAAC;YAErB,8FAA8F;YAC9F,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;YAEvG,wGAAwG;YACxG,wGAAwG;YACxG,8CAA8C;YAC9C,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;YAChE,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;YAE7G,gHAAgH;YAChH,MAAM,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;YAEvG,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AAEL,CAAC,CAAC,CAAC","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 { IModelJsFs } from \"../../IModelJsFs\";\nimport { IModelTestUtils } from \"../IModelTestUtils\";\nimport { SQLiteDb } from \"../../SQLiteDb\";\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 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 (with the table already present - raw sqlite changesets cannot capture DDL),\n // then capture a changeset that inserts some rows\n const source = new SQLiteDb();\n source.createDb(sourceFileName, undefined, { rawSQLite: true });\n source.executeSQL(\"CREATE TABLE test1(id INTEGER PRIMARY KEY,val TEXT)\");\n source.saveChanges();\n source.startChangeTracking();\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 // apply the changeset (raw sqlite changesets have no header to validate) to a db with the same schema\n const target = new SQLiteDb();\n target.createDb(targetFileName, undefined, { rawSQLite: true });\n target.executeSQL(\"CREATE TABLE test1(id INTEGER PRIMARY KEY,val TEXT)\");\n target.saveChanges();\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 throw when creating a changeset containing DDL/schema changes\", () => {\n const sourceFileName = IModelTestUtils.prepareOutputFile(\"SQLiteDb\", \"applyChangeset-ddl-source.db\");\n const changesetFileName = IModelTestUtils.prepareOutputFile(\"SQLiteDb\", \"applyChangeset-ddl.changeset\");\n\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.saveChanges();\n\n // raw sqlite changesets cannot represent DDL/schema changes\n expect(() => source.createChangeset(changesetFileName)).throws();\n\n source.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"]}