@itwin/core-backend 5.15.1 → 5.16.0-dev.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/lib/cjs/ConcurrentQuery.d.ts +4 -0
- package/lib/cjs/ConcurrentQuery.d.ts.map +1 -1
- package/lib/cjs/ConcurrentQuery.js +28 -1
- package/lib/cjs/ConcurrentQuery.js.map +1 -1
- package/lib/cjs/ECDb.d.ts.map +1 -1
- package/lib/cjs/ECDb.js +5 -10
- package/lib/cjs/ECDb.js.map +1 -1
- package/lib/cjs/ECSqlRowExecutor.d.ts +39 -55
- package/lib/cjs/ECSqlRowExecutor.d.ts.map +1 -1
- package/lib/cjs/ECSqlRowExecutor.js +118 -140
- package/lib/cjs/ECSqlRowExecutor.js.map +1 -1
- package/lib/cjs/ECSqlSyncReader.d.ts +21 -8
- package/lib/cjs/ECSqlSyncReader.d.ts.map +1 -1
- package/lib/cjs/ECSqlSyncReader.js +67 -25
- package/lib/cjs/ECSqlSyncReader.js.map +1 -1
- package/lib/cjs/IModelDb.d.ts.map +1 -1
- package/lib/cjs/IModelDb.js +5 -10
- package/lib/cjs/IModelDb.js.map +1 -1
- package/lib/cjs/IModelHost.d.ts +7 -0
- package/lib/cjs/IModelHost.d.ts.map +1 -1
- package/lib/cjs/IModelHost.js +1 -0
- package/lib/cjs/IModelHost.js.map +1 -1
- package/lib/cjs/TxnManager.d.ts.map +1 -1
- package/lib/cjs/TxnManager.js +11 -6
- package/lib/cjs/TxnManager.js.map +1 -1
- package/lib/cjs/internal/ChangesetConflictArgs.d.ts +4 -0
- package/lib/cjs/internal/ChangesetConflictArgs.d.ts.map +1 -1
- package/lib/cjs/internal/ChangesetConflictArgs.js +1 -0
- package/lib/cjs/internal/ChangesetConflictArgs.js.map +1 -1
- package/lib/cjs/internal/QueryMetadataCache.d.ts +8 -0
- package/lib/cjs/internal/QueryMetadataCache.d.ts.map +1 -1
- package/lib/cjs/internal/QueryMetadataCache.js +23 -0
- package/lib/cjs/internal/QueryMetadataCache.js.map +1 -1
- package/lib/esm/ConcurrentQuery.d.ts +4 -0
- package/lib/esm/ConcurrentQuery.d.ts.map +1 -1
- package/lib/esm/ConcurrentQuery.js +29 -2
- package/lib/esm/ConcurrentQuery.js.map +1 -1
- package/lib/esm/ECDb.d.ts.map +1 -1
- package/lib/esm/ECDb.js +6 -11
- package/lib/esm/ECDb.js.map +1 -1
- package/lib/esm/ECSqlRowExecutor.d.ts +39 -55
- package/lib/esm/ECSqlRowExecutor.d.ts.map +1 -1
- package/lib/esm/ECSqlRowExecutor.js +119 -140
- package/lib/esm/ECSqlRowExecutor.js.map +1 -1
- package/lib/esm/ECSqlSyncReader.d.ts +21 -8
- package/lib/esm/ECSqlSyncReader.d.ts.map +1 -1
- package/lib/esm/ECSqlSyncReader.js +68 -26
- package/lib/esm/ECSqlSyncReader.js.map +1 -1
- package/lib/esm/IModelDb.d.ts.map +1 -1
- package/lib/esm/IModelDb.js +6 -11
- package/lib/esm/IModelDb.js.map +1 -1
- package/lib/esm/IModelHost.d.ts +7 -0
- package/lib/esm/IModelHost.d.ts.map +1 -1
- package/lib/esm/IModelHost.js +1 -0
- package/lib/esm/IModelHost.js.map +1 -1
- package/lib/esm/TxnManager.d.ts.map +1 -1
- package/lib/esm/TxnManager.js +12 -7
- package/lib/esm/TxnManager.js.map +1 -1
- package/lib/esm/internal/ChangesetConflictArgs.d.ts +4 -0
- package/lib/esm/internal/ChangesetConflictArgs.d.ts.map +1 -1
- package/lib/esm/internal/ChangesetConflictArgs.js +1 -0
- package/lib/esm/internal/ChangesetConflictArgs.js.map +1 -1
- package/lib/esm/internal/QueryMetadataCache.d.ts +8 -0
- package/lib/esm/internal/QueryMetadataCache.d.ts.map +1 -1
- package/lib/esm/internal/QueryMetadataCache.js +23 -0
- package/lib/esm/internal/QueryMetadataCache.js.map +1 -1
- package/lib/esm/test/IModelHost.test.js +103 -2
- package/lib/esm/test/IModelHost.test.js.map +1 -1
- package/lib/esm/test/ecdb/CTE.test.js +21 -0
- package/lib/esm/test/ecdb/CTE.test.js.map +1 -1
- package/lib/esm/test/ecdb/ConcurrentQuery.test.js +72 -0
- package/lib/esm/test/ecdb/ConcurrentQuery.test.js.map +1 -1
- package/lib/esm/test/ecdb/ConcurrentQueryLoad.test.js +51 -9
- package/lib/esm/test/ecdb/ConcurrentQueryLoad.test.js.map +1 -1
- package/lib/esm/test/ecdb/ECSqlQuery.test.js +2 -1
- package/lib/esm/test/ecdb/ECSqlQuery.test.js.map +1 -1
- package/lib/esm/test/ecdb/ECSqlSyncReader.test.js +338 -84
- package/lib/esm/test/ecdb/ECSqlSyncReader.test.js.map +1 -1
- package/lib/esm/test/ecdb/QueryMetadataCache.test.js +40 -4
- package/lib/esm/test/ecdb/QueryMetadataCache.test.js.map +1 -1
- package/lib/esm/test/ecdb/QueryReaders.test.js +14 -7
- package/lib/esm/test/ecdb/QueryReaders.test.js.map +1 -1
- package/lib/esm/test/standalone/ChangeMerge.test.js +71 -1
- package/lib/esm/test/standalone/ChangeMerge.test.js.map +1 -1
- package/lib/esm/test/standalone/IModelWrite.test.js +6 -2
- package/lib/esm/test/standalone/IModelWrite.test.js.map +1 -1
- package/lib/esm/test/standalone/MergeConflict.test.js +15 -0
- package/lib/esm/test/standalone/MergeConflict.test.js.map +1 -1
- package/package.json +16 -16
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ECSqlSyncReader.test.js","sourceRoot":"","sources":["../../../../src/test/ecdb/ECSqlSyncReader.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { assert, expect } from \"chai\";\r\nimport * as sinon from \"sinon\";\r\nimport * as path from \"node:path\";\r\nimport { QueryBinder, QueryOptionsBuilder, QueryPropertyMetaData, QueryRowFormat } from \"@itwin/core-common\";\r\nimport { SnapshotDb } from \"../../IModelDb\";\r\nimport { IModelTestUtils } from \"../IModelTestUtils\";\r\nimport { Id64 } from \"@itwin/core-bentley\";\r\nimport { ECSqlStatement } from \"../../ECSqlStatement\";\r\nimport { ECDbTestHelper } from \"./ECDbTestHelper\";\r\nimport { KnownTestLocations } from \"../KnownTestLocations\";\r\nimport { IModelNative } from \"../../internal/NativePlatform\";\r\nimport { IModelJsFs } from \"../../IModelJsFs\";\r\nimport { SynchronousQueryOptions } from \"../../ECSqlSyncReader\";\r\n\r\ndescribe(\"WithQueryReaderTests\", () => {\r\n let iModel: SnapshotDb;\r\n\r\n before(async () => {\r\n iModel = SnapshotDb.openFile(IModelTestUtils.resolveAssetFile(\"test.bim\"));\r\n });\r\n\r\n after(async () => {\r\n iModel.close();\r\n });\r\n it(\"check behvaiour if we call clearCaches in between\", () => {\r\n let actualRowCount = 0;\r\n const expectedInstanceIds = [\"0x1\", \"0xe\", \"0x10\", \"0x11\", \"0x12\",\r\n \"0x13\", \"0x14\", \"0x15\", \"0x16\", \"0x17\"];\r\n\r\n expect(() => iModel.withQueryReader(\"SELECT * FROM bis.Element\", (reader) => {\r\n let loopCount = 0;\r\n // First loop - read first 10 rows\r\n while (loopCount < 10) {\r\n reader.step()\r\n actualRowCount++;\r\n loopCount++;\r\n assert.isDefined(reader.current[0]);\r\n assert.equal(reader.current[0], expectedInstanceIds[actualRowCount - 1]);\r\n }\r\n assert.equal(loopCount, 10);\r\n iModel.clearCaches();\r\n\r\n reader.step(); // step should fail after clearCaches\r\n })).to.throw(\"Step failed\");\r\n });\r\n it(\"should throw error if we try to step on a closed iModelDb object\", () => {\r\n const imodelPath = iModel.pathName;\r\n expect(() => iModel.withQueryReader(\"SELECT * FROM bis.Element\", (reader) => {\r\n let loopCount = 0;\r\n while (loopCount < 10) {\r\n reader.step();\r\n assert.isDefined(reader.current[0]);\r\n loopCount++;\r\n }\r\n assert.equal(loopCount, 10);\r\n iModel.close();\r\n\r\n iModel = SnapshotDb.openFile(imodelPath);\r\n assert.isDefined(reader.current[0]);\r\n reader.step(); // step should fail after iModelDb is closed\r\n })).to.throw(\"Statement is not prepared\");\r\n });\r\n it(\"returning reader from withQueryReader callback should throw error if we try to step on it\", () => {\r\n const readerObj = iModel.withQueryReader(\"SELECT * FROM bis.Element\", (reader) => {\r\n reader.step();\r\n return reader;\r\n });\r\n expect(readerObj.current[0]).to.equal(\"0x1\"); // will not throw error as we are just accessing current row\r\n expect(() => readerObj.step()).to.throw(\"Statement is not prepared\");\r\n });\r\n it(\"checking rowFormat unspecified case - values accessed by index\", () => {\r\n // Default rowFormat is UseECSqlPropertyIndexes: columns are accessed by their SELECT-order index.\r\n iModel.withQueryReader(\"SELECT ECInstanceId, ECClassId FROM bis.Element\", (reader) => {\r\n assert.isTrue(reader.step());\r\n const id: string = reader.current[0];\r\n const classId: string = reader.current[1];\r\n assert.isTrue(Id64.isValid(classId));\r\n assert.isTrue(Id64.isValid(id));\r\n assert.equal(id, \"0x19\");\r\n });\r\n });\r\n\r\n it(\"checking rowFormat UseECSqlPropertyIndexes - values accessed by index\", () => {\r\n const config = new QueryOptionsBuilder().setRowFormat(QueryRowFormat.UseECSqlPropertyIndexes).getOptions();\r\n iModel.withQueryReader(\"SELECT ECInstanceId, ECClassId FROM bis.Element\", (reader) => {\r\n assert.isTrue(reader.step());\r\n // Index 0 → ECInstanceId, index 1 → ECClassId\r\n const id: string = reader.current[0];\r\n const classId: string = reader.current[1];\r\n assert.equal(id, \"0x19\");\r\n assert.isTrue(Id64.isValid(classId));\r\n // Swapping column order changes index, not value\r\n }, undefined, config);\r\n });\r\n\r\n it(\"checking rowFormat UseECSqlPropertyNames - values accessed by ECSQL property name\", () => {\r\n const config = new QueryOptionsBuilder().setRowFormat(QueryRowFormat.UseECSqlPropertyNames).getOptions();\r\n iModel.withQueryReader(\"SELECT ECInstanceId, ECClassId FROM bis.Element\", (reader) => {\r\n assert.isTrue(reader.step());\r\n const id: string = reader.current.ECInstanceId;\r\n const classId: string = reader.current.ECClassId;\r\n assert.equal(id, \"0x19\");\r\n assert.isTrue(Id64.isValid(classId));\r\n }, undefined, config);\r\n });\r\n\r\n it(\"checking rowFormat UseJsPropertyNames - values accessed by JavaScript property name\", () => {\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n const config = new QueryOptionsBuilder().setRowFormat(QueryRowFormat.UseJsPropertyNames).getOptions();\r\n iModel.withQueryReader(\"SELECT ECInstanceId, ECClassId FROM bis.Element\", (reader) => {\r\n assert.isTrue(reader.step());\r\n // ECInstanceId → id, ECClassId → className (resolved to a fully-qualified class name string)\r\n const id: string = reader.current.id;\r\n const className: string = reader.current.className;\r\n assert.equal(id, \"0x19\");\r\n // className should be in the form \"SchemaName.ClassName\"\r\n assert.equal(className, \"BisCore.DrawingCategory\");\r\n }, undefined, config);\r\n });\r\n\r\n it(\"checking rowFormat UseECSqlPropertyNames with convertClassIdsToClassNames - ECClassId returned as class name string\", () => {\r\n const config = new QueryOptionsBuilder()\r\n .setRowFormat(QueryRowFormat.UseECSqlPropertyNames)\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n .setConvertClassIdsToNames(true)\r\n .getOptions();\r\n iModel.withQueryReader(\"SELECT ECInstanceId, ECClassId FROM bis.Element\", (reader) => {\r\n assert.isTrue(reader.step());\r\n const id: string = reader.current.ECInstanceId;\r\n const classId: string = reader.current.ECClassId;\r\n assert.equal(id, \"0x19\");\r\n // With convertClassIdsToClassNames, ECClassId is resolved to \"SchemaName.ClassName\" instead of an Id\r\n assert.equal(classId, \"BisCore.DrawingCategory\");\r\n }, undefined, config);\r\n });\r\n\r\n describe(\"statement caching (regression)\", () => {\r\n // `withQueryReader` used to build a fresh `ECSqlStatement` and re-compile the ECSQL on every\r\n // call (via `ECSqlRowExecutor`), with no caching. Callers such as `IModelTransformer` invoke\r\n // per-element helpers (e.g. `hasSubModel`) once per element, so on large models this turned one\r\n // cached ECSQL prepare into N full native compiles - a significant performance regression. The\r\n // reader now reuses a prepared statement from the owning db's `_statementCache`.\r\n const sql = \"SELECT ECInstanceId FROM bis.Element WHERE ECInstanceId=?\";\r\n\r\n afterEach(() => sinon.restore());\r\n\r\n it(\"reuses a single prepared statement across repeated calls instead of re-preparing\", () => {\r\n iModel.clearCaches();\r\n const prepareSpy = sinon.spy(ECSqlStatement.prototype, \"prepare\"); // eslint-disable-line @typescript-eslint/no-deprecated\r\n for (let i = 0; i < 20; i++) {\r\n iModel.withQueryReader(sql, (reader) => {\r\n reader.step();\r\n }, new QueryBinder().bindId(1, \"0x1\"));\r\n }\r\n expect(prepareSpy.callCount).to.equal(1, \"queries with identical ECSQL text should re-use one cached prepared statement\");\r\n });\r\n\r\n it(\"keeps nested withQueryReader calls on the same SQL independent\", () => {\r\n iModel.clearCaches();\r\n // A nested reader on the same SQL must get its own statement (findAndRemove hands the outer\r\n // reader's statement out of the cache), so results do not corrupt each other.\r\n const outerId = iModel.withQueryReader(sql, (outer) => {\r\n assert.isTrue(outer.step());\r\n const innerId = iModel.withQueryReader(sql, (inner) => {\r\n assert.isTrue(inner.step());\r\n return inner.current[0] as string;\r\n }, new QueryBinder().bindId(1, \"0xe\"));\r\n expect(innerId).to.equal(\"0xe\");\r\n // Outer reader's cursor must be unaffected by the nested reader.\r\n return outer.current[0] as string;\r\n }, new QueryBinder().bindId(1, \"0x1\"));\r\n expect(outerId).to.equal(\"0x1\");\r\n });\r\n\r\n it(\"recovers from a prepare failure without poisoning the cache\", () => {\r\n iModel.clearCaches();\r\n const invalidSql = \"SELECT * FROM bis.ThisClassDoesNotExist\";\r\n const prepareSpy = sinon.spy(ECSqlStatement.prototype, \"prepare\"); // eslint-disable-line @typescript-eslint/no-deprecated\r\n expect(() => iModel.withQueryReader(invalidSql, (reader) => reader.step())).to.throw();\r\n expect(() => iModel.withQueryReader(invalidSql, (reader) => reader.step())).to.throw();\r\n expect(prepareSpy.callCount).to.equal(2, \"a statement that failed to prepare must not be cached\");\r\n\r\n iModel.withQueryReader(sql, (reader) => {\r\n assert.isTrue(reader.step());\r\n expect(reader.current[0]).to.equal(\"0x1\");\r\n }, new QueryBinder().bindId(1, \"0x1\"));\r\n });\r\n\r\n it(\"releases the executor and cached statement when binding fails during reader construction\", () => {\r\n iModel.clearCaches();\r\n const prepareSpy = sinon.spy(ECSqlStatement.prototype, \"prepare\"); // eslint-disable-line @typescript-eslint/no-deprecated\r\n iModel.withQueryReader(sql, (reader) => reader.step(), new QueryBinder().bindId(1, \"0x1\"));\r\n const listenerCount = iModel.onBeforeClose.numberOfListeners;\r\n\r\n const bindStub = sinon.stub(ECSqlStatement.prototype, \"bindParams\").throws(new Error(\"Expected bind failure\")); // eslint-disable-line @typescript-eslint/no-deprecated\r\n expect(() => iModel.withQueryReader(sql, () => undefined, new QueryBinder().bindId(1, \"0x1\"))).to.throw(\"Expected bind failure\");\r\n bindStub.restore();\r\n expect(iModel.onBeforeClose.numberOfListeners).to.equal(listenerCount);\r\n\r\n iModel.withQueryReader(sql, (reader) => reader.step(), new QueryBinder().bindId(1, \"0x1\"));\r\n expect(prepareSpy.callCount).to.equal(1, \"the statement checked out before the bind failure should be returned to the cache\");\r\n });\r\n\r\n it(\"also caches for ECDb.withQueryReader (shared ECSqlRowExecutor path)\", () => {\r\n using ecdb = ECDbTestHelper.createECDb(KnownTestLocations.outputDir, \"syncReaderStmtCache.ecdb\",\r\n `<ECSchema schemaName=\"Test\" alias=\"ts\" version=\"01.00.00\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\r\n <ECEntityClass typeName=\"Foo\" modifier=\"Sealed\">\r\n <ECProperty propertyName=\"n\" typeName=\"int\"/>\r\n </ECEntityClass>\r\n </ECSchema>`);\r\n ecdb.saveChanges();\r\n const ecdbSql = \"SELECT ECInstanceId FROM meta.ECClassDef WHERE ECInstanceId=?\";\r\n const prepareSpy = sinon.spy(ECSqlStatement.prototype, \"prepare\"); // eslint-disable-line @typescript-eslint/no-deprecated\r\n for (let i = 0; i < 10; i++)\r\n ecdb.withQueryReader(ecdbSql, (reader) => reader.step(), new QueryBinder().bindId(1, \"0x1\"));\r\n expect(prepareSpy.callCount).to.equal(1, \"ECDb.withQueryReader should also reuse a cached prepared statement\");\r\n });\r\n });\r\n\r\n describe(\"metadata caching\", () => {\r\n // Column metadata depends only on the prepared statement and the row-adaptor options, so it is cached\r\n // on the cached ECSqlStatement instead of being fetched from native code on every withQueryReader call.\r\n const sql = \"SELECT ECInstanceId, ECClassId, CodeValue, GeometryStream FROM bis.GeometricElement3d WHERE ECInstanceId=?\";\r\n let elementId: string;\r\n\r\n before(() => {\r\n elementId = iModel.withQueryReader(\"SELECT ECInstanceId FROM bis.GeometricElement3d WHERE GeometryStream IS NOT NULL LIMIT 1\", (reader) => {\r\n assert.isTrue(reader.step());\r\n return reader.current[0] as string;\r\n });\r\n });\r\n\r\n afterEach(() => sinon.restore());\r\n\r\n function readMetadata(options: SynchronousQueryOptions): { meta: QueryPropertyMetaData[], row: any } {\r\n return iModel.withQueryReader(sql, (reader) => {\r\n assert.isTrue(reader.step());\r\n return { meta: reader.getMetaData(), row: reader.current.toRow() };\r\n }, new QueryBinder().bindId(1, elementId), options);\r\n }\r\n\r\n it(\"returns metadata matching the row options when the same statement is reused with different options\", () => {\r\n const optionSets: SynchronousQueryOptions[] = [\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n { rowFormat: QueryRowFormat.UseJsPropertyNames },\r\n { rowFormat: QueryRowFormat.UseECSqlPropertyNames },\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n { rowFormat: QueryRowFormat.UseJsPropertyNames, abbreviateBlobs: true },\r\n { rowFormat: QueryRowFormat.UseECSqlPropertyNames, abbreviateBlobs: true },\r\n { rowFormat: QueryRowFormat.UseECSqlPropertyNames, convertClassIdsToClassNames: true },\r\n ];\r\n\r\n // Expected metadata comes from a freshly prepared statement for each option set.\r\n const expected = optionSets.map((options) => {\r\n iModel.clearCaches();\r\n return readMetadata({ ...options }).meta;\r\n });\r\n expect(expected[0].map((p) => p.jsonName)).to.deep.equal([\"id\", \"className\", \"codeValue\", \"geometryStream\"]);\r\n expect(expected[1].map((p) => p.name)).to.deep.equal([\"ECInstanceId\", \"ECClassId\", \"CodeValue\", \"GeometryStream\"]);\r\n\r\n iModel.clearCaches();\r\n for (let pass = 0; pass < 2; pass++) {\r\n optionSets.forEach((options, i) => {\r\n const { meta, row } = readMetadata({ ...options });\r\n expect(meta).to.deep.equal(expected[i]);\r\n const geometryStream = row[options.rowFormat === QueryRowFormat.UseECSqlPropertyNames ? \"GeometryStream\" : \"geometryStream\"];\r\n if (options.abbreviateBlobs)\r\n expect(geometryStream).to.be.a(\"string\").and.match(/^\\{\"bytes\":\\d+\\}$/);\r\n else\r\n expect(geometryStream).to.be.instanceOf(Uint8Array);\r\n });\r\n }\r\n });\r\n\r\n it(\"fetches native metadata once per statement and row options\", () => {\r\n // Native prototype methods cannot be spied on directly, so count calls through a subclass.\r\n const getMetadataSpy = sinon.spy();\r\n const nativeStatement = IModelNative.platform.ECSqlStatement;\r\n sinon.replace(IModelNative.platform, \"ECSqlStatement\", class extends nativeStatement {\r\n public override getMetadata(...args: Parameters<typeof nativeStatement.prototype.getMetadata>) {\r\n getMetadataSpy();\r\n return super.getMetadata(...args);\r\n }\r\n });\r\n iModel.clearCaches();\r\n const options = { rowFormat: QueryRowFormat.UseECSqlPropertyNames };\r\n for (let i = 0; i < 10; i++)\r\n readMetadata({ ...options });\r\n expect(getMetadataSpy.callCount).to.equal(1);\r\n\r\n readMetadata({ ...options, abbreviateBlobs: true });\r\n readMetadata({ ...options, abbreviateBlobs: true });\r\n expect(getMetadataSpy.callCount).to.equal(2, \"different row options need their own metadata\");\r\n\r\n iModel.clearCaches();\r\n readMetadata({ ...options });\r\n expect(getMetadataSpy.callCount).to.equal(3, \"a re-prepared statement must not reuse cached metadata\");\r\n });\r\n\r\n it(\"does not share metadata objects between calls\", () => {\r\n iModel.clearCaches();\r\n const options = { rowFormat: QueryRowFormat.UseECSqlPropertyNames };\r\n const expected = structuredClone(readMetadata({ ...options }).meta);\r\n\r\n iModel.withQueryReader(sql, (reader) => {\r\n assert.isTrue(reader.step());\r\n const readerMeta = reader.getMetaData();\r\n readerMeta[0].name = \"Changed\";\r\n readerMeta[0].index = 3;\r\n readerMeta.reverse();\r\n const proxyMeta = reader.current.getMetaData();\r\n proxyMeta.push({ ...proxyMeta[0], name: \"Extra\" });\r\n }, new QueryBinder().bindId(1, elementId), options);\r\n\r\n const { meta, row } = readMetadata({ ...options });\r\n expect(meta).to.deep.equal(expected);\r\n expect(row.ECInstanceId).to.equal(elementId);\r\n });\r\n\r\n it(\"returns metadata for queries that produce no rows\", () => {\r\n iModel.clearCaches();\r\n const options = { rowFormat: QueryRowFormat.UseECSqlPropertyNames };\r\n const expected = readMetadata({ ...options }).meta;\r\n for (let i = 0; i < 3; i++) {\r\n iModel.withQueryReader(sql, (reader) => {\r\n expect(reader.step()).to.be.false;\r\n expect(reader.getMetaData()).to.deep.equal(expected);\r\n }, new QueryBinder().bindId(1, \"0xffffff\"), options);\r\n iModel.withQueryReader(sql, (reader) => {\r\n expect(reader.getMetaData()).to.deep.equal(expected);\r\n expect(reader.toArray()).to.deep.equal([]);\r\n }, new QueryBinder().bindId(1, \"0xffffff\"), options);\r\n }\r\n });\r\n\r\n it(\"reflects a schema import between calls\", () => {\r\n const schemaXml = (version: string, extraProperty: string) => `<ECSchema schemaName=\"Test\" alias=\"ts\" version=\"${version}\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\r\n <ECEntityClass typeName=\"Foo\" modifier=\"Sealed\">\r\n <ECProperty propertyName=\"n\" typeName=\"int\"/>\r\n ${extraProperty}\r\n </ECEntityClass>\r\n </ECSchema>`;\r\n using ecdb = ECDbTestHelper.createECDb(KnownTestLocations.outputDir, \"syncReaderMetadataCache.ecdb\", schemaXml(\"01.00.00\", \"\"));\r\n ecdb.withCachedWriteStatement(\"INSERT INTO ts.Foo(n) VALUES(1)\", (stmt) => stmt.stepForInsert());\r\n ecdb.saveChanges();\r\n\r\n const fooSql = \"SELECT * FROM ts.Foo\";\r\n const options = { rowFormat: QueryRowFormat.UseECSqlPropertyNames };\r\n const readNames = () => ecdb.withQueryReader(fooSql, (reader) => {\r\n assert.isTrue(reader.step());\r\n return reader.getMetaData().map((p) => p.name);\r\n }, undefined, options);\r\n expect(readNames()).to.deep.equal([\"ECInstanceId\", \"ECClassId\", \"n\"]);\r\n expect(readNames()).to.deep.equal([\"ECInstanceId\", \"ECClassId\", \"n\"]);\r\n\r\n const schemaPath = path.join(KnownTestLocations.outputDir, \"syncReaderMetadataCache.ecschema.xml\");\r\n IModelJsFs.writeFileSync(schemaPath, schemaXml(\"01.00.01\", `<ECProperty propertyName=\"m\" typeName=\"string\"/>`));\r\n ecdb.importSchema(schemaPath);\r\n ecdb.saveChanges();\r\n\r\n expect(readNames()).to.deep.equal([\"ECInstanceId\", \"ECClassId\", \"n\", \"m\"]);\r\n });\r\n });\r\n});\r\n"]}
|
|
1
|
+
{"version":3,"file":"ECSqlSyncReader.test.js","sourceRoot":"","sources":["../../../../src/test/ecdb/ECSqlSyncReader.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { assert, expect } from \"chai\";\r\nimport * as sinon from \"sinon\";\r\nimport * as path from \"node:path\";\r\nimport { QueryBinder, QueryOptionsBuilder, QueryPropertyMetaData, QueryRowFormat } from \"@itwin/core-common\";\r\nimport { IModelDb, SnapshotDb } from \"../../IModelDb\";\r\nimport { IModelTestUtils } from \"../IModelTestUtils\";\r\nimport { DbResult, Id64 } from \"@itwin/core-bentley\";\r\nimport { ECDb } from \"../../ECDb\";\r\nimport { _nativeDb } from \"../../internal/Symbols\";\r\nimport { SyncReaderRowFlags } from \"../../ECSqlRowExecutor\";\r\nimport { ECDbTestHelper } from \"./ECDbTestHelper\";\r\nimport { KnownTestLocations } from \"../KnownTestLocations\";\r\nimport { IModelJsFs } from \"../../IModelJsFs\";\r\nimport { SynchronousQueryOptions } from \"../../ECSqlSyncReader\";\r\n\r\ndescribe(\"WithQueryReaderTests\", () => {\r\n let iModel: SnapshotDb;\r\n\r\n before(async () => {\r\n iModel = SnapshotDb.openFile(IModelTestUtils.resolveAssetFile(\"test.bim\"));\r\n });\r\n\r\n after(async () => {\r\n iModel.close();\r\n });\r\n it(\"check behvaiour if we call clearCaches in between\", () => {\r\n let actualRowCount = 0;\r\n const expectedInstanceIds = [\"0x1\", \"0xe\", \"0x10\", \"0x11\", \"0x12\",\r\n \"0x13\", \"0x14\", \"0x15\", \"0x16\", \"0x17\"];\r\n\r\n expect(() => iModel.withQueryReader(\"SELECT * FROM bis.Element\", (reader) => {\r\n let loopCount = 0;\r\n // First loop - read first 10 rows\r\n while (loopCount < 10) {\r\n reader.step()\r\n actualRowCount++;\r\n loopCount++;\r\n assert.isDefined(reader.current[0]);\r\n assert.equal(reader.current[0], expectedInstanceIds[actualRowCount - 1]);\r\n }\r\n assert.equal(loopCount, 10);\r\n iModel.clearCaches();\r\n\r\n // Rows already read ahead are still returned; stepping past them must fail.\r\n while (reader.step())\r\n assert.isDefined(reader.current[0]);\r\n })).to.throw(\"Step failed\");\r\n });\r\n function readCountedRows(db: IModelDb | ECDb) {\r\n const ecsql = \"WITH RECURSIVE cnt(x) AS (SELECT 1 UNION ALL SELECT x + 1 FROM cnt WHERE x < ?) SELECT x FROM cnt\";\r\n // Read-only dbs read ahead in batches of 4 -> 16 -> 64 -> 128 rows, so these counts cover each boundary and its neighbours.\r\n for (const rowCount of [1, 3, 4, 5, 19, 20, 21, 83, 84, 85, 211, 212, 213, 339, 340, 341, 1000]) {\r\n const values = db.withQueryReader(ecsql, (reader) => {\r\n const rows: number[] = [];\r\n while (reader.step())\r\n rows.push(reader.current[0]);\r\n assert.isFalse(reader.step(), \"stepping after the end keeps returning false\");\r\n return rows;\r\n }, QueryBinder.from([rowCount]));\r\n expect(values).to.deep.equal(Array.from({ length: rowCount }, (_, i) => i + 1), `rowCount=${rowCount}`);\r\n }\r\n }\r\n\r\n it(\"returns every row in order across read-ahead batch boundaries\", () => {\r\n assert.isTrue(iModel.isReadonly);\r\n readCountedRows(iModel);\r\n });\r\n\r\n it(\"returns every row in order from a writable db\", () => {\r\n using ecdb = ECDbTestHelper.createECDb(KnownTestLocations.outputDir, \"syncReaderWritableRowOrder.ecdb\");\r\n readCountedRows(ecdb);\r\n });\r\n\r\n function readMixedRows(db: IModelDb | ECDb) {\r\n // Infinity cannot be written as JSON, so those rows are rendered individually between JSON-rendered rows.\r\n const ecsql = \"WITH RECURSIVE cnt(x) AS (SELECT 1 UNION ALL SELECT x + 1 FROM cnt WHERE x < 100) SELECT x, CASE WHEN x % 2 = 0 THEN NULL ELSE x END, CASE WHEN x % 7 = 0 THEN 1e308 * 10 ELSE x * 2 END FROM cnt\";\r\n const rows = db.withQueryReader(ecsql, (reader) => {\r\n const result: any[][] = [];\r\n while (reader.step())\r\n result.push([reader.current[0], reader.current[1], reader.current[2]]);\r\n return result;\r\n });\r\n expect(rows).to.deep.equal(Array.from({ length: 100 }, (_, i) => {\r\n const x = i + 1;\r\n return [x, x % 2 === 0 ? undefined : x, x % 7 === 0 ? Infinity : x * 2];\r\n }));\r\n }\r\n\r\n it(\"returns null cells as undefined and non-finite values from read-ahead batches\", () => {\r\n readMixedRows(iModel);\r\n });\r\n\r\n it(\"returns null cells as undefined and non-finite values from a writable db\", () => {\r\n using ecdb = ECDbTestHelper.createECDb(KnownTestLocations.outputDir, \"syncReaderMixedRows.ecdb\");\r\n readMixedRows(ecdb);\r\n });\r\n\r\n it(\"returns the same rows whether the native batch is rendered as JSON or cell by cell\", () => {\r\n const readNative = (ecsql: string, renderAsJson: boolean, options: SynchronousQueryOptions = {}) => {\r\n let rowFlags = SyncReaderRowFlags.DoNotConvertClassIdsToClassNamesWhenAliased;\r\n if (options.abbreviateBlobs)\r\n rowFlags |= SyncReaderRowFlags.AbbreviateBlobs;\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n if (options.convertClassIdsToClassNames)\r\n rowFlags |= SyncReaderRowFlags.ClassIdsToClassNames;\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n if (options.rowFormat === QueryRowFormat.UseJsPropertyNames)\r\n rowFlags |= SyncReaderRowFlags.UseJsName;\r\n const out: any[] = [];\r\n const reader = iModel[_nativeDb].prepareECSqlBatchReader(ecsql, undefined, rowFlags, 0, out);\r\n try {\r\n expect(out[0]).to.be.undefined;\r\n const rows: any[] = [];\r\n for (;;) {\r\n const batch = reader.stepBatch(16, renderAsJson);\r\n if (typeof batch === \"number\") {\r\n expect(batch).to.equal(DbResult.BE_SQLITE_DONE);\r\n return rows;\r\n }\r\n if (renderAsJson)\r\n expect(batch).to.be.a(\"string\");\r\n rows.push(...(typeof batch === \"string\" ? JSON.parse(batch) : batch));\r\n }\r\n } finally {\r\n reader.dispose();\r\n }\r\n };\r\n\r\n for (const ecsql of [\r\n \"SELECT * FROM bis.Element\",\r\n \"SELECT * FROM bis.GeometricElement3d\",\r\n \"SELECT ECInstanceId,ECClassId,Model,Parent,Origin,BBoxLow,BBoxHigh FROM bis.GeometricElement3d ORDER BY ECInstanceId\",\r\n ]) {\r\n for (const options of [\r\n {},\r\n { convertClassIdsToClassNames: true },\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n { rowFormat: QueryRowFormat.UseJsPropertyNames, convertClassIdsToClassNames: true },\r\n { abbreviateBlobs: true },\r\n {},\r\n ]) {\r\n const expected = readNative(ecsql, false, options);\r\n assert.isAbove(expected.length, 0);\r\n const actual = iModel.withQueryReader(ecsql, (reader) => {\r\n const rows: any[] = [];\r\n while (reader.step())\r\n rows.push(reader.current.toArray());\r\n return rows;\r\n }, undefined, { ...options });\r\n expect(actual).to.deep.equal(expected, ecsql);\r\n }\r\n }\r\n const blobs = readNative(\"SELECT GeometryStream FROM bis.GeometricElement3d WHERE GeometryStream IS NOT NULL\", false);\r\n assert.isAbove(blobs.length, 0);\r\n assert.isTrue(blobs.every((row) => row[0] instanceof Uint8Array));\r\n });\r\n\r\n it(\"preserves non-finite mapped double values when using the prepared renderer\", () => {\r\n const schema = `<ECSchema schemaName=\"SyncRendering\" alias=\"sr\" version=\"01.00.00\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\r\n <ECEntityClass typeName=\"Sample\"><ECProperty propertyName=\"Amount\" typeName=\"double\"/></ECEntityClass>\r\n </ECSchema>`;\r\n using ecdb = ECDbTestHelper.createECDb(KnownTestLocations.outputDir, \"syncReaderMappedDoubles.ecdb\", schema);\r\n for (const value of [\"42.0\", \"1e308 * 10\", \"-1e308 * 10\", \"43.0\"])\r\n ecdb.withCachedWriteStatement(`INSERT INTO sr.Sample(Amount) VALUES(${value})`, (stmt) => stmt.stepForInsert());\r\n ecdb.saveChanges();\r\n const actual = ecdb.withQueryReader(\"SELECT Amount FROM sr.Sample ORDER BY ECInstanceId\", (reader) => reader.toArray());\r\n expect(actual).to.deep.equal([[42], [Infinity], [-Infinity], [43]]);\r\n });\r\n\r\n it(\"restarts from the first row when a query is reused after an early exit\", () => {\r\n const ecsql = \"WITH RECURSIVE cnt(x) AS (SELECT 1 UNION ALL SELECT x + 1 FROM cnt WHERE x < 500) SELECT x FROM cnt\";\r\n for (const take of [1, 4, 5, 30]) {\r\n const values = iModel.withQueryReader(ecsql, (reader) => {\r\n const rows: number[] = [];\r\n while (rows.length < take && reader.step())\r\n rows.push(reader.current[0]);\r\n return rows;\r\n });\r\n expect(values).to.deep.equal(Array.from({ length: take }, (_, i) => i + 1));\r\n }\r\n });\r\n\r\n it(\"should throw error if we try to step on a closed iModelDb object\", () => {\r\n const imodelPath = iModel.pathName;\r\n expect(() => iModel.withQueryReader(\"SELECT * FROM bis.Element\", (reader) => {\r\n let loopCount = 0;\r\n while (loopCount < 10) {\r\n reader.step();\r\n assert.isDefined(reader.current[0]);\r\n loopCount++;\r\n }\r\n assert.equal(loopCount, 10);\r\n iModel.close();\r\n\r\n iModel = SnapshotDb.openFile(imodelPath);\r\n assert.isDefined(reader.current[0]);\r\n reader.step(); // step should fail after iModelDb is closed\r\n })).to.throw(\"Statement is not prepared\");\r\n });\r\n it(\"returning reader from withQueryReader callback should throw error if we try to step on it\", () => {\r\n const readerObj = iModel.withQueryReader(\"SELECT * FROM bis.Element\", (reader) => {\r\n reader.step();\r\n return reader;\r\n });\r\n expect(readerObj.current[0]).to.equal(\"0x1\"); // will not throw error as we are just accessing current row\r\n expect(() => readerObj.step()).to.throw(\"Statement is not prepared\");\r\n });\r\n it(\"checking rowFormat unspecified case - values accessed by index\", () => {\r\n // Default rowFormat is UseECSqlPropertyIndexes: columns are accessed by their SELECT-order index.\r\n iModel.withQueryReader(\"SELECT ECInstanceId, ECClassId FROM bis.Element\", (reader) => {\r\n assert.isTrue(reader.step());\r\n const id: string = reader.current[0];\r\n const classId: string = reader.current[1];\r\n assert.isTrue(Id64.isValid(classId));\r\n assert.isTrue(Id64.isValid(id));\r\n assert.equal(id, \"0x19\");\r\n });\r\n });\r\n\r\n it(\"checking rowFormat UseECSqlPropertyIndexes - values accessed by index\", () => {\r\n const config = new QueryOptionsBuilder().setRowFormat(QueryRowFormat.UseECSqlPropertyIndexes).getOptions();\r\n iModel.withQueryReader(\"SELECT ECInstanceId, ECClassId FROM bis.Element\", (reader) => {\r\n assert.isTrue(reader.step());\r\n // Index 0 → ECInstanceId, index 1 → ECClassId\r\n const id: string = reader.current[0];\r\n const classId: string = reader.current[1];\r\n assert.equal(id, \"0x19\");\r\n assert.isTrue(Id64.isValid(classId));\r\n // Swapping column order changes index, not value\r\n }, undefined, config);\r\n });\r\n\r\n it(\"checking rowFormat UseECSqlPropertyNames - values accessed by ECSQL property name\", () => {\r\n const config = new QueryOptionsBuilder().setRowFormat(QueryRowFormat.UseECSqlPropertyNames).getOptions();\r\n iModel.withQueryReader(\"SELECT ECInstanceId, ECClassId FROM bis.Element\", (reader) => {\r\n assert.isTrue(reader.step());\r\n const id: string = reader.current.ECInstanceId;\r\n const classId: string = reader.current.ECClassId;\r\n assert.equal(id, \"0x19\");\r\n assert.isTrue(Id64.isValid(classId));\r\n }, undefined, config);\r\n });\r\n\r\n it(\"checking rowFormat UseJsPropertyNames - values accessed by JavaScript property name\", () => {\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n const config = new QueryOptionsBuilder().setRowFormat(QueryRowFormat.UseJsPropertyNames).getOptions();\r\n iModel.withQueryReader(\"SELECT ECInstanceId, ECClassId FROM bis.Element\", (reader) => {\r\n assert.isTrue(reader.step());\r\n // ECInstanceId → id, ECClassId → className (resolved to a fully-qualified class name string)\r\n const id: string = reader.current.id;\r\n const className: string = reader.current.className;\r\n assert.equal(id, \"0x19\");\r\n // className should be in the form \"SchemaName.ClassName\"\r\n assert.equal(className, \"BisCore.DrawingCategory\");\r\n }, undefined, config);\r\n });\r\n\r\n it(\"checking rowFormat UseECSqlPropertyNames with convertClassIdsToClassNames - ECClassId returned as class name string\", () => {\r\n const config = new QueryOptionsBuilder()\r\n .setRowFormat(QueryRowFormat.UseECSqlPropertyNames)\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n .setConvertClassIdsToNames(true)\r\n .getOptions();\r\n iModel.withQueryReader(\"SELECT ECInstanceId, ECClassId FROM bis.Element\", (reader) => {\r\n assert.isTrue(reader.step());\r\n const id: string = reader.current.ECInstanceId;\r\n const classId: string = reader.current.ECClassId;\r\n assert.equal(id, \"0x19\");\r\n // With convertClassIdsToClassNames, ECClassId is resolved to \"SchemaName.ClassName\" instead of an Id\r\n assert.equal(classId, \"BisCore.DrawingCategory\");\r\n }, undefined, config);\r\n });\r\n\r\n /** Records the native readers leased by `withQueryReader` on `db`. N-API prototype methods are not configurable,\r\n * so the native db and each reader are instrumented through own properties.\r\n */\r\n function instrumentSyncReaders(db: IModelDb | ECDb) {\r\n const nativeDb = db[_nativeDb];\r\n const prepare = nativeDb.prepareECSqlBatchReader.bind(nativeDb);\r\n const statementIds: number[] = [];\r\n const getMetadataSpy = sinon.spy();\r\n Object.defineProperty(nativeDb, \"prepareECSqlBatchReader\", {\r\n configurable: true,\r\n value: (ecsql: string, args: any[] | undefined, rowFlags: number, maxRows: number, out: any[], logErrors?: boolean) => {\r\n const reader = prepare(ecsql, args, rowFlags, maxRows, out, logErrors);\r\n statementIds.push(out[1]);\r\n expect(out[1]).to.equal(reader.getStatementId());\r\n const getMetadata = reader.getMetadata.bind(reader);\r\n Object.defineProperty(reader, \"getMetadata\", {\r\n configurable: true,\r\n value: () => {\r\n getMetadataSpy();\r\n return getMetadata();\r\n },\r\n });\r\n return reader;\r\n },\r\n });\r\n return {\r\n statementIds,\r\n getMetadataSpy,\r\n [Symbol.dispose]: () => { delete (nativeDb as any).prepareECSqlBatchReader; },\r\n };\r\n }\r\n\r\n describe(\"statement caching (regression)\", () => {\r\n // `withQueryReader` used to build a fresh statement and re-compile the ECSQL on every call. Callers such as\r\n // `IModelTransformer` invoke per-element helpers (e.g. `hasSubModel`) once per element, so on large models this\r\n // turned one cached ECSQL prepare into N full native compiles. The reader now leases a prepared statement from\r\n // the native concurrent query statement cache of the primary connection.\r\n const sql = \"SELECT ECInstanceId FROM bis.Element WHERE ECInstanceId=?\";\r\n\r\n afterEach(() => sinon.restore());\r\n\r\n it(\"reuses a single prepared statement across repeated calls instead of re-preparing\", () => {\r\n iModel.clearCaches();\r\n using readers = instrumentSyncReaders(iModel);\r\n for (let i = 0; i < 20; i++) {\r\n iModel.withQueryReader(sql, (reader) => {\r\n reader.step();\r\n }, new QueryBinder().bindId(1, \"0x1\"));\r\n }\r\n expect(readers.statementIds).to.have.lengthOf(20);\r\n expect(new Set(readers.statementIds).size).to.equal(1, \"queries with identical ECSQL text should re-use one cached prepared statement\");\r\n });\r\n\r\n it(\"keeps nested withQueryReader calls on the same SQL independent\", () => {\r\n iModel.clearCaches();\r\n using readers = instrumentSyncReaders(iModel);\r\n // A nested reader on the same SQL must get its own statement while the outer one is leased,\r\n // so results do not corrupt each other.\r\n const outerId = iModel.withQueryReader(sql, (outer) => {\r\n assert.isTrue(outer.step());\r\n const innerId = iModel.withQueryReader(sql, (inner) => {\r\n assert.isTrue(inner.step());\r\n return inner.current[0] as string;\r\n }, new QueryBinder().bindId(1, \"0xe\"));\r\n expect(innerId).to.equal(\"0xe\");\r\n // Outer reader's cursor must be unaffected by the nested reader.\r\n return outer.current[0] as string;\r\n }, new QueryBinder().bindId(1, \"0x1\"));\r\n expect(outerId).to.equal(\"0x1\");\r\n expect(readers.statementIds[0]).to.not.equal(readers.statementIds[1]);\r\n });\r\n\r\n it(\"recovers from a prepare failure without poisoning the cache\", () => {\r\n iModel.clearCaches();\r\n const invalidSql = \"SELECT * FROM bis.ThisClassDoesNotExist\";\r\n expect(() => iModel.withQueryReader(invalidSql, (reader) => reader.step())).to.throw();\r\n expect(() => iModel.withQueryReader(invalidSql, (reader) => reader.step())).to.throw();\r\n\r\n using readers = instrumentSyncReaders(iModel);\r\n for (let i = 0; i < 2; i++) {\r\n iModel.withQueryReader(sql, (reader) => {\r\n assert.isTrue(reader.step());\r\n expect(reader.current[0]).to.equal(\"0x1\");\r\n }, new QueryBinder().bindId(1, \"0x1\"));\r\n }\r\n expect(new Set(readers.statementIds).size).to.equal(1);\r\n });\r\n\r\n it(\"releases the executor and cached statement when binding fails during reader construction\", () => {\r\n iModel.clearCaches();\r\n iModel.withQueryReader(sql, (reader) => reader.step(), new QueryBinder().bindId(1, \"0x1\"));\r\n const listenerCount = iModel.onBeforeClose.numberOfListeners;\r\n\r\n using readers = instrumentSyncReaders(iModel);\r\n expect(() => iModel.withQueryReader(sql, () => undefined, new QueryBinder().bindId(\"missing\", \"0x1\"))).to.throw(\"Failed to bind parameters\");\r\n expect(iModel.onBeforeClose.numberOfListeners).to.equal(listenerCount);\r\n expect(readers.statementIds).to.have.lengthOf(0, \"a reader is not created when binding fails\");\r\n\r\n iModel.withQueryReader(sql, (reader) => reader.step(), new QueryBinder().bindId(1, \"0x1\"));\r\n iModel.withQueryReader(sql, (reader) => reader.step(), new QueryBinder().bindId(1, \"0x1\"));\r\n expect(new Set(readers.statementIds).size).to.equal(1, \"the statement leased before the bind failure should be returned to the cache\");\r\n });\r\n\r\n it(\"also caches for ECDb.withQueryReader (shared ECSqlRowExecutor path)\", () => {\r\n using ecdb = ECDbTestHelper.createECDb(KnownTestLocations.outputDir, \"syncReaderStmtCache.ecdb\",\r\n `<ECSchema schemaName=\"Test\" alias=\"ts\" version=\"01.00.00\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\r\n <ECEntityClass typeName=\"Foo\" modifier=\"Sealed\">\r\n <ECProperty propertyName=\"n\" typeName=\"int\"/>\r\n </ECEntityClass>\r\n </ECSchema>`);\r\n ecdb.saveChanges();\r\n const ecdbSql = \"SELECT ECInstanceId FROM meta.ECClassDef WHERE ECInstanceId=?\";\r\n using readers = instrumentSyncReaders(ecdb);\r\n for (let i = 0; i < 10; i++)\r\n ecdb.withQueryReader(ecdbSql, (reader) => reader.step(), new QueryBinder().bindId(1, \"0x1\"));\r\n expect(new Set(readers.statementIds).size).to.equal(1, \"ECDb.withQueryReader should also reuse a cached prepared statement\");\r\n });\r\n });\r\n\r\n describe(\"metadata caching\", () => {\r\n // Column metadata depends only on the prepared statement and the row-adaptor options, so it is cached\r\n // per native statement id instead of being fetched from native code on every withQueryReader call.\r\n const sql = \"SELECT ECInstanceId, ECClassId, CodeValue, GeometryStream FROM bis.GeometricElement3d WHERE ECInstanceId=?\";\r\n let elementId: string;\r\n\r\n before(() => {\r\n elementId = iModel.withQueryReader(\"SELECT ECInstanceId FROM bis.GeometricElement3d WHERE GeometryStream IS NOT NULL LIMIT 1\", (reader) => {\r\n assert.isTrue(reader.step());\r\n return reader.current[0] as string;\r\n });\r\n });\r\n\r\n afterEach(() => sinon.restore());\r\n\r\n function readMetadata(options: SynchronousQueryOptions): { meta: QueryPropertyMetaData[], row: any } {\r\n return iModel.withQueryReader(sql, (reader) => {\r\n assert.isTrue(reader.step());\r\n return { meta: reader.getMetaData(), row: reader.current.toRow() };\r\n }, new QueryBinder().bindId(1, elementId), options);\r\n }\r\n\r\n it(\"returns metadata matching the row options when the same statement is reused with different options\", () => {\r\n const optionSets: SynchronousQueryOptions[] = [\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n { rowFormat: QueryRowFormat.UseJsPropertyNames },\r\n { rowFormat: QueryRowFormat.UseECSqlPropertyNames },\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n { rowFormat: QueryRowFormat.UseJsPropertyNames, abbreviateBlobs: true },\r\n { rowFormat: QueryRowFormat.UseECSqlPropertyNames, abbreviateBlobs: true },\r\n { rowFormat: QueryRowFormat.UseECSqlPropertyNames, convertClassIdsToClassNames: true },\r\n ];\r\n\r\n // Expected metadata comes from a freshly prepared statement for each option set.\r\n const expected = optionSets.map((options) => {\r\n iModel.clearCaches();\r\n return readMetadata({ ...options }).meta;\r\n });\r\n expect(expected[0].map((p) => p.jsonName)).to.deep.equal([\"id\", \"className\", \"codeValue\", \"geometryStream\"]);\r\n expect(expected[1].map((p) => p.name)).to.deep.equal([\"ECInstanceId\", \"ECClassId\", \"CodeValue\", \"GeometryStream\"]);\r\n\r\n iModel.clearCaches();\r\n for (let pass = 0; pass < 2; pass++) {\r\n optionSets.forEach((options, i) => {\r\n const { meta, row } = readMetadata({ ...options });\r\n expect(meta).to.deep.equal(expected[i]);\r\n const geometryStream = row[options.rowFormat === QueryRowFormat.UseECSqlPropertyNames ? \"GeometryStream\" : \"geometryStream\"];\r\n if (options.abbreviateBlobs)\r\n expect(geometryStream).to.be.a(\"string\").and.match(/^\\{\"bytes\":\\d+\\}$/);\r\n else\r\n expect(geometryStream).to.be.instanceOf(Uint8Array);\r\n });\r\n }\r\n });\r\n\r\n it(\"fetches native metadata once per statement and row options\", () => {\r\n using readers = instrumentSyncReaders(iModel);\r\n const getMetadataSpy = readers.getMetadataSpy;\r\n iModel.clearCaches();\r\n const options = { rowFormat: QueryRowFormat.UseECSqlPropertyNames };\r\n for (let i = 0; i < 10; i++)\r\n readMetadata({ ...options });\r\n expect(getMetadataSpy.callCount).to.equal(1);\r\n\r\n readMetadata({ ...options, abbreviateBlobs: true });\r\n readMetadata({ ...options, abbreviateBlobs: true });\r\n expect(getMetadataSpy.callCount).to.equal(2, \"different row options need their own metadata\");\r\n\r\n iModel.clearCaches();\r\n readMetadata({ ...options });\r\n expect(getMetadataSpy.callCount).to.equal(3, \"a re-prepared statement must not reuse cached metadata\");\r\n });\r\n\r\n it(\"does not share metadata objects between calls\", () => {\r\n iModel.clearCaches();\r\n const options = { rowFormat: QueryRowFormat.UseECSqlPropertyNames };\r\n const expected = structuredClone(readMetadata({ ...options }).meta);\r\n\r\n iModel.withQueryReader(sql, (reader) => {\r\n assert.isTrue(reader.step());\r\n const readerMeta = reader.getMetaData();\r\n readerMeta[0].name = \"Changed\";\r\n readerMeta[0].index = 3;\r\n readerMeta.reverse();\r\n const proxyMeta = reader.current.getMetaData();\r\n proxyMeta.push({ ...proxyMeta[0], name: \"Extra\" });\r\n }, new QueryBinder().bindId(1, elementId), options);\r\n\r\n const { meta, row } = readMetadata({ ...options });\r\n expect(meta).to.deep.equal(expected);\r\n expect(row.ECInstanceId).to.equal(elementId);\r\n });\r\n\r\n it(\"isolates metadata exposed only through the row proxy, including nested readers\", () => {\r\n const options = { rowFormat: QueryRowFormat.UseECSqlPropertyNames };\r\n const expected = structuredClone(readMetadata({ ...options }).meta);\r\n iModel.withQueryReader(sql, (outer) => {\r\n assert.isTrue(outer.step());\r\n const outerMeta = outer.current.getMetaData();\r\n iModel.withQueryReader(sql, (inner) => {\r\n assert.isTrue(inner.step());\r\n const innerMeta = inner.current.getMetaData();\r\n expect(innerMeta).to.deep.equal(expected);\r\n innerMeta[0].name = \"Changed\";\r\n innerMeta.reverse();\r\n }, new QueryBinder().bindId(1, elementId), { ...options });\r\n expect(outerMeta).to.deep.equal(expected);\r\n outerMeta[0].name = \"OuterChanged\";\r\n outerMeta.push({ ...outerMeta[0], name: \"Extra\" });\r\n }, new QueryBinder().bindId(1, elementId), { ...options });\r\n expect(readMetadata({ ...options }).meta).to.deep.equal(expected);\r\n });\r\n\r\n it(\"returns metadata for queries that produce no rows\", () => {\r\n iModel.clearCaches();\r\n const options = { rowFormat: QueryRowFormat.UseECSqlPropertyNames };\r\n const expected = readMetadata({ ...options }).meta;\r\n for (let i = 0; i < 3; i++) {\r\n iModel.withQueryReader(sql, (reader) => {\r\n expect(reader.step()).to.be.false;\r\n expect(reader.getMetaData()).to.deep.equal(expected);\r\n }, new QueryBinder().bindId(1, \"0xffffff\"), options);\r\n iModel.withQueryReader(sql, (reader) => {\r\n expect(reader.getMetaData()).to.deep.equal(expected);\r\n expect(reader.toArray()).to.deep.equal([]);\r\n }, new QueryBinder().bindId(1, \"0xffffff\"), options);\r\n }\r\n });\r\n\r\n it(\"reflects a schema import between calls\", () => {\r\n const schemaXml = (version: string, extraProperty: string) => `<ECSchema schemaName=\"Test\" alias=\"ts\" version=\"${version}\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\r\n <ECEntityClass typeName=\"Foo\" modifier=\"Sealed\">\r\n <ECProperty propertyName=\"n\" typeName=\"int\"/>\r\n ${extraProperty}\r\n </ECEntityClass>\r\n </ECSchema>`;\r\n using ecdb = ECDbTestHelper.createECDb(KnownTestLocations.outputDir, \"syncReaderMetadataCache.ecdb\", schemaXml(\"01.00.00\", \"\"));\r\n ecdb.withCachedWriteStatement(\"INSERT INTO ts.Foo(n) VALUES(1)\", (stmt) => stmt.stepForInsert());\r\n ecdb.saveChanges();\r\n\r\n const fooSql = \"SELECT * FROM ts.Foo\";\r\n const options = { rowFormat: QueryRowFormat.UseECSqlPropertyNames };\r\n const readNames = () => ecdb.withQueryReader(fooSql, (reader) => {\r\n assert.isTrue(reader.step());\r\n return reader.getMetaData().map((p) => p.name);\r\n }, undefined, options);\r\n expect(readNames()).to.deep.equal([\"ECInstanceId\", \"ECClassId\", \"n\"]);\r\n expect(readNames()).to.deep.equal([\"ECInstanceId\", \"ECClassId\", \"n\"]);\r\n\r\n const schemaPath = path.join(KnownTestLocations.outputDir, \"syncReaderMetadataCache.ecschema.xml\");\r\n IModelJsFs.writeFileSync(schemaPath, schemaXml(\"01.00.01\", `<ECProperty propertyName=\"m\" typeName=\"string\"/>`));\r\n ecdb.importSchema(schemaPath);\r\n ecdb.saveChanges();\r\n\r\n expect(readNames()).to.deep.equal([\"ECInstanceId\", \"ECClassId\", \"n\", \"m\"]);\r\n });\r\n });\r\n});\r\n"]}
|
|
@@ -122,6 +122,29 @@ describe("QueryMetadataCache", () => {
|
|
|
122
122
|
expect(second.meta).to.deep.equal(makeMeta("A", "B"));
|
|
123
123
|
expect(cache.size).to.equal(1);
|
|
124
124
|
});
|
|
125
|
+
it("serves cached metadata synchronously for primary-connection requests", () => {
|
|
126
|
+
const cache = new QueryMetadataCache();
|
|
127
|
+
const requests = [];
|
|
128
|
+
let status = DbResponseStatus.Done;
|
|
129
|
+
const execute = (req) => {
|
|
130
|
+
requests.push(req);
|
|
131
|
+
return makeResponse(req.includeMetaData ? makeMeta("A", "B") : [], status);
|
|
132
|
+
};
|
|
133
|
+
const request = makeRequest({ usePrimaryConn: true });
|
|
134
|
+
status = DbResponseStatus.Error;
|
|
135
|
+
expect(cache.executeCachedPrimaryQueryRequest(request, execute).meta).to.deep.equal(makeMeta("A", "B"));
|
|
136
|
+
expect(cache.size).to.equal(0); // failed responses are not cached
|
|
137
|
+
status = DbResponseStatus.Done;
|
|
138
|
+
const first = cache.executeCachedPrimaryQueryRequest(request, execute);
|
|
139
|
+
const second = cache.executeCachedPrimaryQueryRequest(request, execute);
|
|
140
|
+
expect(requests.map((r) => r.includeMetaData)).to.deep.equal([true, true, false]);
|
|
141
|
+
expect(request.includeMetaData).to.be.true;
|
|
142
|
+
expect(second.meta).to.deep.equal(first.meta);
|
|
143
|
+
expect(second.meta).to.not.equal(first.meta);
|
|
144
|
+
status = DbResponseStatus.Cancel;
|
|
145
|
+
expect(cache.executeCachedPrimaryQueryRequest(request, execute).meta).to.deep.equal([]);
|
|
146
|
+
expect(cache.executeCachedPrimaryQueryRequest({ ...request, includeMetaData: false }, execute).meta).to.deep.equal([]);
|
|
147
|
+
});
|
|
125
148
|
it("keys entries by every option that affects metadata", async () => {
|
|
126
149
|
const cache = new QueryMetadataCache();
|
|
127
150
|
const exec = new FakeExecutor(makeMeta("A"));
|
|
@@ -273,12 +296,25 @@ async function readMetaData(db, ecsql, config) {
|
|
|
273
296
|
async function readColumnNames(db, ecsql, config) {
|
|
274
297
|
return (await readMetaData(db, ecsql, config)).map((p) => p.name);
|
|
275
298
|
}
|
|
299
|
+
/** Spy on both native entry points: worker requests are asynchronous, primary-connection requests complete synchronously. */
|
|
300
|
+
function spyQueryRequests() {
|
|
301
|
+
const worker = sinon.spy(ConcurrentQuery, "executeQueryRequest");
|
|
302
|
+
const primary = sinon.spy(ConcurrentQuery, "executePrimaryQueryRequest");
|
|
303
|
+
return {
|
|
304
|
+
get requests() {
|
|
305
|
+
const calls = [...worker.getCalls(), ...primary.getCalls()];
|
|
306
|
+
return calls.sort((a, b) => a.calledBefore(b) ? -1 : 1).map((call) => call.args[1]);
|
|
307
|
+
},
|
|
308
|
+
resetHistory: () => { worker.resetHistory(); primary.resetHistory(); },
|
|
309
|
+
restore: () => { worker.restore(); primary.restore(); },
|
|
310
|
+
};
|
|
311
|
+
}
|
|
276
312
|
/** Read the metadata of a fresh reader and check whether it had to ask native for it, i.e. whether the cache missed. */
|
|
277
313
|
async function expectMetadataRequested(db, ecsql, requested, config) {
|
|
278
|
-
const spy =
|
|
314
|
+
const spy = spyQueryRequests();
|
|
279
315
|
try {
|
|
280
316
|
await readMetaData(db, ecsql, config);
|
|
281
|
-
expect(spy.
|
|
317
|
+
expect(spy.requests[0].includeMetaData).to.equal(requested);
|
|
282
318
|
}
|
|
283
319
|
finally {
|
|
284
320
|
spy.restore();
|
|
@@ -304,7 +340,7 @@ describe("createQueryReader metadata cache", () => {
|
|
|
304
340
|
const ecdb = __addDisposableResource(env_1, ECDbTestHelper.createECDb(outDir, "query-metadata-cache-hit.ecdb", schemaV1), false);
|
|
305
341
|
ecdb.withCachedWriteStatement("INSERT INTO mct.Foo(PropA) VALUES('a')", (stmt) => stmt.stepForInsert());
|
|
306
342
|
ecdb.saveChanges();
|
|
307
|
-
const spy =
|
|
343
|
+
const spy = spyQueryRequests();
|
|
308
344
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
309
345
|
for (const config of [{}, { usePrimaryConn: true }, { rowFormat: QueryRowFormat.UseJsPropertyNames }, { abbreviateBlobs: true }]) {
|
|
310
346
|
spy.resetHistory();
|
|
@@ -315,7 +351,7 @@ describe("createQueryReader metadata cache", () => {
|
|
|
315
351
|
const secondReader = ecdb.createQueryReader(ecsql, undefined, config);
|
|
316
352
|
const secondRows = await secondReader.toArray();
|
|
317
353
|
const secondMeta = await secondReader.getMetaData();
|
|
318
|
-
expect(spy.
|
|
354
|
+
expect(spy.requests.map((request) => request.includeMetaData)).to.deep.equal([true, false]);
|
|
319
355
|
expect(secondMeta).to.deep.equal(firstMeta);
|
|
320
356
|
expect(secondRows).to.deep.equal(firstRows);
|
|
321
357
|
expect(secondMeta.map((p) => p.name)).to.deep.equal(["ECInstanceId", "ECClassId", "PropA"]);
|