@itwin/core-backend 5.15.0-dev.1 → 5.15.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.
Files changed (80) hide show
  1. package/CHANGELOG.md +42 -1
  2. package/lib/cjs/BriefcaseManager.d.ts +2 -2
  3. package/lib/cjs/BriefcaseManager.js.map +1 -1
  4. package/lib/cjs/ChangesetReaderTypes.d.ts +1 -1
  5. package/lib/cjs/ChangesetReaderTypes.js.map +1 -1
  6. package/lib/cjs/ECSqlRowExecutor.d.ts +3 -3
  7. package/lib/cjs/ECSqlRowExecutor.d.ts.map +1 -1
  8. package/lib/cjs/ECSqlRowExecutor.js +2 -2
  9. package/lib/cjs/ECSqlRowExecutor.js.map +1 -1
  10. package/lib/cjs/ECSqlStatement.d.ts +5 -0
  11. package/lib/cjs/ECSqlStatement.d.ts.map +1 -1
  12. package/lib/cjs/ECSqlStatement.js +15 -2
  13. package/lib/cjs/ECSqlStatement.js.map +1 -1
  14. package/lib/cjs/ECSqlSyncReader.d.ts.map +1 -1
  15. package/lib/cjs/ECSqlSyncReader.js +2 -2
  16. package/lib/cjs/ECSqlSyncReader.js.map +1 -1
  17. package/lib/cjs/Element.d.ts +29 -2
  18. package/lib/cjs/Element.d.ts.map +1 -1
  19. package/lib/cjs/Element.js +38 -2
  20. package/lib/cjs/Element.js.map +1 -1
  21. package/lib/cjs/GeographicCRSServices.d.ts +50 -2
  22. package/lib/cjs/GeographicCRSServices.d.ts.map +1 -1
  23. package/lib/cjs/GeographicCRSServices.js +11 -1
  24. package/lib/cjs/GeographicCRSServices.js.map +1 -1
  25. package/lib/cjs/ViewStore.d.ts.map +1 -1
  26. package/lib/cjs/ViewStore.js +62 -19
  27. package/lib/cjs/ViewStore.js.map +1 -1
  28. package/lib/esm/BriefcaseManager.d.ts +2 -2
  29. package/lib/esm/BriefcaseManager.js.map +1 -1
  30. package/lib/esm/ChangesetReaderTypes.d.ts +1 -1
  31. package/lib/esm/ChangesetReaderTypes.js.map +1 -1
  32. package/lib/esm/ECSqlRowExecutor.d.ts +3 -3
  33. package/lib/esm/ECSqlRowExecutor.d.ts.map +1 -1
  34. package/lib/esm/ECSqlRowExecutor.js +2 -2
  35. package/lib/esm/ECSqlRowExecutor.js.map +1 -1
  36. package/lib/esm/ECSqlStatement.d.ts +5 -0
  37. package/lib/esm/ECSqlStatement.d.ts.map +1 -1
  38. package/lib/esm/ECSqlStatement.js +15 -2
  39. package/lib/esm/ECSqlStatement.js.map +1 -1
  40. package/lib/esm/ECSqlSyncReader.d.ts.map +1 -1
  41. package/lib/esm/ECSqlSyncReader.js +3 -3
  42. package/lib/esm/ECSqlSyncReader.js.map +1 -1
  43. package/lib/esm/Element.d.ts +29 -2
  44. package/lib/esm/Element.d.ts.map +1 -1
  45. package/lib/esm/Element.js +41 -5
  46. package/lib/esm/Element.js.map +1 -1
  47. package/lib/esm/GeographicCRSServices.d.ts +50 -2
  48. package/lib/esm/GeographicCRSServices.d.ts.map +1 -1
  49. package/lib/esm/GeographicCRSServices.js +10 -1
  50. package/lib/esm/GeographicCRSServices.js.map +1 -1
  51. package/lib/esm/ViewStore.d.ts.map +1 -1
  52. package/lib/esm/ViewStore.js +62 -19
  53. package/lib/esm/ViewStore.js.map +1 -1
  54. package/lib/esm/test/ecdb/ECSqlQuery.test.js +17 -11
  55. package/lib/esm/test/ecdb/ECSqlQuery.test.js.map +1 -1
  56. package/lib/esm/test/ecdb/ECSqlSyncReader.test.js +140 -0
  57. package/lib/esm/test/ecdb/ECSqlSyncReader.test.js.map +1 -1
  58. package/lib/esm/test/element/ElementSubModelInsert.test.d.ts +2 -0
  59. package/lib/esm/test/element/ElementSubModelInsert.test.d.ts.map +1 -0
  60. package/lib/esm/test/element/ElementSubModelInsert.test.js +183 -0
  61. package/lib/esm/test/element/ElementSubModelInsert.test.js.map +1 -0
  62. package/lib/esm/test/hubaccess/CodeSwap.test.js +78 -0
  63. package/lib/esm/test/hubaccess/CodeSwap.test.js.map +1 -1
  64. package/lib/esm/test/hubaccess/SchemaImportOrphanColumns.test.d.ts +2 -0
  65. package/lib/esm/test/hubaccess/SchemaImportOrphanColumns.test.d.ts.map +1 -0
  66. package/lib/esm/test/hubaccess/SchemaImportOrphanColumns.test.js +142 -0
  67. package/lib/esm/test/hubaccess/SchemaImportOrphanColumns.test.js.map +1 -0
  68. package/lib/esm/test/imodel/IModelGeolocation.test.js +5 -5
  69. package/lib/esm/test/imodel/IModelGeolocation.test.js.map +1 -1
  70. package/lib/esm/test/standalone/ChangesetReader.test.js +5 -5
  71. package/lib/esm/test/standalone/ChangesetReader.test.js.map +1 -1
  72. package/lib/esm/test/standalone/SQliteChangesetReaderAndChangesetECAdaptor.test.js +2 -2
  73. package/lib/esm/test/standalone/SQliteChangesetReaderAndChangesetECAdaptor.test.js.map +1 -1
  74. package/lib/esm/test/standalone/SessionApplyIndirect.test.d.ts +2 -0
  75. package/lib/esm/test/standalone/SessionApplyIndirect.test.d.ts.map +1 -0
  76. package/lib/esm/test/standalone/SessionApplyIndirect.test.js +211 -0
  77. package/lib/esm/test/standalone/SessionApplyIndirect.test.js.map +1 -0
  78. package/lib/esm/test/standalone/ViewStoreDb.test.js +53 -0
  79. package/lib/esm/test/standalone/ViewStoreDb.test.js.map +1 -1
  80. package/package.json +15 -15
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=SessionApplyIndirect.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionApplyIndirect.test.d.ts","sourceRoot":"","sources":["../../../../src/test/standalone/SessionApplyIndirect.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,211 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
6
+ if (value !== null && value !== void 0) {
7
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
8
+ var dispose, inner;
9
+ if (async) {
10
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
11
+ dispose = value[Symbol.asyncDispose];
12
+ }
13
+ if (dispose === void 0) {
14
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
15
+ dispose = value[Symbol.dispose];
16
+ if (async) inner = dispose;
17
+ }
18
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
19
+ if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
20
+ env.stack.push({ value: value, dispose: dispose, async: async });
21
+ }
22
+ else if (async) {
23
+ env.stack.push({ async: true });
24
+ }
25
+ return value;
26
+ };
27
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
28
+ return function (env) {
29
+ function fail(e) {
30
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
31
+ env.hasError = true;
32
+ }
33
+ var r, s = 0;
34
+ function next() {
35
+ while (r = env.stack.pop()) {
36
+ try {
37
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
38
+ if (r.dispose) {
39
+ var result = r.dispose.call(r.value);
40
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
41
+ }
42
+ else s |= 1;
43
+ }
44
+ catch (e) {
45
+ fail(e);
46
+ }
47
+ }
48
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
49
+ if (env.hasError) throw env.error;
50
+ }
51
+ return next();
52
+ };
53
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
54
+ var e = new Error(message);
55
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
56
+ });
57
+ //=================================================================================================
58
+ // Tests for the "indirect flag is preserved while applying a changeset" behavior.
59
+ //
60
+ // Background (iTwin/itwinjs-backlog#2474, scenario iTwin/itwinjs-backlog#2346, SQLite check-in
61
+ // https://sqlite.org/src/info/9d36067e76):
62
+ //
63
+ // Every row change recorded by a SQLite session is flagged as either "direct" (made explicitly
64
+ // by the user) or "indirect" (a side effect - e.g. produced by a trigger/foreign-key action, or
65
+ // produced by applying a changeset entry that was itself flagged indirect). iTwin surfaces this
66
+ // flag through `SqliteChangesetReader.isIndirect` (and `ChangeInstance.$meta.isIndirectChange`).
67
+ //
68
+ // Before the SQLite fix, when a changeset was applied to a briefcase that had an active change
69
+ // session (as happens during a `pullChanges` that must rebase local, un-pushed txns), EVERY
70
+ // applied row change was re-recorded as DIRECT, regardless of how it was flagged in the incoming
71
+ // changeset. In OpenSite+ this caused a whole site to be flagged as "directly modified" when only
72
+ // a pond (whose trigger indirectly touched the site row) had actually been edited, which broke
73
+ // the Blame feature.
74
+ //
75
+ // The fix makes `sqlite3changeset_apply()` temporarily set the session "indirect" flag while
76
+ // stepping a row change that was flagged indirect in the incoming changeset. As a result the
77
+ // per-change direct/indirect classification is preserved end-to-end: a direct source change is
78
+ // re-recorded direct, an indirect source change is re-recorded indirect.
79
+ //
80
+ // What these tests assert:
81
+ // When briefcase B2 has a local, un-pushed change and pulls a changeset from B1 that contains an
82
+ // INDIRECT change (a `bis_Model` LastMod/GeometryGuid update produced by a trigger when B1
83
+ // inserted an element), the incoming indirect change is applied under B2's active session during
84
+ // rebase. After the fix, that re-recorded change is still INDIRECT in B2; before the fix it would
85
+ // have been DIRECT.
86
+ //
87
+ // NOTE: This test exercises behavior that lives in the native addon (@bentley/imodeljs-native).
88
+ // It can only pass once an addon built from iTwin/imodel-native#1621 (SQLite tag
89
+ // itwin-sqlite-v3.53.4-r3) is published and consumed by itwinjs-core. Until then it is expected
90
+ // to fail locally, which is why it is parked on a branch rather than opened as a PR.
91
+ //=================================================================================================
92
+ import { assert } from "chai";
93
+ import { IModel, SubCategoryAppearance } from "@itwin/core-common";
94
+ import { EditTxn } from "../../EditTxn";
95
+ import { ChannelControl, SpatialCategory, SqliteChangesetReader, } from "../../core-backend";
96
+ import { HubMock } from "../../internal/HubMock";
97
+ import { HubWrappers, KnownTestLocations } from "..";
98
+ import { IModelTestUtils, TestUserType } from "../IModelTestUtils";
99
+ import { TestUtils } from "../TestUtils";
100
+ function startTestTxn(briefcase) {
101
+ const txn = new EditTxn(briefcase, "session apply indirect");
102
+ txn.start();
103
+ return txn;
104
+ }
105
+ describe("Session apply preserves indirect flag (iTwin/itwinjs-backlog#2346)", () => {
106
+ const ctx = {
107
+ accessTokens: { user1: "", user2: "" },
108
+ iModelId: "",
109
+ iTwinId: "",
110
+ modelId: "",
111
+ spatialCategoryId: "",
112
+ iModelName: "SessionApplyIndirect",
113
+ rootSubject: "SessionApplyIndirect",
114
+ openBriefcase: async (user, noLock) => {
115
+ const b = await HubWrappers.downloadAndOpenBriefcase({ accessToken: ctx.accessTokens[user], iTwinId: ctx.iTwinId, iModelId: ctx.iModelId, noLock });
116
+ b.channels.addAllowedChannel(ChannelControl.sharedChannelName);
117
+ return b;
118
+ },
119
+ openB1: async (noLock) => ctx.openBriefcase("user1", noLock),
120
+ openB2: async (noLock) => ctx.openBriefcase("user2", noLock),
121
+ };
122
+ async function insertPhysicalObject(txn) {
123
+ const briefcase = txn.iModel;
124
+ await briefcase.locks.acquireLocks({ shared: ctx.modelId });
125
+ return txn.insertElement(IModelTestUtils.createPhysicalObject(briefcase, ctx.modelId, ctx.spatialCategoryId).toJSON());
126
+ }
127
+ before(async () => {
128
+ await TestUtils.startBackend();
129
+ HubMock.startup("SessionApplyIndirect", KnownTestLocations.outputDir);
130
+ });
131
+ after(async () => {
132
+ HubMock.shutdown();
133
+ });
134
+ beforeEach(async () => {
135
+ ctx.iTwinId = HubMock.iTwinId;
136
+ ctx.accessTokens.user1 = await HubWrappers.getAccessToken(TestUserType.SuperManager);
137
+ ctx.accessTokens.user2 = await HubWrappers.getAccessToken(TestUserType.Regular);
138
+ ctx.iModelId = await HubMock.createNewIModel({ accessToken: ctx.accessTokens.user1, iTwinId: ctx.iTwinId, iModelName: ctx.iModelName, description: ctx.rootSubject });
139
+ assert.isNotEmpty(ctx.iModelId);
140
+ // Seed the iModel with a physical model + spatial category that both briefcases share.
141
+ const b1 = await ctx.openB1();
142
+ const seedTxn = startTestTxn(b1);
143
+ await b1.locks.acquireLocks({ shared: IModel.dictionaryId });
144
+ [, ctx.modelId] = IModelTestUtils.createAndInsertPhysicalPartitionAndModel(seedTxn, IModelTestUtils.getUniqueModelCode(b1, "indirectModel"), true);
145
+ const dictionary = b1.models.getModel(IModel.dictionaryId);
146
+ const categoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, "IndirectCategory");
147
+ ctx.spatialCategoryId = SpatialCategory.insert(seedTxn, dictionary.id, categoryCode.value, new SubCategoryAppearance({ color: 0xff0000 }));
148
+ seedTxn.saveChanges();
149
+ await b1.pushChanges({ description: "seed model + category" });
150
+ b1.close();
151
+ });
152
+ it("re-recorded indirect bis_Model update stays indirect after a rebasing pull", async () => {
153
+ // B1 inserts an element. Inserting an element DIRECTLY writes the bis_Element row, and
154
+ // INDIRECTLY updates the owning bis_Model row (LastMod / GeometryGuid) via a trigger. The
155
+ // pushed changeset therefore contains at least one indirect bis_Model update.
156
+ const b1 = await ctx.openB1();
157
+ const b1Txn = startTestTxn(b1);
158
+ await insertPhysicalObject(b1Txn);
159
+ b1Txn.saveChanges("B1 inserts element (indirectly updates model)");
160
+ await b1.pushChanges({ description: "B1 element insert" });
161
+ // B2 makes its own local change into the SAME model but does NOT push it. This leaves B2 with
162
+ // an active change session and un-pushed local txns, so the subsequent pull must REBASE: B1's
163
+ // changeset is applied into B2 while B2's session is recording. This is exactly the path that
164
+ // re-records applied changes and, before the fix, dropped their indirect flag.
165
+ const b2 = await ctx.openB2();
166
+ const b2Txn = startTestTxn(b2);
167
+ await insertPhysicalObject(b2Txn);
168
+ b2Txn.saveChanges("B2 local element insert (un-pushed)");
169
+ // Pulling B1's changeset forces the rebase/apply of B1's indirect bis_Model update under B2's
170
+ // active session. noFastForward guarantees a rebase actually happens rather than a trivial
171
+ // fast-forward (which would not re-record anything).
172
+ await b2.pullChanges();
173
+ // Walk every local txn recorded in B2 (the result of applying B1's changeset and rebasing B2's
174
+ // own txn on top of it) and inspect each bis_Model update. The #2346 invariant: a bis_Model
175
+ // update must NEVER be recorded as a direct change - model LastMod/GeometryGuid changes are
176
+ // always a trigger side effect, so they must stay indirect through the apply/rebase.
177
+ let sawModelUpdate = false;
178
+ let sawDirectModelUpdate = false;
179
+ for (let txnId = b2.txns.queryFirstTxnId(); b2.txns.isTxnIdValid(txnId); txnId = b2.txns.queryNextTxnId(txnId)) {
180
+ const env_1 = { stack: [], error: void 0, hasError: false };
181
+ try {
182
+ const reader = __addDisposableResource(env_1, SqliteChangesetReader.openTxn({ db: b2, txnId }), false);
183
+ while (reader.step()) {
184
+ if (reader.tableName === "bis_Model" && reader.op === "Updated") {
185
+ sawModelUpdate = true;
186
+ if (!reader.isIndirect)
187
+ sawDirectModelUpdate = true;
188
+ }
189
+ }
190
+ reader.close();
191
+ }
192
+ catch (e_1) {
193
+ env_1.error = e_1;
194
+ env_1.hasError = true;
195
+ }
196
+ finally {
197
+ __disposeResources(env_1);
198
+ }
199
+ }
200
+ // We must have observed at least one bis_Model update (otherwise the test setup is wrong and
201
+ // the assertion below would be vacuously true).
202
+ assert.isTrue(sawModelUpdate, "expected at least one bis_Model update among B2's local changes");
203
+ // The core assertion: after applying B1's changeset under B2's active session, no bis_Model
204
+ // update was re-recorded as a DIRECT change. Before the SQLite fix this would be false because
205
+ // every applied change was recorded direct.
206
+ assert.isFalse(sawDirectModelUpdate, "a bis_Model update was re-recorded as direct; the indirect flag was lost while applying the changeset (iTwin/itwinjs-backlog#2346)");
207
+ b1.close();
208
+ b2.close();
209
+ });
210
+ });
211
+ //# sourceMappingURL=SessionApplyIndirect.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionApplyIndirect.test.js","sourceRoot":"","sources":["../../../../src/test/standalone/SessionApplyIndirect.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\n//=================================================================================================\r\n// Tests for the \"indirect flag is preserved while applying a changeset\" behavior.\r\n//\r\n// Background (iTwin/itwinjs-backlog#2474, scenario iTwin/itwinjs-backlog#2346, SQLite check-in\r\n// https://sqlite.org/src/info/9d36067e76):\r\n//\r\n// Every row change recorded by a SQLite session is flagged as either \"direct\" (made explicitly\r\n// by the user) or \"indirect\" (a side effect - e.g. produced by a trigger/foreign-key action, or\r\n// produced by applying a changeset entry that was itself flagged indirect). iTwin surfaces this\r\n// flag through `SqliteChangesetReader.isIndirect` (and `ChangeInstance.$meta.isIndirectChange`).\r\n//\r\n// Before the SQLite fix, when a changeset was applied to a briefcase that had an active change\r\n// session (as happens during a `pullChanges` that must rebase local, un-pushed txns), EVERY\r\n// applied row change was re-recorded as DIRECT, regardless of how it was flagged in the incoming\r\n// changeset. In OpenSite+ this caused a whole site to be flagged as \"directly modified\" when only\r\n// a pond (whose trigger indirectly touched the site row) had actually been edited, which broke\r\n// the Blame feature.\r\n//\r\n// The fix makes `sqlite3changeset_apply()` temporarily set the session \"indirect\" flag while\r\n// stepping a row change that was flagged indirect in the incoming changeset. As a result the\r\n// per-change direct/indirect classification is preserved end-to-end: a direct source change is\r\n// re-recorded direct, an indirect source change is re-recorded indirect.\r\n//\r\n// What these tests assert:\r\n// When briefcase B2 has a local, un-pushed change and pulls a changeset from B1 that contains an\r\n// INDIRECT change (a `bis_Model` LastMod/GeometryGuid update produced by a trigger when B1\r\n// inserted an element), the incoming indirect change is applied under B2's active session during\r\n// rebase. After the fix, that re-recorded change is still INDIRECT in B2; before the fix it would\r\n// have been DIRECT.\r\n//\r\n// NOTE: This test exercises behavior that lives in the native addon (@bentley/imodeljs-native).\r\n// It can only pass once an addon built from iTwin/imodel-native#1621 (SQLite tag\r\n// itwin-sqlite-v3.53.4-r3) is published and consumed by itwinjs-core. Until then it is expected\r\n// to fail locally, which is why it is parked on a branch rather than opened as a PR.\r\n//=================================================================================================\r\n\r\nimport { assert } from \"chai\";\r\nimport { IModel, SubCategoryAppearance } from \"@itwin/core-common\";\r\nimport { EditTxn } from \"../../EditTxn\";\r\nimport {\r\n BriefcaseDb,\r\n ChannelControl,\r\n DictionaryModel,\r\n SpatialCategory,\r\n SqliteChangesetReader,\r\n} from \"../../core-backend\";\r\nimport { HubMock } from \"../../internal/HubMock\";\r\nimport { HubWrappers, KnownTestLocations } from \"..\";\r\nimport { IModelTestUtils, TestUserType } from \"../IModelTestUtils\";\r\nimport { TestUtils } from \"../TestUtils\";\r\n\r\nfunction startTestTxn(briefcase: BriefcaseDb): EditTxn {\r\n const txn = new EditTxn(briefcase, \"session apply indirect\");\r\n txn.start();\r\n return txn;\r\n}\r\n\r\ndescribe(\"Session apply preserves indirect flag (iTwin/itwinjs-backlog#2346)\", () => {\r\n const ctx = {\r\n accessTokens: { user1: \"\", user2: \"\" },\r\n iModelId: \"\",\r\n iTwinId: \"\",\r\n modelId: \"\",\r\n spatialCategoryId: \"\",\r\n iModelName: \"SessionApplyIndirect\",\r\n rootSubject: \"SessionApplyIndirect\",\r\n openBriefcase: async (user: \"user1\" | \"user2\", noLock?: true) => {\r\n const b = await HubWrappers.downloadAndOpenBriefcase({ accessToken: ctx.accessTokens[user], iTwinId: ctx.iTwinId, iModelId: ctx.iModelId, noLock });\r\n b.channels.addAllowedChannel(ChannelControl.sharedChannelName);\r\n return b;\r\n },\r\n openB1: async (noLock?: true) => ctx.openBriefcase(\"user1\", noLock),\r\n openB2: async (noLock?: true) => ctx.openBriefcase(\"user2\", noLock),\r\n };\r\n\r\n async function insertPhysicalObject(txn: EditTxn): Promise<string> {\r\n const briefcase = txn.iModel as BriefcaseDb;\r\n await briefcase.locks.acquireLocks({ shared: ctx.modelId });\r\n return txn.insertElement(IModelTestUtils.createPhysicalObject(briefcase, ctx.modelId, ctx.spatialCategoryId).toJSON());\r\n }\r\n\r\n before(async () => {\r\n await TestUtils.startBackend();\r\n HubMock.startup(\"SessionApplyIndirect\", KnownTestLocations.outputDir);\r\n });\r\n\r\n after(async () => {\r\n HubMock.shutdown();\r\n });\r\n\r\n beforeEach(async () => {\r\n ctx.iTwinId = HubMock.iTwinId;\r\n ctx.accessTokens.user1 = await HubWrappers.getAccessToken(TestUserType.SuperManager);\r\n ctx.accessTokens.user2 = await HubWrappers.getAccessToken(TestUserType.Regular);\r\n ctx.iModelId = await HubMock.createNewIModel({ accessToken: ctx.accessTokens.user1, iTwinId: ctx.iTwinId, iModelName: ctx.iModelName, description: ctx.rootSubject });\r\n assert.isNotEmpty(ctx.iModelId);\r\n\r\n // Seed the iModel with a physical model + spatial category that both briefcases share.\r\n const b1 = await ctx.openB1();\r\n const seedTxn = startTestTxn(b1);\r\n await b1.locks.acquireLocks({ shared: IModel.dictionaryId });\r\n [, ctx.modelId] = IModelTestUtils.createAndInsertPhysicalPartitionAndModel(\r\n seedTxn,\r\n IModelTestUtils.getUniqueModelCode(b1, \"indirectModel\"),\r\n true);\r\n const dictionary: DictionaryModel = b1.models.getModel<DictionaryModel>(IModel.dictionaryId);\r\n const categoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, \"IndirectCategory\");\r\n ctx.spatialCategoryId = SpatialCategory.insert(\r\n seedTxn,\r\n dictionary.id,\r\n categoryCode.value,\r\n new SubCategoryAppearance({ color: 0xff0000 }),\r\n );\r\n seedTxn.saveChanges();\r\n await b1.pushChanges({ description: \"seed model + category\" });\r\n b1.close();\r\n });\r\n\r\n it(\"re-recorded indirect bis_Model update stays indirect after a rebasing pull\", async () => {\r\n // B1 inserts an element. Inserting an element DIRECTLY writes the bis_Element row, and\r\n // INDIRECTLY updates the owning bis_Model row (LastMod / GeometryGuid) via a trigger. The\r\n // pushed changeset therefore contains at least one indirect bis_Model update.\r\n const b1 = await ctx.openB1();\r\n const b1Txn = startTestTxn(b1);\r\n await insertPhysicalObject(b1Txn);\r\n b1Txn.saveChanges(\"B1 inserts element (indirectly updates model)\");\r\n await b1.pushChanges({ description: \"B1 element insert\" });\r\n\r\n // B2 makes its own local change into the SAME model but does NOT push it. This leaves B2 with\r\n // an active change session and un-pushed local txns, so the subsequent pull must REBASE: B1's\r\n // changeset is applied into B2 while B2's session is recording. This is exactly the path that\r\n // re-records applied changes and, before the fix, dropped their indirect flag.\r\n const b2 = await ctx.openB2();\r\n const b2Txn = startTestTxn(b2);\r\n await insertPhysicalObject(b2Txn);\r\n b2Txn.saveChanges(\"B2 local element insert (un-pushed)\");\r\n\r\n // Pulling B1's changeset forces the rebase/apply of B1's indirect bis_Model update under B2's\r\n // active session. noFastForward guarantees a rebase actually happens rather than a trivial\r\n // fast-forward (which would not re-record anything).\r\n await b2.pullChanges();\r\n\r\n // Walk every local txn recorded in B2 (the result of applying B1's changeset and rebasing B2's\r\n // own txn on top of it) and inspect each bis_Model update. The #2346 invariant: a bis_Model\r\n // update must NEVER be recorded as a direct change - model LastMod/GeometryGuid changes are\r\n // always a trigger side effect, so they must stay indirect through the apply/rebase.\r\n let sawModelUpdate = false;\r\n let sawDirectModelUpdate = false;\r\n for (let txnId = b2.txns.queryFirstTxnId(); b2.txns.isTxnIdValid(txnId); txnId = b2.txns.queryNextTxnId(txnId)) {\r\n using reader = SqliteChangesetReader.openTxn({ db: b2, txnId });\r\n while (reader.step()) {\r\n if (reader.tableName === \"bis_Model\" && reader.op === \"Updated\") {\r\n sawModelUpdate = true;\r\n if (!reader.isIndirect)\r\n sawDirectModelUpdate = true;\r\n }\r\n }\r\n reader.close();\r\n }\r\n\r\n // We must have observed at least one bis_Model update (otherwise the test setup is wrong and\r\n // the assertion below would be vacuously true).\r\n assert.isTrue(sawModelUpdate, \"expected at least one bis_Model update among B2's local changes\");\r\n\r\n // The core assertion: after applying B1's changeset under B2's active session, no bis_Model\r\n // update was re-recorded as a DIRECT change. Before the SQLite fix this would be false because\r\n // every applied change was recorded direct.\r\n assert.isFalse(sawDirectModelUpdate, \"a bis_Model update was re-recorded as direct; the indirect flag was lost while applying the changeset (iTwin/itwinjs-backlog#2346)\");\r\n\r\n b1.close();\r\n b2.close();\r\n });\r\n});\r\n"]}
@@ -6,6 +6,7 @@ import { expect } from "chai";
6
6
  import { join } from "path";
7
7
  import { Guid, Logger, LogLevel, OpenMode } from "@itwin/core-bentley";
8
8
  import { ViewStore } from "../../ViewStore";
9
+ import { ViewStoreError } from "@itwin/core-common";
9
10
  import { KnownTestLocations } from "../KnownTestLocations";
10
11
  import { SnapshotDb } from "../../IModelDb";
11
12
  import { IModelTestUtils } from "../IModelTestUtils";
@@ -236,6 +237,58 @@ describe("ViewStore", function () {
236
237
  expect(vs1.queryViewsSync({ owner: "owner10", classNames: ["BisCore:SpatialViewDefinition", "BisCore:OrthographicViewDefinition"] }).length).equal(2);
237
238
  expect(vs1.queryViewsSync({ owner: "owner10", classNames: ["BisCore:DrawingViewDefinition"] }).length).equal(1);
238
239
  expect(vs1.queryViewsSync({ owner: "owner10", classNames: ["BisCore:DrawingViewDefinition", "BisCore:SheetViewDefinition"] }).length).equal(2);
240
+ // query parameters may come from RPC callers, so values must never be interpreted as SQL
241
+ const allPublicCount = vs1.queryViewsSync({}).length;
242
+ const injectClause = "x') OR 1=1 OR className IN('x";
243
+ expect(vs1.queryViewsSync({ classNames: [injectClause] }).length).equal(0);
244
+ expect(vs1.queryViewsSync({ classNames: ["foo') UNION SELECT Id,name,owner,private,1 FROM views -- "] }).length).equal(0);
245
+ expect(vs1.queryViewsSync({ tags: [injectClause] }).length).equal(0);
246
+ expect(vs1.queryViewsSync({ classNames: ["it's"] }).length).equal(0); // quotes in values must not cause SQL errors
247
+ expect(vs1.queryViewsSync({ tags: ["it's"] }).length).equal(0);
248
+ expect(vs1.queryViewsSync({ nameSearch: "' OR 1=1 --" }).length).equal(0);
249
+ expect(vs1.queryViewsSync({ group: "group2", offset: 95 }).length).equal(5); // offset without limit
250
+ const badParams = [
251
+ { nameSearch: "x", nameCompare: "= @name OR 1=1 OR name =" },
252
+ { nameSearch: "x", nameCompare: "like" },
253
+ { limit: "1 UNION SELECT Id FROM views" },
254
+ { limit: 1.5 },
255
+ { limit: -1 },
256
+ { limit: 10, offset: "1; --" },
257
+ { classNames: "BisCore:SpatialViewDefinition" },
258
+ { classNames: [1] },
259
+ { tags: [{}] },
260
+ { owner: 1 },
261
+ { nameSearch: { $ne: "" } },
262
+ { group: 5 },
263
+ { group: ["group2"] },
264
+ null,
265
+ undefined,
266
+ ];
267
+ for (const params of badParams) {
268
+ // must be rejected by validation with a ViewStoreError, not fail later with a generic or native error
269
+ expect(() => vs1.queryViewsSync(params), String(JSON.stringify(params))).throws().that.satisfies((e) => ViewStoreError.isError(e, "invalid-value"));
270
+ }
271
+ expect(vs1.queryViewsSync({ owner: "", nameSearch: "", group: "" }).length).equal(allPublicCount); // empty strings are treated as absent
272
+ // owner is optional: without it only public views are returned; with it, that owner's private views are added
273
+ expect(vs1.queryViewsSync({ group: "/" }).every((view) => !view.isPrivate)).to.be.true;
274
+ expect(vs1.queryViewsSync({ group: "/", owner: "someoneElse" }).every((view) => !view.isPrivate)).to.be.true;
275
+ expect(vs1.queryViewsSync({ group: "/", owner: "owner10" }).filter((view) => view.isPrivate).length).equal(4);
276
+ expect(vs1.queryViewsSync({ nameSearch: "my private 2" }).length).equal(0);
277
+ expect(vs1.queryViewsSync({ nameSearch: "my private 2", owner: "someoneElse" }).length).equal(0);
278
+ expect(vs1.queryViewsSync({ nameSearch: "my private 2", owner: "owner10" }).length).equal(1);
279
+ // a limit of 0 means no limit
280
+ expect(vs1.queryViewsSync({ group: "group2", limit: 0 }).length).equal(100);
281
+ expect(vs1.queryViewsSync({ group: "group2", limit: 0, offset: 0 }).length).equal(100);
282
+ // the query statement is cached, so bindings from one call must not leak into the next
283
+ expect(vs1.queryViewsSync({ owner: "owner10" }).length).equal(7);
284
+ expect(vs1.queryViewsSync({}).length).equal(allPublicCount);
285
+ expect(vs1.queryViewsSync({ owner: "owner10", classNames: ["BisCore:SpatialViewDefinition"], nameSearch: "my%", nameCompare: "LIKE", limit: 1 }).length).equal(1);
286
+ expect(vs1.queryViewsSync({ nameSearch: "another view" }).length).equal(1);
287
+ expect(vs1.queryViewsSync({}).length).equal(allPublicCount);
288
+ // arrays are bound as a single JSON value, so their size is not limited by SQLite's bound-variable limit
289
+ const manyClassNames = Array.from({ length: 40000 }, (_, i) => `Fake:Class${i}`);
290
+ expect(vs1.queryViewsSync({ owner: "owner10", classNames: [...manyClassNames, "BisCore:DrawingViewDefinition"] }).length).equal(1);
291
+ expect(vs1.queryViewsSync({}).length).equal(allPublicCount);
239
292
  await vs1.renameTag({ oldName: "tag2", newName: "tag2-renamed" });
240
293
  views = vs1.queryViewsSync({ tags: ["tag2-renamed"] });
241
294
  expect(views.length).equal(3);
@@ -1 +1 @@
1
- {"version":3,"file":"ViewStoreDb.test.js","sourceRoot":"","sources":["../../../../src/test/standalone/ViewStoreDb.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 { expect } from \"chai\";\r\nimport { Suite } from \"mocha\";\r\nimport { join } from \"path\";\r\nimport { Guid, GuidString, Logger, LogLevel, OpenMode } from \"@itwin/core-bentley\";\r\nimport { ViewStore } from \"../../ViewStore\";\r\nimport { ThumbnailFormatProps } from \"@itwin/core-common\";\r\nimport { KnownTestLocations } from \"../KnownTestLocations\";\r\nimport { SnapshotDb } from \"../../IModelDb\";\r\nimport { IModelTestUtils } from \"../IModelTestUtils\";\r\nimport { IModelJsFs } from \"../../IModelJsFs\";\r\n\r\ndescribe(\"ViewStore\", function (this: Suite) {\r\n this.timeout(0);\r\n\r\n let vs1: ViewStore.ViewDb;\r\n\r\n before(async () => {\r\n Logger.setLevel(\"SQLite\", LogLevel.None); // we're expecting errors\r\n const dbName = join(KnownTestLocations.outputDir, \"viewStore.db\");\r\n ViewStore.ViewDb.createNewDb(dbName);\r\n vs1 = new ViewStore.ViewDb({ guidMap: {} as any });\r\n vs1.openDb(dbName, OpenMode.ReadWrite);\r\n });\r\n\r\n after(async () => {\r\n vs1.closeDb(true);\r\n Logger.setLevel(\"SQLite\", LogLevel.Error);\r\n });\r\n\r\n it(\"ViewDb\", async () => {\r\n const c1 = vs1.addCategorySelectorRow({ name: \"first cat\", json: \"cat1-json\" });\r\n const ds1 = vs1.addDisplayStyleRow({ name: \"first style\", json: \"style1-json\" });\r\n\r\n expect(vs1.getViewByNameSync({ name: \"view1\" })).to.be.undefined;\r\n const v1Id = vs1.addViewRow({ className: \"spatial\", name: \"view1\", json: \"json1\", owner: \"owner10\", isPrivate: true, groupId: 1, categorySel: c1, displayStyle: ds1 });\r\n expect(v1Id).equals(1);\r\n\r\n const v1 = vs1.getViewByNameSync({ name: \"view1\" })!;\r\n expect(vs1.findViewIdByName({ name: \"view1\" })).equals(v1Id);\r\n expect(vs1.findViewIdByName({ name: \"/view1\" })).equals(v1Id);\r\n expect(v1.owner).equals(\"owner10\");\r\n expect(v1.className).equals(\"spatial\");\r\n expect(v1.groupId).equals(\"@1\");\r\n expect(v1.isPrivate).to.be.true;\r\n expect(v1.name).equals(\"view1\");\r\n await vs1.updateViewShared({ viewId: v1Id, isShared: true, owner: \"owner10\" });\r\n const v1Updated = vs1.getViewByNameSync({ name: \"view1\" })!;\r\n expect(v1Updated.isPrivate).to.be.false;\r\n\r\n const v1Id2 = vs1.addViewRow({ className: \"spatial\", name: \"v2\", json: \"json-v2\", owner: \"owner1\", groupId: 1, categorySel: c1, displayStyle: ds1 });\r\n expect(v1Id2).equals(2);\r\n const v2 = vs1.getViewRow(v1Id2)!;\r\n expect(v2.name).equals(\"v2\");\r\n vs1.deleteViewRow(v1Id2);\r\n expect(vs1.findViewIdByName({ name: \"v2\", groupId: 1 })).equals(0);\r\n\r\n expect(() => vs1.addViewGroupRow({ name: \"\", json: \"\" })).to.throw(\"illegal group\");\r\n expect(() => vs1.addViewGroupRow({ name: \" \", json: \"\" })).to.throw(\"illegal group\");\r\n expect(() => vs1.addViewGroupRow({ name: \"@bad\", json: \"\" })).to.throw(\"illegal group\");\r\n expect(() => vs1.addViewGroupRow({ name: \"bad/name\", json: \"\" })).to.throw(\"illegal group\");\r\n expect(() => vs1.addViewGroupRow({ name: \"^fd\", json: \"\" })).to.throw(\"illegal group\");\r\n expect(() => vs1.addViewGroupRow({ name: \"sd#fd\", json: \"\" })).to.throw(\"illegal group\");\r\n expect(() => vs1.addViewRow({ className: \"spatial\", name: \"@bad\", json: \"json-v2\", owner: \"owner1\", groupId: 1, categorySel: c1, displayStyle: ds1 })).to.throw(\"illegal view\");\r\n expect(() => vs1.addViewRow({ className: \"spatial\", name: \"bad/name\", json: \"json-v2\", owner: \"owner1\", groupId: 1, categorySel: c1, displayStyle: ds1 })).to.throw(\"illegal view\");\r\n\r\n const g1 = vs1.addViewGroupRow({ name: \"group1\", json: \"group1-json\" });\r\n const g2 = vs1.addViewGroupRow({ name: \"group2\", json: \"group2-json\" });\r\n const g3 = vs1.addViewGroupRow({ name: \"group 3\", parentId: g2, json: \"group3-json\" });\r\n const g4 = vs1.addViewGroupRow({ name: \"group4\", parentId: g3, json: \"group3-json\" });\r\n const v2Id = vs1.addViewRow({ className: \"spatial2\", name: \"view2\", json: \"json2\", groupId: g4, categorySel: c1, displayStyle: ds1 });\r\n expect(v2Id).equals(3);\r\n\r\n for (let i = 0; i < 100; i++)\r\n vs1.addViewRow({ className: \"spatial\", name: `test view ${i}`, json: `json${i}`, owner: \"owner1\", groupId: g2, categorySel: c1, displayStyle: ds1 });\r\n\r\n // duplicate name in a group should throw\r\n expect(() => vs1.addViewRow({ className: \"spatial3\", name: \"test view 0\", json: \"json-blah\", owner: \"owner1\", groupId: g2, categorySel: c1, displayStyle: ds1 })).to.throw(\"UNIQUE\");\r\n // allow the same name in different groups\r\n const v103 = vs1.addViewRow({ className: \"spatial3\", name: \"test view 0\", json: \"json-blah\", owner: \"owner1\", groupId: 1, categorySel: c1, displayStyle: ds1 });\r\n const v104 = vs1.addViewRow({ className: \"spatial3\", name: \"another view\", json: \"json-blah\", owner: \"owner10\", groupId: 1, categorySel: c1, displayStyle: ds1 });\r\n\r\n const g3Id = vs1.getViewGroupByName(\"group 3\", g2);\r\n\r\n expect(g3Id).equals(g3);\r\n expect(vs1.findViewGroup(\"group1\")).equals(g1);\r\n expect(vs1.findViewGroup(\"group 3\")).equals(0); // not in the root group\r\n expect(vs1.findViewGroup(\"/group2/group 3/\")).equals(g3);\r\n expect(vs1.findViewGroup(\"/group2/group 3/group4\")).equals(g4);\r\n expect(vs1.findViewGroup(\"group2/group 3/group4\")).equals(g4);\r\n expect(vs1.findViewGroup(ViewStore.fromRowId(g4))).equals(g4);\r\n expect(vs1.findViewGroup(\"group2/group 3/group4/blah\")).equals(0);\r\n expect(vs1.findViewGroup(\"group2/blah/group4\")).equals(0);\r\n expect(vs1.findViewGroup(\"blah\")).equals(0);\r\n expect(vs1.findViewGroup(\"/\")).equals(1);\r\n expect(vs1.findViewGroup(\"\")).equals(1);\r\n\r\n expect(vs1.getViewByNameSync({ name: \"view2\", groupId: g4 })?.groupId).equals(ViewStore.fromRowId(g4));\r\n expect(vs1.findViewIdByName({ name: \"/group2/group 3/group4/view2\" })).equals(v2Id);\r\n expect(vs1.findViewIdByName({ name: \"group2/group 3/group4/view2\" })).equals(v2Id);\r\n expect(vs1.findViewIdByName({ name: `${ViewStore.fromRowId(g4)}/view2` })).equals(v2Id);\r\n expect(vs1.findViewIdByName({ name: \"group2/group 3/group4/not there\" })).equals(0);\r\n expect(vs1.findViewIdByName({ name: \"group2/test view 3\" })).not.equal(0);\r\n\r\n const group3 = vs1.getViewGroup(g3Id)!;\r\n expect(group3.name).equals(\"group 3\");\r\n expect(group3.parentId).equals(g2);\r\n expect(group3.json).equals(\"group3-json\");\r\n await vs1.renameViewGroup({ groupId: g3Id, name: \"group3-updated\" });\r\n vs1.updateViewGroupJson(g3Id, \"group3-json-updated\");\r\n const g3Updated = vs1.getViewGroup(g3Id)!;\r\n expect(g3Updated.name).equals(\"group3-updated\");\r\n expect(g3Updated.json).equals(\"group3-json-updated\");\r\n\r\n expect(vs1.queryViewsSync({ group: \"group2\", classNames: [\"spatial\"] }).length).equals(100);\r\n expect(vs1.queryViewsSync({ group: ViewStore.fromRowId(g4), classNames: [\"spatial2\"] }).length).equals(1);\r\n expect(vs1.queryViewsSync({ classNames: [\"spatial\", \"spatial3\", \"blah\"] }).length).equals(3);\r\n expect(vs1.queryViewsSync({ classNames: [] }).length).equals(0);\r\n expect(vs1.queryViewsSync({ classNames: [\"blah\"] }).length).equals(0);\r\n expect((await vs1.findViewsByOwner({ owner: \"owner1\" })).length).equals(101);\r\n\r\n const thumbnail1 = new Uint8Array([2, 33, 23, 0, 202]);\r\n const format1: ThumbnailFormatProps = { width: 100, height: 200, format: \"jpeg\" };\r\n const format2: ThumbnailFormatProps = { width: 10, height: 20, format: \"png\" };\r\n vs1.addOrReplaceThumbnailRow({ data: thumbnail1, viewId: v1Id, format: format1 });\r\n vs1.addOrReplaceThumbnailRow({ data: thumbnail1, viewId: v2Id, format: format2 });\r\n const thumbnail2 = vs1.getThumbnailRow(v2Id);\r\n expect(thumbnail2?.data).deep.equals(thumbnail1);\r\n expect(thumbnail2?.format).deep.equals(format2);\r\n const thumb3 = new Uint8Array([2, 33, 23, 0, 203]);\r\n vs1.addOrReplaceThumbnailRow({ data: thumb3, viewId: v2Id, format: format2 });\r\n const thumbnail3 = vs1.getThumbnailRow(v2Id);\r\n expect(thumbnail3?.data).deep.equals(thumb3);\r\n vs1.addOrReplaceThumbnailRow({ data: thumbnail1, viewId: 33, format: format1 });\r\n expect(vs1.getThumbnailRow(33)).to.not.be.undefined;\r\n vs1.deleteThumbnailSync(ViewStore.fromRowId(33));\r\n expect(vs1.getThumbnailRow(33)).to.be.undefined;\r\n\r\n await vs1.deleteViewGroup({ name: \"group1\" });\r\n expect(vs1.getViewByNameSync({ name: \"view2\", groupId: g1 })).to.be.undefined;\r\n\r\n const cat01 = vs1.addCategorySelectorRow({ name: \"cat1\", json: \"cat1-json\" });\r\n vs1.addCategorySelectorRow({ name: \"cat2\", json: \"cat2-json\" });\r\n const cat1Id = vs1.findCategorySelectorByName(\"cat1\");\r\n expect(cat1Id).equals(cat01);\r\n let cat1 = vs1.getCategorySelectorRow(cat1Id)!;\r\n expect(cat1.name).equals(\"cat1\");\r\n expect(cat1.json).equals(\"cat1-json\");\r\n await vs1.updateCategorySelectorJson(cat1Id, \"cat1-json-updated\");// eslint-disable-line @typescript-eslint/await-thenable\r\n cat1 = vs1.getCategorySelectorRow(cat1Id)!;\r\n expect(cat1.json).equals(\"cat1-json-updated\");\r\n\r\n vs1.deleteCategorySelectorSync(cat1Id);\r\n expect(vs1.findCategorySelectorByName(\"cat1\")).equals(0);\r\n\r\n const ds01 = vs1.addDisplayStyleRow({ name: \"style1\", json: \"style1-json\" });\r\n vs1.addDisplayStyleRow({ name: \"style2\", json: \"style2-json\" });\r\n const style1Id = vs1.findDisplayStyleByName(\"style1\");\r\n expect(style1Id).equals(ds01);\r\n const style1 = vs1.getDisplayStyleRow(style1Id)!;\r\n expect(style1.name).equals(\"style1\");\r\n expect(style1.json).equals(\"style1-json\");\r\n await vs1.renameDisplayStyle({ id: style1Id, name: \"style1-updated\" });\r\n const style1UpdatedNameId = vs1.findDisplayStyleByName(\"style1-updated\");\r\n expect(style1UpdatedNameId).equals(style1Id);\r\n\r\n vs1.updateDisplayStyleJson(style1Id, \"style1-json-updated\");\r\n const style1Updated = vs1.getDisplayStyleRow(style1Id)!;\r\n expect(style1Updated.json).equals(\"style1-json-updated\");\r\n\r\n vs1.deleteDisplayStyleSync(style1Id);\r\n expect(vs1.findDisplayStyleByName(\"style1\")).equals(0);\r\n expect(vs1.findDisplayStyleByName(\"style2\")).equals(3);\r\n\r\n vs1.addModelSelectorRow({ name: \"model1\", json: \"model1-json\" });\r\n const ms2 = vs1.addModelSelectorRow({ json: \"model2-json\" });\r\n const model1Id = vs1.findModelSelectorByName(\"model1\");\r\n expect(model1Id).equals(1);\r\n const model1 = vs1.getModelSelectorRow(model1Id)!;\r\n expect(model1.name).equals(\"model1\");\r\n expect(model1.json).equals(\"model1-json\");\r\n const model2 = vs1.getModelSelectorRow(ms2)!;\r\n expect(model2.name).undefined;\r\n expect(model2.json).equals(\"model2-json\");\r\n\r\n await vs1.renameModelSelector({ id: model1Id, name: \"model1-updated\" });\r\n const model1UpdatedNameId = vs1.findModelSelectorByName(\"model1-updated\");\r\n expect(model1UpdatedNameId).equals(model1Id);\r\n await vs1.renameModelSelector({ id: model1Id, name: undefined });\r\n expect(vs1.getModelSelectorRow(model1Id)!.name).undefined;\r\n\r\n vs1.updateModelSelectorJson(model1Id, \"model1-json-updated\");\r\n const model1Updated = vs1.getModelSelectorRow(model1Id)!;\r\n expect(model1Updated.json).equals(\"model1-json-updated\");\r\n\r\n vs1.deleteModelSelectorSync(model1Id);\r\n expect(vs1.findModelSelectorByName(\"model1\")).equals(0);\r\n\r\n vs1.addTimelineRow({ name: \"timeline1\", json: \"timeline1-json\" });\r\n vs1.addTimelineRow({ name: \"timeline2\", json: \"timeline2-json\" });\r\n const timeline1Id = vs1.findTimelineByName(\"timeline1\");\r\n const timeline2Id = vs1.findTimelineByName(\"timeline2\");\r\n expect(timeline1Id).equals(1);\r\n const timeline1 = vs1.getTimelineRow(timeline1Id)!;\r\n expect(timeline1.name).equals(\"timeline1\");\r\n expect(timeline1.json).equals(\"timeline1-json\");\r\n\r\n await vs1.renameTimeline({ id: timeline1Id, name: \"timeline1-updated\" });\r\n const timeline1UpdatedNameId = vs1.findTimelineByName(\"timeline1-updated\");\r\n expect(timeline1UpdatedNameId).equals(timeline1Id);\r\n\r\n vs1.updateTimelineJson(timeline1Id, \"timeline1-json-updated\");\r\n const timeline1Updated = vs1.getTimelineRow(timeline1Id)!;\r\n expect(timeline1Updated.json).equals(\"timeline1-json-updated\");\r\n\r\n vs1.deleteTimelineSync(timeline2Id);\r\n expect(vs1.findTimelineByName(\"timeline2\")).equals(0);\r\n\r\n const t1 = vs1.addTag({ name: \"tag1\", json: \"tag1-json\", owner: \"owner1\" });\r\n vs1.addTag({ name: \"tag2\", json: \"tag2-json\" });\r\n const tag1Id = vs1.findTagByName(\"tag1\");\r\n expect(tag1Id).equals(t1);\r\n const tag1 = vs1.getTag(tag1Id)!;\r\n expect(tag1.name).equals(\"tag1\");\r\n expect(tag1.json).equals(\"tag1-json\");\r\n expect(tag1.owner).equals(\"owner1\");\r\n for (let i = 0; i < 5; i++)\r\n vs1.addTag({ name: `test tag ${i}`, json: `newTag${i}-json` });\r\n\r\n vs1.addTagToView({ viewId: v1Id, tagId: tag1Id });\r\n vs1.addTagToView({ viewId: v1Id, tagId: 2 });\r\n vs1.addTagToView({ viewId: v103, tagId: 2 });\r\n vs1.addTagToView({ viewId: v104, tagId: 2 });\r\n vs1.addTagToView({ viewId: v1Id, tagId: 3 });\r\n const taggedViewIds = vs1.findViewsForTag(tag1Id);\r\n expect(taggedViewIds.length).equals(1);\r\n expect(taggedViewIds[0]).equals(v1Id);\r\n const tags = vs1.getTagsForView(v1Id)!;\r\n expect(tags.length).equals(3);\r\n expect(tags[0]).equals(\"tag1\");\r\n expect(tags[1]).equals(\"tag2\");\r\n expect(tags[2]).equals(\"test tag 0\");\r\n\r\n vs1.addViewRow({ className: \"BisCore:SpatialViewDefinition\", name: \"my private 2\", json: \"json1\", owner: \"owner10\", isPrivate: true, groupId: 1, categorySel: c1, displayStyle: ds1 });\r\n vs1.addViewRow({ className: \"BisCore:OrthographicViewDefinition\", name: \"my private 3\", json: \"json1\", owner: \"owner10\", isPrivate: true, groupId: 1, categorySel: c1, displayStyle: ds1 });\r\n vs1.addViewRow({ className: \"BisCore:SheetViewDefinition\", name: \"sheet 3\", json: \"json1\", owner: \"owner10\", isPrivate: true, groupId: 1, categorySel: c1, displayStyle: ds1 });\r\n vs1.addViewRow({ className: \"BisCore:DrawingViewDefinition\", name: \"drawing 3\", json: \"json1\", owner: \"owner10\", isPrivate: true, groupId: 1, categorySel: c1, displayStyle: ds1 });\r\n\r\n let views = vs1.queryViewsSync({ group: \"/\" });\r\n expect(views.length).equals(3);\r\n expect(views[0].name).equals(\"another view\");\r\n expect(vs1.queryViewsSync({ group: \"group1\" }).length).equals(0);\r\n expect(vs1.queryViewsSync({ group: \"group2\" }).length).equal(100);\r\n expect(vs1.queryViewsSync({ group: \"group2\", offset: 20, limit: 10 }).length).equals(10);\r\n expect(vs1.queryViewsSync({ group: \"group2\", offset: 20, limit: 100 }).length).equals(80);\r\n views = vs1.queryViewsSync({ group: \"group2\", nameSearch: \"%20%\", nameCompare: \"LIKE\" });\r\n expect(views.length).equals(1);\r\n expect(views[0].name).equals(\"test view 20\");\r\n views = vs1.queryViewsSync({ group: \"group2\", nameSearch: \"*2*\", nameCompare: \"GLOB\" });\r\n expect(views.length).equals(19);\r\n expect(vs1.queryViewsSync({ group: \"group2\", tags: [\"tag1\"] }).length).equal(0);\r\n expect(vs1.queryViewsSync({ tags: [\"tag1\"] }).length).equal(1);\r\n views = vs1.queryViewsSync({ tags: [\"tag2\", \"tag1\"] });\r\n expect(views.length).equal(3);\r\n expect(views[2].tags?.length).equal(3);\r\n views = vs1.queryViewsSync({ owner: \"owner10\" });\r\n expect(views.length).equal(7);\r\n views = vs1.queryViewsSync({ owner: \"owner10\", nameSearch: \"my%\", nameCompare: \"LIKE\" });\r\n expect(views.length).equal(2);\r\n expect(vs1.queryViewsSync({ owner: \"owner10\", classNames: [\"BisCore:SpatialViewDefinition\"] }).length).equal(1);\r\n expect(vs1.queryViewsSync({ owner: \"owner10\", classNames: [\"BisCore:SpatialViewDefinition\", \"BisCore:OrthographicViewDefinition\"] }).length).equal(2);\r\n expect(vs1.queryViewsSync({ owner: \"owner10\", classNames: [\"BisCore:DrawingViewDefinition\"] }).length).equal(1);\r\n expect(vs1.queryViewsSync({ owner: \"owner10\", classNames: [\"BisCore:DrawingViewDefinition\", \"BisCore:SheetViewDefinition\"] }).length).equal(2);\r\n\r\n await vs1.renameTag({ oldName: \"tag2\", newName: \"tag2-renamed\" });\r\n views = vs1.queryViewsSync({ tags: [\"tag2-renamed\"] });\r\n expect(views.length).equal(3);\r\n\r\n vs1.deleteTagSync({ name: \"tag2-renamed\" });\r\n const tagIdsAfterDelete = vs1.getTagsForView(v1Id)!;\r\n expect(tagIdsAfterDelete.length).equals(2);\r\n expect(tagIdsAfterDelete[0]).equals(\"tag1\");\r\n expect(tagIdsAfterDelete[1]).equals(\"test tag 0\");\r\n\r\n await vs1.addSearch({ name: \"search1\", json: \"search1-json\" });\r\n const search2 = await vs1.addSearch({ name: \"search2\", json: \"search2-json\" });\r\n await expect(vs1.addSearch({ name: \"search1\", json: \"search1-json\" })).to.be.rejectedWith(\"UNIQUE\");\r\n const search1Id = vs1.findSearchByName(\"search1\");\r\n expect(search1Id).equals(1);\r\n const search1 = vs1.getSearch(search1Id)!;\r\n expect(search1.name).equals(\"search1\");\r\n expect(search1.json).equals(\"search1-json\");\r\n await vs1.renameSearch({ id: search1Id, name: \"search1-updated\" });\r\n const search1UpdatedNameId = vs1.findSearchByName(\"search1-updated\");\r\n expect(search1UpdatedNameId).equals(search1Id);\r\n vs1.updateSearchJson(search1Id, \"search1-json-updated\");\r\n const search1Updated = vs1.getSearch(search1Id)!;\r\n expect(search1Updated.json).equals(\"search1-json-updated\");\r\n vs1.deleteSearch(search2);\r\n expect(vs1.findSearchByName(\"search2\")).equals(0);\r\n\r\n const guids: GuidString[] = [];\r\n const rowIds: ViewStore.RowId[] = [];\r\n const nGuids = 1000;\r\n for (let i = 0; i < nGuids; i++) {\r\n const guid = Guid.createValue();\r\n const rowId = vs1.addGuid(guid);\r\n guids.push(guid);\r\n rowIds.push(rowId);\r\n }\r\n for (let i = 0; i < nGuids; i++) {\r\n expect(vs1.getGuid(rowIds[i])).equals(guids[i]);\r\n expect(vs1.addGuid(guids[i])).equals(rowIds[i]);\r\n }\r\n\r\n let count = 0;\r\n vs1.iterateGuids(rowIds, (guid: GuidString, row: ViewStore.RowId) => {\r\n count++;\r\n expect(guid).not.undefined;\r\n expect(guids.indexOf(guid)).not.equals(-1);\r\n const rowString1 = ViewStore.fromRowId(row);\r\n expect(rowString1.startsWith(\"@\")).true;\r\n expect(ViewStore.toRowId(rowString1)).equals(row); // round trip\r\n });\r\n expect(count).equals(nGuids);\r\n\r\n const largeNumber = 0x7ffffffffffff;\r\n expect(ViewStore.toRowId(ViewStore.fromRowId(largeNumber))).equals(largeNumber);\r\n\r\n vs1.vacuum();\r\n });\r\n\r\n it(\"selector queries should skip undefined and null bindings\", async () => {\r\n const dbName = join(KnownTestLocations.outputDir, \"viewStoreBindings.db\");\r\n if (IModelJsFs.existsSync(dbName))\r\n IModelJsFs.removeSync(dbName);\r\n const snapshot = SnapshotDb.openFile(IModelTestUtils.resolveAssetFile(\"test.bim\"));\r\n const vs = new ViewStore.ViewDb({ guidMap: {} as any });\r\n try {\r\n ViewStore.ViewDb.createNewDb(dbName);\r\n vs.openDb(dbName, OpenMode.ReadWrite);\r\n vs.iModel = snapshot;\r\n\r\n const selectorId = await vs.addCategorySelector({ selector: { query: { from: \"BisCore:SpatialCategory\" } } });\r\n\r\n const baseline = vs.getCategorySelectorSync({ id: selectorId });\r\n expect(baseline.categories.length).greaterThan(0);\r\n\r\n // Undefined/null bindings not referenced by the query must be skipped (legacy ECSqlStatement.bindValues\r\n // semantics, per ViewStoreRpc.QueryBindings), not bound as NULL.\r\n const withUnusedUndefined = vs.getCategorySelectorSync({ id: selectorId, bindings: { parent: undefined } });\r\n expect(withUnusedUndefined.categories).deep.equal(baseline.categories);\r\n\r\n const withUnusedNull = vs.getCategorySelectorSync({ id: selectorId, bindings: { parent: null } });\r\n expect(withUnusedNull.categories).deep.equal(baseline.categories);\r\n } finally {\r\n if (vs.isOpen)\r\n vs.closeDb();\r\n if (snapshot.isOpen)\r\n snapshot.close();\r\n }\r\n });\r\n});\r\n"]}
1
+ {"version":3,"file":"ViewStoreDb.test.js","sourceRoot":"","sources":["../../../../src/test/standalone/ViewStoreDb.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 { expect } from \"chai\";\r\nimport { Suite } from \"mocha\";\r\nimport { join } from \"path\";\r\nimport { Guid, GuidString, Logger, LogLevel, OpenMode } from \"@itwin/core-bentley\";\r\nimport { ViewStore } from \"../../ViewStore\";\r\nimport { ThumbnailFormatProps, ViewStoreError } from \"@itwin/core-common\";\r\nimport { KnownTestLocations } from \"../KnownTestLocations\";\r\nimport { SnapshotDb } from \"../../IModelDb\";\r\nimport { IModelTestUtils } from \"../IModelTestUtils\";\r\nimport { IModelJsFs } from \"../../IModelJsFs\";\r\n\r\ndescribe(\"ViewStore\", function (this: Suite) {\r\n this.timeout(0);\r\n\r\n let vs1: ViewStore.ViewDb;\r\n\r\n before(async () => {\r\n Logger.setLevel(\"SQLite\", LogLevel.None); // we're expecting errors\r\n const dbName = join(KnownTestLocations.outputDir, \"viewStore.db\");\r\n ViewStore.ViewDb.createNewDb(dbName);\r\n vs1 = new ViewStore.ViewDb({ guidMap: {} as any });\r\n vs1.openDb(dbName, OpenMode.ReadWrite);\r\n });\r\n\r\n after(async () => {\r\n vs1.closeDb(true);\r\n Logger.setLevel(\"SQLite\", LogLevel.Error);\r\n });\r\n\r\n it(\"ViewDb\", async () => {\r\n const c1 = vs1.addCategorySelectorRow({ name: \"first cat\", json: \"cat1-json\" });\r\n const ds1 = vs1.addDisplayStyleRow({ name: \"first style\", json: \"style1-json\" });\r\n\r\n expect(vs1.getViewByNameSync({ name: \"view1\" })).to.be.undefined;\r\n const v1Id = vs1.addViewRow({ className: \"spatial\", name: \"view1\", json: \"json1\", owner: \"owner10\", isPrivate: true, groupId: 1, categorySel: c1, displayStyle: ds1 });\r\n expect(v1Id).equals(1);\r\n\r\n const v1 = vs1.getViewByNameSync({ name: \"view1\" })!;\r\n expect(vs1.findViewIdByName({ name: \"view1\" })).equals(v1Id);\r\n expect(vs1.findViewIdByName({ name: \"/view1\" })).equals(v1Id);\r\n expect(v1.owner).equals(\"owner10\");\r\n expect(v1.className).equals(\"spatial\");\r\n expect(v1.groupId).equals(\"@1\");\r\n expect(v1.isPrivate).to.be.true;\r\n expect(v1.name).equals(\"view1\");\r\n await vs1.updateViewShared({ viewId: v1Id, isShared: true, owner: \"owner10\" });\r\n const v1Updated = vs1.getViewByNameSync({ name: \"view1\" })!;\r\n expect(v1Updated.isPrivate).to.be.false;\r\n\r\n const v1Id2 = vs1.addViewRow({ className: \"spatial\", name: \"v2\", json: \"json-v2\", owner: \"owner1\", groupId: 1, categorySel: c1, displayStyle: ds1 });\r\n expect(v1Id2).equals(2);\r\n const v2 = vs1.getViewRow(v1Id2)!;\r\n expect(v2.name).equals(\"v2\");\r\n vs1.deleteViewRow(v1Id2);\r\n expect(vs1.findViewIdByName({ name: \"v2\", groupId: 1 })).equals(0);\r\n\r\n expect(() => vs1.addViewGroupRow({ name: \"\", json: \"\" })).to.throw(\"illegal group\");\r\n expect(() => vs1.addViewGroupRow({ name: \" \", json: \"\" })).to.throw(\"illegal group\");\r\n expect(() => vs1.addViewGroupRow({ name: \"@bad\", json: \"\" })).to.throw(\"illegal group\");\r\n expect(() => vs1.addViewGroupRow({ name: \"bad/name\", json: \"\" })).to.throw(\"illegal group\");\r\n expect(() => vs1.addViewGroupRow({ name: \"^fd\", json: \"\" })).to.throw(\"illegal group\");\r\n expect(() => vs1.addViewGroupRow({ name: \"sd#fd\", json: \"\" })).to.throw(\"illegal group\");\r\n expect(() => vs1.addViewRow({ className: \"spatial\", name: \"@bad\", json: \"json-v2\", owner: \"owner1\", groupId: 1, categorySel: c1, displayStyle: ds1 })).to.throw(\"illegal view\");\r\n expect(() => vs1.addViewRow({ className: \"spatial\", name: \"bad/name\", json: \"json-v2\", owner: \"owner1\", groupId: 1, categorySel: c1, displayStyle: ds1 })).to.throw(\"illegal view\");\r\n\r\n const g1 = vs1.addViewGroupRow({ name: \"group1\", json: \"group1-json\" });\r\n const g2 = vs1.addViewGroupRow({ name: \"group2\", json: \"group2-json\" });\r\n const g3 = vs1.addViewGroupRow({ name: \"group 3\", parentId: g2, json: \"group3-json\" });\r\n const g4 = vs1.addViewGroupRow({ name: \"group4\", parentId: g3, json: \"group3-json\" });\r\n const v2Id = vs1.addViewRow({ className: \"spatial2\", name: \"view2\", json: \"json2\", groupId: g4, categorySel: c1, displayStyle: ds1 });\r\n expect(v2Id).equals(3);\r\n\r\n for (let i = 0; i < 100; i++)\r\n vs1.addViewRow({ className: \"spatial\", name: `test view ${i}`, json: `json${i}`, owner: \"owner1\", groupId: g2, categorySel: c1, displayStyle: ds1 });\r\n\r\n // duplicate name in a group should throw\r\n expect(() => vs1.addViewRow({ className: \"spatial3\", name: \"test view 0\", json: \"json-blah\", owner: \"owner1\", groupId: g2, categorySel: c1, displayStyle: ds1 })).to.throw(\"UNIQUE\");\r\n // allow the same name in different groups\r\n const v103 = vs1.addViewRow({ className: \"spatial3\", name: \"test view 0\", json: \"json-blah\", owner: \"owner1\", groupId: 1, categorySel: c1, displayStyle: ds1 });\r\n const v104 = vs1.addViewRow({ className: \"spatial3\", name: \"another view\", json: \"json-blah\", owner: \"owner10\", groupId: 1, categorySel: c1, displayStyle: ds1 });\r\n\r\n const g3Id = vs1.getViewGroupByName(\"group 3\", g2);\r\n\r\n expect(g3Id).equals(g3);\r\n expect(vs1.findViewGroup(\"group1\")).equals(g1);\r\n expect(vs1.findViewGroup(\"group 3\")).equals(0); // not in the root group\r\n expect(vs1.findViewGroup(\"/group2/group 3/\")).equals(g3);\r\n expect(vs1.findViewGroup(\"/group2/group 3/group4\")).equals(g4);\r\n expect(vs1.findViewGroup(\"group2/group 3/group4\")).equals(g4);\r\n expect(vs1.findViewGroup(ViewStore.fromRowId(g4))).equals(g4);\r\n expect(vs1.findViewGroup(\"group2/group 3/group4/blah\")).equals(0);\r\n expect(vs1.findViewGroup(\"group2/blah/group4\")).equals(0);\r\n expect(vs1.findViewGroup(\"blah\")).equals(0);\r\n expect(vs1.findViewGroup(\"/\")).equals(1);\r\n expect(vs1.findViewGroup(\"\")).equals(1);\r\n\r\n expect(vs1.getViewByNameSync({ name: \"view2\", groupId: g4 })?.groupId).equals(ViewStore.fromRowId(g4));\r\n expect(vs1.findViewIdByName({ name: \"/group2/group 3/group4/view2\" })).equals(v2Id);\r\n expect(vs1.findViewIdByName({ name: \"group2/group 3/group4/view2\" })).equals(v2Id);\r\n expect(vs1.findViewIdByName({ name: `${ViewStore.fromRowId(g4)}/view2` })).equals(v2Id);\r\n expect(vs1.findViewIdByName({ name: \"group2/group 3/group4/not there\" })).equals(0);\r\n expect(vs1.findViewIdByName({ name: \"group2/test view 3\" })).not.equal(0);\r\n\r\n const group3 = vs1.getViewGroup(g3Id)!;\r\n expect(group3.name).equals(\"group 3\");\r\n expect(group3.parentId).equals(g2);\r\n expect(group3.json).equals(\"group3-json\");\r\n await vs1.renameViewGroup({ groupId: g3Id, name: \"group3-updated\" });\r\n vs1.updateViewGroupJson(g3Id, \"group3-json-updated\");\r\n const g3Updated = vs1.getViewGroup(g3Id)!;\r\n expect(g3Updated.name).equals(\"group3-updated\");\r\n expect(g3Updated.json).equals(\"group3-json-updated\");\r\n\r\n expect(vs1.queryViewsSync({ group: \"group2\", classNames: [\"spatial\"] }).length).equals(100);\r\n expect(vs1.queryViewsSync({ group: ViewStore.fromRowId(g4), classNames: [\"spatial2\"] }).length).equals(1);\r\n expect(vs1.queryViewsSync({ classNames: [\"spatial\", \"spatial3\", \"blah\"] }).length).equals(3);\r\n expect(vs1.queryViewsSync({ classNames: [] }).length).equals(0);\r\n expect(vs1.queryViewsSync({ classNames: [\"blah\"] }).length).equals(0);\r\n expect((await vs1.findViewsByOwner({ owner: \"owner1\" })).length).equals(101);\r\n\r\n const thumbnail1 = new Uint8Array([2, 33, 23, 0, 202]);\r\n const format1: ThumbnailFormatProps = { width: 100, height: 200, format: \"jpeg\" };\r\n const format2: ThumbnailFormatProps = { width: 10, height: 20, format: \"png\" };\r\n vs1.addOrReplaceThumbnailRow({ data: thumbnail1, viewId: v1Id, format: format1 });\r\n vs1.addOrReplaceThumbnailRow({ data: thumbnail1, viewId: v2Id, format: format2 });\r\n const thumbnail2 = vs1.getThumbnailRow(v2Id);\r\n expect(thumbnail2?.data).deep.equals(thumbnail1);\r\n expect(thumbnail2?.format).deep.equals(format2);\r\n const thumb3 = new Uint8Array([2, 33, 23, 0, 203]);\r\n vs1.addOrReplaceThumbnailRow({ data: thumb3, viewId: v2Id, format: format2 });\r\n const thumbnail3 = vs1.getThumbnailRow(v2Id);\r\n expect(thumbnail3?.data).deep.equals(thumb3);\r\n vs1.addOrReplaceThumbnailRow({ data: thumbnail1, viewId: 33, format: format1 });\r\n expect(vs1.getThumbnailRow(33)).to.not.be.undefined;\r\n vs1.deleteThumbnailSync(ViewStore.fromRowId(33));\r\n expect(vs1.getThumbnailRow(33)).to.be.undefined;\r\n\r\n await vs1.deleteViewGroup({ name: \"group1\" });\r\n expect(vs1.getViewByNameSync({ name: \"view2\", groupId: g1 })).to.be.undefined;\r\n\r\n const cat01 = vs1.addCategorySelectorRow({ name: \"cat1\", json: \"cat1-json\" });\r\n vs1.addCategorySelectorRow({ name: \"cat2\", json: \"cat2-json\" });\r\n const cat1Id = vs1.findCategorySelectorByName(\"cat1\");\r\n expect(cat1Id).equals(cat01);\r\n let cat1 = vs1.getCategorySelectorRow(cat1Id)!;\r\n expect(cat1.name).equals(\"cat1\");\r\n expect(cat1.json).equals(\"cat1-json\");\r\n await vs1.updateCategorySelectorJson(cat1Id, \"cat1-json-updated\");// eslint-disable-line @typescript-eslint/await-thenable\r\n cat1 = vs1.getCategorySelectorRow(cat1Id)!;\r\n expect(cat1.json).equals(\"cat1-json-updated\");\r\n\r\n vs1.deleteCategorySelectorSync(cat1Id);\r\n expect(vs1.findCategorySelectorByName(\"cat1\")).equals(0);\r\n\r\n const ds01 = vs1.addDisplayStyleRow({ name: \"style1\", json: \"style1-json\" });\r\n vs1.addDisplayStyleRow({ name: \"style2\", json: \"style2-json\" });\r\n const style1Id = vs1.findDisplayStyleByName(\"style1\");\r\n expect(style1Id).equals(ds01);\r\n const style1 = vs1.getDisplayStyleRow(style1Id)!;\r\n expect(style1.name).equals(\"style1\");\r\n expect(style1.json).equals(\"style1-json\");\r\n await vs1.renameDisplayStyle({ id: style1Id, name: \"style1-updated\" });\r\n const style1UpdatedNameId = vs1.findDisplayStyleByName(\"style1-updated\");\r\n expect(style1UpdatedNameId).equals(style1Id);\r\n\r\n vs1.updateDisplayStyleJson(style1Id, \"style1-json-updated\");\r\n const style1Updated = vs1.getDisplayStyleRow(style1Id)!;\r\n expect(style1Updated.json).equals(\"style1-json-updated\");\r\n\r\n vs1.deleteDisplayStyleSync(style1Id);\r\n expect(vs1.findDisplayStyleByName(\"style1\")).equals(0);\r\n expect(vs1.findDisplayStyleByName(\"style2\")).equals(3);\r\n\r\n vs1.addModelSelectorRow({ name: \"model1\", json: \"model1-json\" });\r\n const ms2 = vs1.addModelSelectorRow({ json: \"model2-json\" });\r\n const model1Id = vs1.findModelSelectorByName(\"model1\");\r\n expect(model1Id).equals(1);\r\n const model1 = vs1.getModelSelectorRow(model1Id)!;\r\n expect(model1.name).equals(\"model1\");\r\n expect(model1.json).equals(\"model1-json\");\r\n const model2 = vs1.getModelSelectorRow(ms2)!;\r\n expect(model2.name).undefined;\r\n expect(model2.json).equals(\"model2-json\");\r\n\r\n await vs1.renameModelSelector({ id: model1Id, name: \"model1-updated\" });\r\n const model1UpdatedNameId = vs1.findModelSelectorByName(\"model1-updated\");\r\n expect(model1UpdatedNameId).equals(model1Id);\r\n await vs1.renameModelSelector({ id: model1Id, name: undefined });\r\n expect(vs1.getModelSelectorRow(model1Id)!.name).undefined;\r\n\r\n vs1.updateModelSelectorJson(model1Id, \"model1-json-updated\");\r\n const model1Updated = vs1.getModelSelectorRow(model1Id)!;\r\n expect(model1Updated.json).equals(\"model1-json-updated\");\r\n\r\n vs1.deleteModelSelectorSync(model1Id);\r\n expect(vs1.findModelSelectorByName(\"model1\")).equals(0);\r\n\r\n vs1.addTimelineRow({ name: \"timeline1\", json: \"timeline1-json\" });\r\n vs1.addTimelineRow({ name: \"timeline2\", json: \"timeline2-json\" });\r\n const timeline1Id = vs1.findTimelineByName(\"timeline1\");\r\n const timeline2Id = vs1.findTimelineByName(\"timeline2\");\r\n expect(timeline1Id).equals(1);\r\n const timeline1 = vs1.getTimelineRow(timeline1Id)!;\r\n expect(timeline1.name).equals(\"timeline1\");\r\n expect(timeline1.json).equals(\"timeline1-json\");\r\n\r\n await vs1.renameTimeline({ id: timeline1Id, name: \"timeline1-updated\" });\r\n const timeline1UpdatedNameId = vs1.findTimelineByName(\"timeline1-updated\");\r\n expect(timeline1UpdatedNameId).equals(timeline1Id);\r\n\r\n vs1.updateTimelineJson(timeline1Id, \"timeline1-json-updated\");\r\n const timeline1Updated = vs1.getTimelineRow(timeline1Id)!;\r\n expect(timeline1Updated.json).equals(\"timeline1-json-updated\");\r\n\r\n vs1.deleteTimelineSync(timeline2Id);\r\n expect(vs1.findTimelineByName(\"timeline2\")).equals(0);\r\n\r\n const t1 = vs1.addTag({ name: \"tag1\", json: \"tag1-json\", owner: \"owner1\" });\r\n vs1.addTag({ name: \"tag2\", json: \"tag2-json\" });\r\n const tag1Id = vs1.findTagByName(\"tag1\");\r\n expect(tag1Id).equals(t1);\r\n const tag1 = vs1.getTag(tag1Id)!;\r\n expect(tag1.name).equals(\"tag1\");\r\n expect(tag1.json).equals(\"tag1-json\");\r\n expect(tag1.owner).equals(\"owner1\");\r\n for (let i = 0; i < 5; i++)\r\n vs1.addTag({ name: `test tag ${i}`, json: `newTag${i}-json` });\r\n\r\n vs1.addTagToView({ viewId: v1Id, tagId: tag1Id });\r\n vs1.addTagToView({ viewId: v1Id, tagId: 2 });\r\n vs1.addTagToView({ viewId: v103, tagId: 2 });\r\n vs1.addTagToView({ viewId: v104, tagId: 2 });\r\n vs1.addTagToView({ viewId: v1Id, tagId: 3 });\r\n const taggedViewIds = vs1.findViewsForTag(tag1Id);\r\n expect(taggedViewIds.length).equals(1);\r\n expect(taggedViewIds[0]).equals(v1Id);\r\n const tags = vs1.getTagsForView(v1Id)!;\r\n expect(tags.length).equals(3);\r\n expect(tags[0]).equals(\"tag1\");\r\n expect(tags[1]).equals(\"tag2\");\r\n expect(tags[2]).equals(\"test tag 0\");\r\n\r\n vs1.addViewRow({ className: \"BisCore:SpatialViewDefinition\", name: \"my private 2\", json: \"json1\", owner: \"owner10\", isPrivate: true, groupId: 1, categorySel: c1, displayStyle: ds1 });\r\n vs1.addViewRow({ className: \"BisCore:OrthographicViewDefinition\", name: \"my private 3\", json: \"json1\", owner: \"owner10\", isPrivate: true, groupId: 1, categorySel: c1, displayStyle: ds1 });\r\n vs1.addViewRow({ className: \"BisCore:SheetViewDefinition\", name: \"sheet 3\", json: \"json1\", owner: \"owner10\", isPrivate: true, groupId: 1, categorySel: c1, displayStyle: ds1 });\r\n vs1.addViewRow({ className: \"BisCore:DrawingViewDefinition\", name: \"drawing 3\", json: \"json1\", owner: \"owner10\", isPrivate: true, groupId: 1, categorySel: c1, displayStyle: ds1 });\r\n\r\n let views = vs1.queryViewsSync({ group: \"/\" });\r\n expect(views.length).equals(3);\r\n expect(views[0].name).equals(\"another view\");\r\n expect(vs1.queryViewsSync({ group: \"group1\" }).length).equals(0);\r\n expect(vs1.queryViewsSync({ group: \"group2\" }).length).equal(100);\r\n expect(vs1.queryViewsSync({ group: \"group2\", offset: 20, limit: 10 }).length).equals(10);\r\n expect(vs1.queryViewsSync({ group: \"group2\", offset: 20, limit: 100 }).length).equals(80);\r\n views = vs1.queryViewsSync({ group: \"group2\", nameSearch: \"%20%\", nameCompare: \"LIKE\" });\r\n expect(views.length).equals(1);\r\n expect(views[0].name).equals(\"test view 20\");\r\n views = vs1.queryViewsSync({ group: \"group2\", nameSearch: \"*2*\", nameCompare: \"GLOB\" });\r\n expect(views.length).equals(19);\r\n expect(vs1.queryViewsSync({ group: \"group2\", tags: [\"tag1\"] }).length).equal(0);\r\n expect(vs1.queryViewsSync({ tags: [\"tag1\"] }).length).equal(1);\r\n views = vs1.queryViewsSync({ tags: [\"tag2\", \"tag1\"] });\r\n expect(views.length).equal(3);\r\n expect(views[2].tags?.length).equal(3);\r\n views = vs1.queryViewsSync({ owner: \"owner10\" });\r\n expect(views.length).equal(7);\r\n views = vs1.queryViewsSync({ owner: \"owner10\", nameSearch: \"my%\", nameCompare: \"LIKE\" });\r\n expect(views.length).equal(2);\r\n expect(vs1.queryViewsSync({ owner: \"owner10\", classNames: [\"BisCore:SpatialViewDefinition\"] }).length).equal(1);\r\n expect(vs1.queryViewsSync({ owner: \"owner10\", classNames: [\"BisCore:SpatialViewDefinition\", \"BisCore:OrthographicViewDefinition\"] }).length).equal(2);\r\n expect(vs1.queryViewsSync({ owner: \"owner10\", classNames: [\"BisCore:DrawingViewDefinition\"] }).length).equal(1);\r\n expect(vs1.queryViewsSync({ owner: \"owner10\", classNames: [\"BisCore:DrawingViewDefinition\", \"BisCore:SheetViewDefinition\"] }).length).equal(2);\r\n\r\n // query parameters may come from RPC callers, so values must never be interpreted as SQL\r\n const allPublicCount = vs1.queryViewsSync({}).length;\r\n const injectClause = \"x') OR 1=1 OR className IN('x\";\r\n expect(vs1.queryViewsSync({ classNames: [injectClause] }).length).equal(0);\r\n expect(vs1.queryViewsSync({ classNames: [\"foo') UNION SELECT Id,name,owner,private,1 FROM views -- \"] }).length).equal(0);\r\n expect(vs1.queryViewsSync({ tags: [injectClause] }).length).equal(0);\r\n expect(vs1.queryViewsSync({ classNames: [\"it's\"] }).length).equal(0); // quotes in values must not cause SQL errors\r\n expect(vs1.queryViewsSync({ tags: [\"it's\"] }).length).equal(0);\r\n expect(vs1.queryViewsSync({ nameSearch: \"' OR 1=1 --\" }).length).equal(0);\r\n expect(vs1.queryViewsSync({ group: \"group2\", offset: 95 }).length).equal(5); // offset without limit\r\n const badParams: any[] = [\r\n { nameSearch: \"x\", nameCompare: \"= @name OR 1=1 OR name =\" },\r\n { nameSearch: \"x\", nameCompare: \"like\" },\r\n { limit: \"1 UNION SELECT Id FROM views\" },\r\n { limit: 1.5 },\r\n { limit: -1 },\r\n { limit: 10, offset: \"1; --\" },\r\n { classNames: \"BisCore:SpatialViewDefinition\" },\r\n { classNames: [1] },\r\n { tags: [{}] },\r\n { owner: 1 },\r\n { nameSearch: { $ne: \"\" } },\r\n { group: 5 },\r\n { group: [\"group2\"] },\r\n null,\r\n undefined,\r\n ];\r\n for (const params of badParams) {\r\n // must be rejected by validation with a ViewStoreError, not fail later with a generic or native error\r\n expect(() => vs1.queryViewsSync(params), String(JSON.stringify(params))).throws().that.satisfies((e: unknown) => ViewStoreError.isError(e, \"invalid-value\"));\r\n }\r\n expect(vs1.queryViewsSync({ owner: \"\", nameSearch: \"\", group: \"\" }).length).equal(allPublicCount); // empty strings are treated as absent\r\n\r\n // owner is optional: without it only public views are returned; with it, that owner's private views are added\r\n expect(vs1.queryViewsSync({ group: \"/\" }).every((view) => !view.isPrivate)).to.be.true;\r\n expect(vs1.queryViewsSync({ group: \"/\", owner: \"someoneElse\" }).every((view) => !view.isPrivate)).to.be.true;\r\n expect(vs1.queryViewsSync({ group: \"/\", owner: \"owner10\" }).filter((view) => view.isPrivate).length).equal(4);\r\n expect(vs1.queryViewsSync({ nameSearch: \"my private 2\" }).length).equal(0);\r\n expect(vs1.queryViewsSync({ nameSearch: \"my private 2\", owner: \"someoneElse\" }).length).equal(0);\r\n expect(vs1.queryViewsSync({ nameSearch: \"my private 2\", owner: \"owner10\" }).length).equal(1);\r\n\r\n // a limit of 0 means no limit\r\n expect(vs1.queryViewsSync({ group: \"group2\", limit: 0 }).length).equal(100);\r\n expect(vs1.queryViewsSync({ group: \"group2\", limit: 0, offset: 0 }).length).equal(100);\r\n\r\n // the query statement is cached, so bindings from one call must not leak into the next\r\n expect(vs1.queryViewsSync({ owner: \"owner10\" }).length).equal(7);\r\n expect(vs1.queryViewsSync({}).length).equal(allPublicCount);\r\n expect(vs1.queryViewsSync({ owner: \"owner10\", classNames: [\"BisCore:SpatialViewDefinition\"], nameSearch: \"my%\", nameCompare: \"LIKE\", limit: 1 }).length).equal(1);\r\n expect(vs1.queryViewsSync({ nameSearch: \"another view\" }).length).equal(1);\r\n expect(vs1.queryViewsSync({}).length).equal(allPublicCount);\r\n\r\n // arrays are bound as a single JSON value, so their size is not limited by SQLite's bound-variable limit\r\n const manyClassNames = Array.from({ length: 40000 }, (_, i) => `Fake:Class${i}`);\r\n expect(vs1.queryViewsSync({ owner: \"owner10\", classNames: [...manyClassNames, \"BisCore:DrawingViewDefinition\"] }).length).equal(1);\r\n expect(vs1.queryViewsSync({}).length).equal(allPublicCount);\r\n\r\n await vs1.renameTag({ oldName: \"tag2\", newName: \"tag2-renamed\" });\r\n views = vs1.queryViewsSync({ tags: [\"tag2-renamed\"] });\r\n expect(views.length).equal(3);\r\n\r\n vs1.deleteTagSync({ name: \"tag2-renamed\" });\r\n const tagIdsAfterDelete = vs1.getTagsForView(v1Id)!;\r\n expect(tagIdsAfterDelete.length).equals(2);\r\n expect(tagIdsAfterDelete[0]).equals(\"tag1\");\r\n expect(tagIdsAfterDelete[1]).equals(\"test tag 0\");\r\n\r\n await vs1.addSearch({ name: \"search1\", json: \"search1-json\" });\r\n const search2 = await vs1.addSearch({ name: \"search2\", json: \"search2-json\" });\r\n await expect(vs1.addSearch({ name: \"search1\", json: \"search1-json\" })).to.be.rejectedWith(\"UNIQUE\");\r\n const search1Id = vs1.findSearchByName(\"search1\");\r\n expect(search1Id).equals(1);\r\n const search1 = vs1.getSearch(search1Id)!;\r\n expect(search1.name).equals(\"search1\");\r\n expect(search1.json).equals(\"search1-json\");\r\n await vs1.renameSearch({ id: search1Id, name: \"search1-updated\" });\r\n const search1UpdatedNameId = vs1.findSearchByName(\"search1-updated\");\r\n expect(search1UpdatedNameId).equals(search1Id);\r\n vs1.updateSearchJson(search1Id, \"search1-json-updated\");\r\n const search1Updated = vs1.getSearch(search1Id)!;\r\n expect(search1Updated.json).equals(\"search1-json-updated\");\r\n vs1.deleteSearch(search2);\r\n expect(vs1.findSearchByName(\"search2\")).equals(0);\r\n\r\n const guids: GuidString[] = [];\r\n const rowIds: ViewStore.RowId[] = [];\r\n const nGuids = 1000;\r\n for (let i = 0; i < nGuids; i++) {\r\n const guid = Guid.createValue();\r\n const rowId = vs1.addGuid(guid);\r\n guids.push(guid);\r\n rowIds.push(rowId);\r\n }\r\n for (let i = 0; i < nGuids; i++) {\r\n expect(vs1.getGuid(rowIds[i])).equals(guids[i]);\r\n expect(vs1.addGuid(guids[i])).equals(rowIds[i]);\r\n }\r\n\r\n let count = 0;\r\n vs1.iterateGuids(rowIds, (guid: GuidString, row: ViewStore.RowId) => {\r\n count++;\r\n expect(guid).not.undefined;\r\n expect(guids.indexOf(guid)).not.equals(-1);\r\n const rowString1 = ViewStore.fromRowId(row);\r\n expect(rowString1.startsWith(\"@\")).true;\r\n expect(ViewStore.toRowId(rowString1)).equals(row); // round trip\r\n });\r\n expect(count).equals(nGuids);\r\n\r\n const largeNumber = 0x7ffffffffffff;\r\n expect(ViewStore.toRowId(ViewStore.fromRowId(largeNumber))).equals(largeNumber);\r\n\r\n vs1.vacuum();\r\n });\r\n\r\n it(\"selector queries should skip undefined and null bindings\", async () => {\r\n const dbName = join(KnownTestLocations.outputDir, \"viewStoreBindings.db\");\r\n if (IModelJsFs.existsSync(dbName))\r\n IModelJsFs.removeSync(dbName);\r\n const snapshot = SnapshotDb.openFile(IModelTestUtils.resolveAssetFile(\"test.bim\"));\r\n const vs = new ViewStore.ViewDb({ guidMap: {} as any });\r\n try {\r\n ViewStore.ViewDb.createNewDb(dbName);\r\n vs.openDb(dbName, OpenMode.ReadWrite);\r\n vs.iModel = snapshot;\r\n\r\n const selectorId = await vs.addCategorySelector({ selector: { query: { from: \"BisCore:SpatialCategory\" } } });\r\n\r\n const baseline = vs.getCategorySelectorSync({ id: selectorId });\r\n expect(baseline.categories.length).greaterThan(0);\r\n\r\n // Undefined/null bindings not referenced by the query must be skipped (legacy ECSqlStatement.bindValues\r\n // semantics, per ViewStoreRpc.QueryBindings), not bound as NULL.\r\n const withUnusedUndefined = vs.getCategorySelectorSync({ id: selectorId, bindings: { parent: undefined } });\r\n expect(withUnusedUndefined.categories).deep.equal(baseline.categories);\r\n\r\n const withUnusedNull = vs.getCategorySelectorSync({ id: selectorId, bindings: { parent: null } });\r\n expect(withUnusedNull.categories).deep.equal(baseline.categories);\r\n } finally {\r\n if (vs.isOpen)\r\n vs.closeDb();\r\n if (snapshot.isOpen)\r\n snapshot.close();\r\n }\r\n });\r\n});\r\n"]}