@itwin/grouping-mapping-widget 0.8.2 → 0.8.3

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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=QueryBuilder.test.d.ts.map
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const QueryBuilder_1 = require("../widget/components/QueryBuilder");
8
+ const chai_1 = require("chai");
9
+ describe("QueryBuilder", () => {
10
+ describe("buildQueryString()", () => {
11
+ const testBuildQueryString = (query, expectedResult) => {
12
+ const sut = new QueryBuilder_1.QueryBuilder(undefined);
13
+ sut.query = query;
14
+ const result = sut.buildQueryString();
15
+ chai_1.assert.strictEqual(result, expectedResult);
16
+ };
17
+ it("should return empty string, when query is undefined", () => testBuildQueryString(undefined, ""));
18
+ it("should return empty string, when query unions are empty", () => testBuildQueryString({ unions: [] }, ""));
19
+ it("should return empty string, when query classes are empty", () => testBuildQueryString({ unions: [{ classes: [] }] }, ""));
20
+ it("should return query string with ROUND, when property is float", () => {
21
+ const baseClass = {
22
+ className: "BaseClassName",
23
+ isAspect: false,
24
+ isRelational: true,
25
+ properties: [],
26
+ };
27
+ const joinClass = {
28
+ className: "JoinClassName",
29
+ isAspect: false,
30
+ isRelational: true,
31
+ properties: [
32
+ {
33
+ name: "propName1",
34
+ needsQuote: false,
35
+ isCategory: false,
36
+ value: 3.14159,
37
+ },
38
+ ],
39
+ };
40
+ const query = {
41
+ unions: [
42
+ { classes: [baseClass, joinClass] },
43
+ ],
44
+ };
45
+ testBuildQueryString(query, "SELECT BaseClassName.ECInstanceId FROM BaseClassName JOIN JoinClassName ON ROUND(JoinClassName.propName1, 4)=3.1416");
46
+ });
47
+ it("should return query string with propery value in quotes, when property needs quotes", () => {
48
+ const baseClass = {
49
+ className: "BaseClassName",
50
+ isAspect: false,
51
+ isRelational: true,
52
+ properties: [],
53
+ };
54
+ const joinClass = {
55
+ className: "JoinClassName",
56
+ isAspect: false,
57
+ isRelational: true,
58
+ properties: [
59
+ {
60
+ name: "propName1",
61
+ needsQuote: true,
62
+ isCategory: false,
63
+ value: "someName",
64
+ },
65
+ ],
66
+ };
67
+ const query = {
68
+ unions: [
69
+ { classes: [baseClass, joinClass] },
70
+ ],
71
+ };
72
+ testBuildQueryString(query, "SELECT BaseClassName.ECInstanceId FROM BaseClassName JOIN JoinClassName ON JoinClassName.propName1='someName'");
73
+ });
74
+ it("should return a category query string, when property is category", () => {
75
+ const baseClass = {
76
+ className: "BaseClassName",
77
+ isAspect: false,
78
+ isRelational: true,
79
+ properties: [],
80
+ };
81
+ const joinClass = {
82
+ className: "JoinClassName",
83
+ isAspect: false,
84
+ isRelational: true,
85
+ properties: [
86
+ {
87
+ name: "propName1",
88
+ needsQuote: false,
89
+ isCategory: true,
90
+ value: "propValue1",
91
+ },
92
+ ],
93
+ };
94
+ const query = {
95
+ unions: [
96
+ { classes: [baseClass, joinClass] },
97
+ ],
98
+ };
99
+ testBuildQueryString(query, "SELECT BaseClassName.ECInstanceId FROM BaseClassName JOIN JoinClassName JOIN bis.Category ON bis.Category.ECInstanceId = bis.GeometricElement3d.category.id AND ((bis.Category.CodeValue='propValue1') OR (bis.Category.UserLabel='propValue1'))");
100
+ });
101
+ it("should return query string with where clause, when base class has properties", () => {
102
+ const baseClass = {
103
+ className: "BaseClassName",
104
+ isAspect: false,
105
+ isRelational: true,
106
+ properties: [
107
+ {
108
+ name: "propName1",
109
+ needsQuote: false,
110
+ isCategory: false,
111
+ value: "propValue1",
112
+ },
113
+ {
114
+ name: "propName2",
115
+ needsQuote: false,
116
+ isCategory: false,
117
+ value: "propValue2",
118
+ },
119
+ ],
120
+ };
121
+ const joinClass = {
122
+ className: "JoinClassName",
123
+ isAspect: false,
124
+ isRelational: true,
125
+ properties: [],
126
+ };
127
+ const query = {
128
+ unions: [
129
+ { classes: [baseClass, joinClass] },
130
+ ],
131
+ };
132
+ testBuildQueryString(query, "SELECT BaseClassName.ECInstanceId FROM BaseClassName JOIN JoinClassName WHERE BaseClassName.propName1=propValue1 AND BaseClassName.propName2=propValue2");
133
+ });
134
+ it("should return query string with UNION, when there are multiple unions", () => {
135
+ const queryClass = {
136
+ className: "ClassName",
137
+ isAspect: false,
138
+ isRelational: true,
139
+ properties: [
140
+ {
141
+ name: "propName1",
142
+ needsQuote: false,
143
+ isCategory: false,
144
+ value: "propValue1",
145
+ },
146
+ ],
147
+ };
148
+ const query = {
149
+ unions: [
150
+ { classes: [queryClass] },
151
+ { classes: [queryClass] },
152
+ ],
153
+ };
154
+ testBuildQueryString(query, "SELECT ClassName.ECInstanceId FROM ClassName WHERE ClassName.propName1=propValue1 UNION SELECT ClassName.ECInstanceId FROM ClassName WHERE ClassName.propName1=propValue1");
155
+ });
156
+ });
157
+ });
158
+ //# sourceMappingURL=QueryBuilder.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBuilder.test.js","sourceRoot":"","sources":["../../../src/test/QueryBuilder.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\nimport { QueryBuilder } from \"../widget/components/QueryBuilder\";\nimport type { Query, QueryClass } from \"../widget/components/QueryBuilder\";\nimport { assert } from \"chai\";\n\ndescribe(\"QueryBuilder\", () => {\n describe(\"buildQueryString()\", () => {\n\n const testBuildQueryString = (query: Query | undefined, expectedResult: string) => {\n const sut = new QueryBuilder(undefined);\n sut.query = query;\n const result = sut.buildQueryString();\n\n assert.strictEqual(result, expectedResult);\n };\n\n it(\"should return empty string, when query is undefined\", () => testBuildQueryString(undefined, \"\"));\n it(\"should return empty string, when query unions are empty\", () => testBuildQueryString({unions: []}, \"\"));\n it(\"should return empty string, when query classes are empty\", () => testBuildQueryString({unions: [{classes: []}]}, \"\"));\n\n it(\"should return query string with ROUND, when property is float\", () => {\n const baseClass: QueryClass = {\n className: \"BaseClassName\",\n isAspect: false,\n isRelational: true,\n properties: [],\n };\n\n const joinClass: QueryClass = {\n className: \"JoinClassName\",\n isAspect: false,\n isRelational: true,\n properties: [\n {\n name: \"propName1\",\n needsQuote: false,\n isCategory: false,\n value: 3.14159,\n },\n ],\n };\n\n const query: Query = {\n unions: [\n {classes: [baseClass, joinClass]},\n ],\n };\n\n testBuildQueryString(query, \"SELECT BaseClassName.ECInstanceId FROM BaseClassName JOIN JoinClassName ON ROUND(JoinClassName.propName1, 4)=3.1416\");\n });\n\n it(\"should return query string with propery value in quotes, when property needs quotes\", () => {\n const baseClass: QueryClass = {\n className: \"BaseClassName\",\n isAspect: false,\n isRelational: true,\n properties: [],\n };\n\n const joinClass: QueryClass = {\n className: \"JoinClassName\",\n isAspect: false,\n isRelational: true,\n properties: [\n {\n name: \"propName1\",\n needsQuote: true,\n isCategory: false,\n value: \"someName\",\n },\n ],\n };\n\n const query: Query = {\n unions: [\n {classes: [baseClass, joinClass]},\n ],\n };\n\n testBuildQueryString(query, \"SELECT BaseClassName.ECInstanceId FROM BaseClassName JOIN JoinClassName ON JoinClassName.propName1='someName'\");\n });\n\n it(\"should return a category query string, when property is category\", () => {\n const baseClass: QueryClass = {\n className: \"BaseClassName\",\n isAspect: false,\n isRelational: true,\n properties: [],\n };\n\n const joinClass: QueryClass = {\n className: \"JoinClassName\",\n isAspect: false,\n isRelational: true,\n properties: [\n {\n name: \"propName1\",\n needsQuote: false,\n isCategory: true,\n value: \"propValue1\",\n },\n ],\n };\n\n const query: Query = {\n unions: [\n {classes: [baseClass, joinClass]},\n ],\n };\n\n testBuildQueryString(query, \"SELECT BaseClassName.ECInstanceId FROM BaseClassName JOIN JoinClassName JOIN bis.Category ON bis.Category.ECInstanceId = bis.GeometricElement3d.category.id AND ((bis.Category.CodeValue='propValue1') OR (bis.Category.UserLabel='propValue1'))\");\n });\n\n it(\"should return query string with where clause, when base class has properties\", () => {\n const baseClass: QueryClass = {\n className: \"BaseClassName\",\n isAspect: false,\n isRelational: true,\n properties: [\n {\n name: \"propName1\",\n needsQuote: false,\n isCategory: false,\n value: \"propValue1\",\n },\n {\n name: \"propName2\",\n needsQuote: false,\n isCategory: false,\n value: \"propValue2\",\n },\n ],\n };\n\n const joinClass: QueryClass = {\n className: \"JoinClassName\",\n isAspect: false,\n isRelational: true,\n properties: [],\n };\n\n const query: Query = {\n unions: [\n {classes: [baseClass, joinClass]},\n ],\n };\n testBuildQueryString(query, \"SELECT BaseClassName.ECInstanceId FROM BaseClassName JOIN JoinClassName WHERE BaseClassName.propName1=propValue1 AND BaseClassName.propName2=propValue2\");\n });\n\n it(\"should return query string with UNION, when there are multiple unions\", () => {\n const queryClass: QueryClass = {\n className: \"ClassName\",\n isAspect: false,\n isRelational: true,\n properties: [\n {\n name: \"propName1\",\n needsQuote: false,\n isCategory: false,\n value: \"propValue1\",\n },\n ],\n };\n\n const query: Query = {\n unions: [\n {classes: [queryClass]},\n {classes: [queryClass]},\n ],\n };\n\n testBuildQueryString(query, \"SELECT ClassName.ECInstanceId FROM ClassName WHERE ClassName.propName1=propValue1 UNION SELECT ClassName.ECInstanceId FROM ClassName WHERE ClassName.propName1=propValue1\");\n });\n });\n});\n"]}
@@ -37,8 +37,10 @@ export declare class QueryBuilder {
37
37
  removeProperty(prop: PropertyRecord): Promise<void>;
38
38
  removeRelatedProperty(unionIndex: number, propertyField: PropertiesField, propertyName: string): void;
39
39
  removePropertyFromQuery(unionIndex: number, className: string, propertyName: string): void;
40
- categoryQuery(codeValue: string): string;
41
40
  buildQueryString(): string;
41
+ private _whereSegment;
42
+ private _propertySegment;
43
+ private _categoryQuery;
42
44
  private _isFloat;
43
45
  }
44
46
  //# sourceMappingURL=QueryBuilder.d.ts.map
@@ -9,6 +9,15 @@ class QueryBuilder {
9
9
  *
10
10
  */
11
11
  constructor(provider) {
12
+ this._whereSegment = (baseClass, baseClassName) => {
13
+ const segments = [];
14
+ const properties = baseClass.properties;
15
+ for (let i = 0; i < properties.length; i++) {
16
+ const prefix = i === 0 ? "WHERE" : "AND";
17
+ segments.push(this._propertySegment(baseClassName, properties[i], prefix));
18
+ }
19
+ return segments.join("");
20
+ };
12
21
  this.dataProvider = provider;
13
22
  }
14
23
  isCategory(propertyField) {
@@ -277,23 +286,22 @@ class QueryBuilder {
277
286
  }
278
287
  }
279
288
  }
280
- categoryQuery(codeValue) {
281
- return ` JOIN bis.Category ON bis.Category.ECInstanceId = bis.GeometricElement3d.category.id AND ((bis.Category.CodeValue='${codeValue}') OR (bis.Category.UserLabel='${codeValue}'))`;
282
- }
283
289
  buildQueryString() {
284
290
  if (this.query === undefined ||
285
291
  this.query.unions.length === 0 ||
286
292
  this.query.unions[0].classes.length === 0) {
287
293
  return "";
288
294
  }
289
- let unionQuery = "";
295
+ const unionSegments = [];
290
296
  for (const union of this.query.unions) {
297
+ const querySegments = [];
291
298
  const baseClass = union.classes[0];
292
299
  const baseClassName = baseClass.className;
293
300
  const baseIdName = baseClass.isAspect
294
301
  ? `${baseClassName}.Element.id`
295
302
  : `${baseClassName}.ECInstanceId`;
296
- let queryString = `SELECT ${baseIdName}${baseClass.isAspect ? " ECInstanceId" : ""} FROM ${baseClassName}`;
303
+ const selectSegment = `SELECT ${baseIdName}${baseClass.isAspect ? " ECInstanceId" : ""} FROM ${baseClassName}`;
304
+ querySegments.push(selectSegment);
297
305
  if (union.classes.length > 1) {
298
306
  for (let i = 1; i < union.classes.length; i++) {
299
307
  const joinClass = union.classes[i];
@@ -301,125 +309,51 @@ class QueryBuilder {
301
309
  const joinIdName = joinClass.isAspect
302
310
  ? `${joinClassName}.Element.id`
303
311
  : `${joinClassName}.ECInstanceId`;
304
- if (joinClass.isRelational) {
305
- queryString += ` JOIN ${joinClassName}`;
306
- if (joinClass.properties.length > 0) {
307
- if (joinClass.properties[0].isCategory) {
308
- queryString += this.categoryQuery(joinClass.properties[0].value.toString());
309
- }
310
- else {
311
- if (joinClass.properties[0].needsQuote) {
312
- queryString += ` ON ${joinClassName}.${joinClass.properties[0].name}='${joinClass.properties[0].value}'`;
313
- }
314
- else {
315
- if (this._isFloat(joinClass.properties[0].value)) {
316
- queryString += ` ON ROUND(${joinClassName}.${joinClass.properties[0].name}, `;
317
- queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;
318
- queryString += `${Number(joinClass.properties[0].value).toFixed(QueryBuilder.DEFAULT_DOUBLE_PRECISION)}`;
319
- }
320
- else {
321
- queryString += ` ON ${joinClassName}.${joinClass.properties[0].name}=${joinClass.properties[0].value}`;
322
- }
323
- }
324
- }
325
- }
326
- // when base is regular property, link base to first joined relational property
327
- if (!baseClass.isRelational && i === 1) {
328
- queryString += ` AND ${joinIdName} = ${baseIdName}`;
329
- }
330
- for (const property of joinClass.properties) {
331
- if (property.isCategory) {
332
- queryString += this.categoryQuery(property.value.toString());
333
- }
334
- else {
335
- if (property.needsQuote) {
336
- queryString += ` AND ${joinClassName}.${property.name}='${property.value}'`;
337
- }
338
- else {
339
- if (this._isFloat(property.value)) {
340
- queryString += ` AND ROUND(${joinClassName}.${property.name}, `;
341
- queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;
342
- queryString += `${Number(property.value).toFixed(QueryBuilder.DEFAULT_DOUBLE_PRECISION)}`;
343
- }
344
- else {
345
- queryString += ` AND ${joinClassName}.${property.name}=${property.value}`;
346
- }
347
- }
348
- }
349
- }
312
+ const joinSegment = joinClass.isRelational
313
+ ? ` JOIN ${joinClassName}`
314
+ : ` JOIN ${joinClassName} ON ${joinIdName} = ${baseIdName}`;
315
+ querySegments.push(joinSegment);
316
+ for (let j = 0; j < joinClass.properties.length; j++) {
317
+ const prefix = j === 0 && joinClass.isRelational ? "ON" : "AND";
318
+ const propertySegment = this._propertySegment(joinClassName, joinClass.properties[j], prefix);
319
+ querySegments.push(propertySegment);
350
320
  }
351
- else {
352
- queryString += ` JOIN ${joinClassName} ON ${joinIdName} = ${baseIdName}`;
353
- for (const property of joinClass.properties) {
354
- if (property.isCategory) {
355
- queryString += this.categoryQuery(property.value.toString());
356
- }
357
- else {
358
- if (property.needsQuote) {
359
- queryString += ` AND ${joinClassName}.${property.name}='${property.value}'`;
360
- }
361
- else {
362
- if (this._isFloat(property.value)) {
363
- queryString += ` AND ROUND(${joinClassName}.${property.name}, `;
364
- queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;
365
- queryString += `${Number(property.value).toFixed(QueryBuilder.DEFAULT_DOUBLE_PRECISION)}`;
366
- }
367
- else {
368
- queryString += ` AND ${joinClassName}.${property.name}=${property.value}`;
369
- }
370
- }
371
- }
372
- }
321
+ // when base is regular property, link base to first joined relational property
322
+ if (joinClass.isRelational && !baseClass.isRelational && i === 1) {
323
+ querySegments.push(` AND ${joinIdName} = ${baseIdName}`);
373
324
  }
374
325
  }
375
326
  }
376
- const properties = baseClass.properties;
377
- if (properties.length > 0) {
378
- if (properties[0].isCategory) {
379
- queryString += this.categoryQuery(properties[0].value.toString());
327
+ const whereSegment = this._whereSegment(baseClass, baseClassName);
328
+ querySegments.push(whereSegment);
329
+ unionSegments.push(querySegments.join(""));
330
+ }
331
+ return unionSegments.join(" UNION ");
332
+ }
333
+ _propertySegment(className, property, prefix) {
334
+ const segments = [];
335
+ if (property.isCategory) {
336
+ segments.push(this._categoryQuery(property.value.toString()));
337
+ }
338
+ else {
339
+ if (property.needsQuote) {
340
+ segments.push(` ${prefix} ${className}.${property.name}='${property.value}'`);
341
+ }
342
+ else {
343
+ if (this._isFloat(property.value)) {
344
+ segments.push(` ${prefix} ROUND(${className}.${property.name}, `);
345
+ segments.push(`${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`);
346
+ segments.push(`${Number(property.value).toFixed(QueryBuilder.DEFAULT_DOUBLE_PRECISION)}`);
380
347
  }
381
348
  else {
382
- if (properties[0].needsQuote) {
383
- queryString += ` WHERE ${baseClassName}.${properties[0].name}='${properties[0].value}'`;
384
- }
385
- else {
386
- if (this._isFloat(properties[0].value)) {
387
- queryString += ` WHERE ROUND(${baseClassName}.${properties[0].name}, `;
388
- queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;
389
- queryString += `${Number(properties[0].value).toFixed(QueryBuilder.DEFAULT_DOUBLE_PRECISION)}`;
390
- }
391
- else {
392
- queryString += ` WHERE ${baseClassName}.${properties[0].name}=${properties[0].value}`;
393
- }
394
- }
395
- }
396
- if (properties.length > 1) {
397
- for (let i = 1; i < properties.length; i++) {
398
- if (properties[i].isCategory) {
399
- queryString += this.categoryQuery(properties[i].value.toString());
400
- }
401
- else {
402
- if (properties[i].needsQuote) {
403
- queryString += ` AND ${baseClassName}.${properties[i].name}='${properties[i].value}'`;
404
- }
405
- else {
406
- if (this._isFloat(properties[i].value)) {
407
- queryString += ` AND ROUND(${baseClassName}.${properties[i].name}, `;
408
- queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;
409
- queryString += `${Number(properties[i].value).toFixed(QueryBuilder.DEFAULT_DOUBLE_PRECISION)}`;
410
- }
411
- else {
412
- queryString += ` AND ${baseClassName}.${properties[i].name}=${properties[i].value}`;
413
- }
414
- }
415
- }
416
- }
349
+ segments.push(` ${prefix} ${className}.${property.name}=${property.value}`);
417
350
  }
418
351
  }
419
- unionQuery += `${queryString} UNION `;
420
352
  }
421
- unionQuery = unionQuery.slice(0, unionQuery.length - 7);
422
- return unionQuery;
353
+ return segments.join("");
354
+ }
355
+ _categoryQuery(codeValue) {
356
+ return ` JOIN bis.Category ON bis.Category.ECInstanceId = bis.GeometricElement3d.category.id AND ((bis.Category.CodeValue='${codeValue}') OR (bis.Category.UserLabel='${codeValue}'))`;
423
357
  }
424
358
  _isFloat(n) {
425
359
  return Number(n) === n && n % 1 !== 0;
@@ -1 +1 @@
1
- {"version":3,"file":"QueryBuilder.js","sourceRoot":"","sources":["../../../../src/widget/components/QueryBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport type { PresentationPropertyDataProvider } from \"@itwin/presentation-components\";\nimport type {\n InstanceKey,\n PropertiesField,\n} from \"@itwin/presentation-common\";\nimport type { Primitives, PropertyRecord } from \"@itwin/appui-abstract\";\nimport { PropertyValueFormat } from \"@itwin/appui-abstract\";\nimport { toaster } from \"@itwin/itwinui-react\";\n\nexport interface Query {\n unions: QueryUnion[];\n}\n\nexport interface QueryUnion {\n classes: QueryClass[];\n}\n\nexport interface QueryClass {\n // schemaName.className\n className: string;\n properties: QueryProperty[];\n isAspect: boolean;\n isRelational?: boolean;\n}\n\nexport interface QueryProperty {\n name: string;\n value: Primitives.Value;\n needsQuote: boolean;\n isCategory: boolean;\n}\n\n/* This class is to build adaptive and dynamic query for find similar property selections */\nexport class QueryBuilder {\n public static readonly MULTI_ASPECT_PRIMARY_CLASS =\n \"BisCore:ElementOwnsMultiAspects\";\n public static readonly UNIQUE_ASPECT_PRIMARY_CLASS =\n \"BisCore:ElementOwnsUniqueAspect\";\n public static readonly DEFAULT_DOUBLE_PRECISION = 4;\n\n public dataProvider: PresentationPropertyDataProvider | undefined;\n public query: Query | undefined;\n\n /**\n *\n */\n constructor(provider: PresentationPropertyDataProvider | undefined) {\n this.dataProvider = provider;\n }\n\n public isCategory(propertyField: PropertiesField): boolean {\n const classInfo =\n propertyField.properties[0].property.navigationPropertyInfo?.classInfo;\n return classInfo?.name === \"BisCore:GeometricElement3dIsInCategory\";\n }\n\n public async addProperty(prop: PropertyRecord): Promise<boolean> {\n // TODO: only handle primitive properties now\n if (prop.value?.valueFormat !== PropertyValueFormat.Primitive) {\n toaster.warning(\"Only primitive types are supported for now.\");\n return false;\n }\n if (prop.value.value === undefined) {\n return false;\n }\n\n function replaceAll(str: string, match: string, replacement: string) {\n return str.split(match).join(replacement);\n }\n // if property value has single quote, escape\n if (\n (typeof prop.value.value === \"string\" ||\n prop.value.value instanceof String) &&\n String(prop.value.value).indexOf(\"'\") >= 0\n ) {\n prop.value.value = replaceAll(prop.value.value.toString(), \"'\", \"''\");\n }\n\n // get descriptor\n const descriptor = await this.dataProvider?.getContentDescriptor();\n const propertyField = (await this.dataProvider?.getFieldByPropertyRecord(\n prop,\n )) as PropertiesField;\n\n if (!descriptor || !propertyField) {\n toaster.negative(\n \"Error. Failed to fetch field for this property record.\",\n );\n return false;\n }\n\n // get the special cases\n const isNavigation: boolean =\n prop.property.typename.toLowerCase() === \"navigation\";\n const isCategory: boolean = isNavigation && this.isCategory(propertyField);\n const isAspect: boolean =\n propertyField.parent?.pathToPrimaryClass.find(\n (a) =>\n a.relationshipInfo?.name ===\n QueryBuilder.UNIQUE_ASPECT_PRIMARY_CLASS ||\n a.relationshipInfo?.name === QueryBuilder.MULTI_ASPECT_PRIMARY_CLASS,\n ) !== undefined;\n\n for (let i = 0; i < propertyField.properties.length; i++) {\n const className = propertyField.properties[\n i\n ].property.classInfo.name.replace(\":\", \".\");\n const propertyName = isNavigation\n ? isCategory\n ? `${propertyField.properties[i].property.name}.CodeValue`\n : `${propertyField.properties[i].property.name}.id`\n : propertyField.properties[i].property.name;\n const propertyValue = isNavigation\n ? isCategory\n ? prop.value.displayValue ?? \"\"\n : (prop.value.value as InstanceKey).id\n : prop.value.value;\n\n if (\n !isAspect &&\n propertyField.parent?.pathToPrimaryClass &&\n propertyField.parent?.pathToPrimaryClass.length > 0\n ) {\n this.addRelatedProperty(\n i,\n propertyField,\n propertyName,\n propertyValue,\n isAspect,\n );\n } else {\n this.addPropertyToQuery(\n i,\n className,\n propertyName,\n propertyValue,\n isAspect,\n this._needsQuote(propertyField),\n isCategory,\n false,\n );\n }\n }\n return true;\n }\n\n private _needsQuote(propertyField: PropertiesField): boolean {\n // list of property types that need quote around property value\n if (propertyField.type.typeName.toLowerCase() === \"string\") {\n return true;\n }\n if (propertyField.type.typeName.toLowerCase() === \"uri\") {\n return true;\n }\n return false;\n }\n\n public addRelatedProperty(\n unionIndex: number,\n propertyField: PropertiesField,\n propertyName: string,\n propertyValue: Primitives.Value,\n isAspect: boolean,\n ) {\n const paths = [...(propertyField.parent?.pathToPrimaryClass ?? [])];\n paths.reverse().forEach((path) => {\n const sourceClassName = path.sourceClassInfo?.name.replace(\":\", \".\");\n const targetClassName = path.targetClassInfo?.name.replace(\":\", \".\");\n const relClassName = path.relationshipInfo?.name.replace(\":\", \".\");\n if (!path.isForwardRelationship) {\n this.addPropertyToQuery(\n unionIndex,\n targetClassName,\n `ECInstanceId`,\n `${relClassName}.SourceECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n this.addPropertyToQuery(\n unionIndex,\n relClassName,\n `TargetECInstanceId`,\n `${sourceClassName}.ECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n if (\n path.sourceClassInfo?.name ===\n propertyField.parent?.contentClassInfo.name\n ) {\n this.addPropertyToQuery(\n unionIndex,\n sourceClassName,\n propertyName,\n propertyValue,\n isAspect,\n this._needsQuote(propertyField),\n false,\n true,\n );\n } else {\n this.addPropertyToQuery(\n unionIndex,\n sourceClassName,\n `ECInstanceId`,\n `${relClassName}.TargetECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n }\n } else {\n this.addPropertyToQuery(\n unionIndex,\n targetClassName,\n `ECInstanceId`,\n `${relClassName}.TargetECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n this.addPropertyToQuery(\n unionIndex,\n relClassName,\n `SourceECInstanceId`,\n `${sourceClassName}.ECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n if (\n path.sourceClassInfo?.name ===\n propertyField.parent?.contentClassInfo.name\n ) {\n this.addPropertyToQuery(\n unionIndex,\n sourceClassName,\n propertyName,\n propertyValue,\n isAspect,\n this._needsQuote(propertyField),\n false,\n true,\n );\n } else {\n this.addPropertyToQuery(\n unionIndex,\n sourceClassName,\n `ECInstanceId`,\n `${relClassName}.SourceECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n }\n }\n });\n }\n\n public addPropertyToQuery(\n unionIndex: number,\n className: string,\n propertyName: string,\n propertyValue: Primitives.Value,\n isAspect: boolean,\n needsQuote: boolean,\n isCategory: boolean,\n isRelational?: boolean,\n ) {\n if (this.query === undefined || this.query.unions.length === 0) {\n this.query = {\n unions: [\n {\n classes: [\n {\n className,\n isAspect,\n isRelational,\n properties: [\n {\n name: propertyName,\n value: propertyValue,\n needsQuote,\n isCategory,\n },\n ],\n },\n ],\n },\n ],\n };\n return;\n }\n\n if (this.query.unions.length <= unionIndex) {\n this.query.unions.push({\n classes: [\n {\n className,\n isAspect,\n isRelational,\n properties: [\n {\n name: propertyName,\n value: propertyValue,\n needsQuote,\n isCategory,\n },\n ],\n },\n ],\n });\n return;\n }\n\n const foundClass = this.query.unions[unionIndex].classes.find(\n (c) => c.className === className,\n );\n if (foundClass) {\n foundClass.isRelational = isRelational;\n if (!foundClass.properties.find((x) => x.name === propertyName)) {\n foundClass.properties.push({\n name: propertyName,\n value: propertyValue,\n needsQuote,\n isCategory,\n });\n }\n } else {\n this.query.unions[unionIndex].classes.push({\n className,\n isRelational,\n properties: [\n {\n name: propertyName,\n value: propertyValue,\n needsQuote,\n isCategory,\n },\n ],\n isAspect,\n });\n }\n }\n\n public async removeProperty(prop: PropertyRecord) {\n if (this.query === undefined || this.query.unions.length === 0) {\n return;\n }\n if (\n this.query.unions.length === 1 &&\n this.query.unions[0].classes.length === 0\n ) {\n return;\n }\n\n const descriptor = await this.dataProvider?.getContentDescriptor();\n const propertyField = (await this.dataProvider?.getFieldByPropertyRecord(\n prop,\n )) as PropertiesField;\n if (!descriptor || !propertyField) {\n return;\n }\n\n const isAspect: boolean =\n propertyField.parent?.pathToPrimaryClass.find(\n (a) =>\n a.relationshipInfo?.name ===\n QueryBuilder.UNIQUE_ASPECT_PRIMARY_CLASS ||\n a.relationshipInfo?.name === QueryBuilder.MULTI_ASPECT_PRIMARY_CLASS,\n ) !== undefined;\n const isNavigation: boolean =\n prop.property.typename.toLowerCase() === \"navigation\";\n const isCategory: boolean = isNavigation && this.isCategory(propertyField);\n\n for (let i = 0; i < propertyField.properties.length; i++) {\n const propertyName = isNavigation\n ? isCategory\n ? `${propertyField.properties[i].property.name}.CodeValue`\n : `${propertyField.properties[i].property.name}.id`\n : propertyField.properties[i].property.name;\n const className = propertyField.properties[\n i\n ].property.classInfo.name.replace(\":\", \".\");\n\n if (\n !isAspect &&\n propertyField.parent?.pathToPrimaryClass &&\n propertyField.parent?.pathToPrimaryClass.length > 0\n ) {\n this.removeRelatedProperty(i, propertyField, propertyName);\n } else {\n this.removePropertyFromQuery(i, className, propertyName);\n }\n }\n }\n\n public removeRelatedProperty(\n unionIndex: number,\n propertyField: PropertiesField,\n propertyName: string,\n ) {\n const paths = [...(propertyField.parent?.pathToPrimaryClass ?? [])];\n paths.reverse().forEach((path) => {\n const sourceClassName = path.sourceClassInfo?.name.replace(\":\", \".\");\n const targetClassName = path.targetClassInfo?.name.replace(\":\", \".\");\n const relClassName = path.relationshipInfo?.name.replace(\":\", \".\");\n if (!path.isForwardRelationship) {\n this.removePropertyFromQuery(\n unionIndex,\n targetClassName,\n `ECInstanceId`,\n );\n this.removePropertyFromQuery(\n unionIndex,\n relClassName,\n `TargetECInstanceId`,\n );\n if (\n path.sourceClassInfo?.name ===\n propertyField.parent?.contentClassInfo.name\n ) {\n this.removePropertyFromQuery(\n unionIndex,\n sourceClassName,\n propertyName,\n );\n } else {\n this.removePropertyFromQuery(\n unionIndex,\n sourceClassName,\n `ECInstanceId`,\n );\n }\n } else {\n this.removePropertyFromQuery(\n unionIndex,\n targetClassName,\n `ECInstanceId`,\n );\n this.removePropertyFromQuery(\n unionIndex,\n relClassName,\n `SourceECInstanceId`,\n );\n if (\n path.sourceClassInfo?.name ===\n propertyField.parent?.contentClassInfo.name\n ) {\n this.removePropertyFromQuery(\n unionIndex,\n sourceClassName,\n propertyName,\n );\n } else {\n this.removePropertyFromQuery(\n unionIndex,\n sourceClassName,\n `ECInstanceId`,\n );\n }\n }\n });\n }\n\n public removePropertyFromQuery(\n unionIndex: number,\n className: string,\n propertyName: string,\n ) {\n const foundClass = this.query?.unions[unionIndex].classes.find(\n (c) => c.className === className,\n );\n if (foundClass) {\n const foundPropertyIndex = foundClass.properties.findIndex(\n (p) => p.name === propertyName,\n );\n if (foundPropertyIndex > -1) {\n foundClass.properties.splice(foundPropertyIndex, 1);\n }\n if (foundClass.properties.length === 0) {\n // remove the entire class if all properties are removed\n const foundClassIndex =\n this.query?.unions[unionIndex].classes.findIndex(\n (c) => c.className === className,\n ) ?? -1;\n if (foundClassIndex > -1) {\n this.query?.unions[unionIndex].classes.splice(foundClassIndex, 1);\n }\n }\n }\n }\n\n public categoryQuery(codeValue: string): string {\n return ` JOIN bis.Category ON bis.Category.ECInstanceId = bis.GeometricElement3d.category.id AND ((bis.Category.CodeValue='${codeValue}') OR (bis.Category.UserLabel='${codeValue}'))`;\n }\n\n public buildQueryString() {\n if (\n this.query === undefined ||\n this.query.unions.length === 0 ||\n this.query.unions[0].classes.length === 0\n ) {\n return \"\";\n }\n\n let unionQuery = \"\";\n for (const union of this.query.unions) {\n const baseClass = union.classes[0];\n const baseClassName = baseClass.className;\n const baseIdName = baseClass.isAspect\n ? `${baseClassName}.Element.id`\n : `${baseClassName}.ECInstanceId`;\n\n let queryString = `SELECT ${baseIdName}${\n baseClass.isAspect ? \" ECInstanceId\" : \"\"\n } FROM ${baseClassName}`;\n\n if (union.classes.length > 1) {\n for (let i = 1; i < union.classes.length; i++) {\n const joinClass = union.classes[i];\n const joinClassName = joinClass.className;\n const joinIdName = joinClass.isAspect\n ? `${joinClassName}.Element.id`\n : `${joinClassName}.ECInstanceId`;\n\n if (joinClass.isRelational) {\n queryString += ` JOIN ${joinClassName}`;\n if (joinClass.properties.length > 0) {\n if (joinClass.properties[0].isCategory) {\n queryString += this.categoryQuery(\n joinClass.properties[0].value.toString(),\n );\n } else {\n if (joinClass.properties[0].needsQuote) {\n queryString += ` ON ${joinClassName}.${joinClass.properties[0].name}='${joinClass.properties[0].value}'`;\n } else {\n if (this._isFloat(joinClass.properties[0].value)) {\n queryString += ` ON ROUND(${joinClassName}.${joinClass.properties[0].name}, `;\n queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;\n queryString += `${Number(\n joinClass.properties[0].value,\n ).toFixed(QueryBuilder.DEFAULT_DOUBLE_PRECISION)}`;\n } else {\n queryString += ` ON ${joinClassName}.${joinClass.properties[0].name}=${joinClass.properties[0].value}`;\n }\n }\n }\n }\n // when base is regular property, link base to first joined relational property\n if (!baseClass.isRelational && i === 1) {\n queryString += ` AND ${joinIdName} = ${baseIdName}`;\n }\n for (const property of joinClass.properties) {\n if (property.isCategory) {\n queryString += this.categoryQuery(property.value.toString());\n } else {\n if (property.needsQuote) {\n queryString += ` AND ${joinClassName}.${property.name}='${property.value}'`;\n } else {\n if (this._isFloat(property.value)) {\n queryString += ` AND ROUND(${joinClassName}.${property.name}, `;\n queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;\n queryString += `${Number(property.value).toFixed(\n QueryBuilder.DEFAULT_DOUBLE_PRECISION,\n )}`;\n } else {\n queryString += ` AND ${joinClassName}.${property.name}=${property.value}`;\n }\n }\n }\n }\n } else {\n queryString += ` JOIN ${joinClassName} ON ${joinIdName} = ${baseIdName}`;\n for (const property of joinClass.properties) {\n if (property.isCategory) {\n queryString += this.categoryQuery(property.value.toString());\n } else {\n if (property.needsQuote) {\n queryString += ` AND ${joinClassName}.${property.name}='${property.value}'`;\n } else {\n if (this._isFloat(property.value)) {\n queryString += ` AND ROUND(${joinClassName}.${property.name}, `;\n queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;\n queryString += `${Number(property.value).toFixed(\n QueryBuilder.DEFAULT_DOUBLE_PRECISION,\n )}`;\n } else {\n queryString += ` AND ${joinClassName}.${property.name}=${property.value}`;\n }\n }\n }\n }\n }\n }\n }\n\n const properties = baseClass.properties;\n if (properties.length > 0) {\n if (properties[0].isCategory) {\n queryString += this.categoryQuery(properties[0].value.toString());\n } else {\n if (properties[0].needsQuote) {\n queryString += ` WHERE ${baseClassName}.${properties[0].name}='${properties[0].value}'`;\n } else {\n if (this._isFloat(properties[0].value)) {\n queryString += ` WHERE ROUND(${baseClassName}.${properties[0].name}, `;\n queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;\n queryString += `${Number(properties[0].value).toFixed(\n QueryBuilder.DEFAULT_DOUBLE_PRECISION,\n )}`;\n } else {\n queryString += ` WHERE ${baseClassName}.${properties[0].name}=${properties[0].value}`;\n }\n }\n }\n if (properties.length > 1) {\n for (let i = 1; i < properties.length; i++) {\n if (properties[i].isCategory) {\n queryString += this.categoryQuery(properties[i].value.toString());\n } else {\n if (properties[i].needsQuote) {\n queryString += ` AND ${baseClassName}.${properties[i].name}='${properties[i].value}'`;\n } else {\n if (this._isFloat(properties[i].value)) {\n queryString += ` AND ROUND(${baseClassName}.${properties[i].name}, `;\n queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;\n queryString += `${Number(properties[i].value).toFixed(\n QueryBuilder.DEFAULT_DOUBLE_PRECISION,\n )}`;\n } else {\n queryString += ` AND ${baseClassName}.${properties[i].name}=${properties[i].value}`;\n }\n }\n }\n }\n }\n }\n unionQuery += `${queryString} UNION `;\n }\n unionQuery = unionQuery.slice(0, unionQuery.length - 7);\n return unionQuery;\n }\n\n private _isFloat(n: unknown): boolean {\n return Number(n) === n && n % 1 !== 0;\n }\n}\n"]}
1
+ {"version":3,"file":"QueryBuilder.js","sourceRoot":"","sources":["../../../../src/widget/components/QueryBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport type { PresentationPropertyDataProvider } from \"@itwin/presentation-components\";\nimport type {\n InstanceKey,\n PropertiesField,\n} from \"@itwin/presentation-common\";\nimport type { Primitives, PropertyRecord } from \"@itwin/appui-abstract\";\nimport { PropertyValueFormat } from \"@itwin/appui-abstract\";\nimport { toaster } from \"@itwin/itwinui-react\";\n\nexport interface Query {\n unions: QueryUnion[];\n}\n\nexport interface QueryUnion {\n classes: QueryClass[];\n}\n\nexport interface QueryClass {\n // schemaName.className\n className: string;\n properties: QueryProperty[];\n isAspect: boolean;\n isRelational?: boolean;\n}\n\nexport interface QueryProperty {\n name: string;\n value: Primitives.Value;\n needsQuote: boolean;\n isCategory: boolean;\n}\n\n/* This class is to build adaptive and dynamic query for find similar property selections */\nexport class QueryBuilder {\n public static readonly MULTI_ASPECT_PRIMARY_CLASS =\n \"BisCore:ElementOwnsMultiAspects\";\n public static readonly UNIQUE_ASPECT_PRIMARY_CLASS =\n \"BisCore:ElementOwnsUniqueAspect\";\n public static readonly DEFAULT_DOUBLE_PRECISION = 4;\n\n public dataProvider: PresentationPropertyDataProvider | undefined;\n public query: Query | undefined;\n\n /**\n *\n */\n constructor(provider: PresentationPropertyDataProvider | undefined) {\n this.dataProvider = provider;\n }\n\n public isCategory(propertyField: PropertiesField): boolean {\n const classInfo =\n propertyField.properties[0].property.navigationPropertyInfo?.classInfo;\n return classInfo?.name === \"BisCore:GeometricElement3dIsInCategory\";\n }\n\n public async addProperty(prop: PropertyRecord): Promise<boolean> {\n // TODO: only handle primitive properties now\n if (prop.value?.valueFormat !== PropertyValueFormat.Primitive) {\n toaster.warning(\"Only primitive types are supported for now.\");\n return false;\n }\n if (prop.value.value === undefined) {\n return false;\n }\n\n function replaceAll(str: string, match: string, replacement: string) {\n return str.split(match).join(replacement);\n }\n // if property value has single quote, escape\n if (\n (typeof prop.value.value === \"string\" ||\n prop.value.value instanceof String) &&\n String(prop.value.value).indexOf(\"'\") >= 0\n ) {\n prop.value.value = replaceAll(prop.value.value.toString(), \"'\", \"''\");\n }\n\n // get descriptor\n const descriptor = await this.dataProvider?.getContentDescriptor();\n const propertyField = (await this.dataProvider?.getFieldByPropertyRecord(\n prop,\n )) as PropertiesField;\n\n if (!descriptor || !propertyField) {\n toaster.negative(\n \"Error. Failed to fetch field for this property record.\",\n );\n return false;\n }\n\n // get the special cases\n const isNavigation: boolean =\n prop.property.typename.toLowerCase() === \"navigation\";\n const isCategory: boolean = isNavigation && this.isCategory(propertyField);\n const isAspect: boolean =\n propertyField.parent?.pathToPrimaryClass.find(\n (a) =>\n a.relationshipInfo?.name ===\n QueryBuilder.UNIQUE_ASPECT_PRIMARY_CLASS ||\n a.relationshipInfo?.name === QueryBuilder.MULTI_ASPECT_PRIMARY_CLASS,\n ) !== undefined;\n\n for (let i = 0; i < propertyField.properties.length; i++) {\n const className = propertyField.properties[\n i\n ].property.classInfo.name.replace(\":\", \".\");\n const propertyName = isNavigation\n ? isCategory\n ? `${propertyField.properties[i].property.name}.CodeValue`\n : `${propertyField.properties[i].property.name}.id`\n : propertyField.properties[i].property.name;\n const propertyValue = isNavigation\n ? isCategory\n ? prop.value.displayValue ?? \"\"\n : (prop.value.value as InstanceKey).id\n : prop.value.value;\n\n if (\n !isAspect &&\n propertyField.parent?.pathToPrimaryClass &&\n propertyField.parent?.pathToPrimaryClass.length > 0\n ) {\n this.addRelatedProperty(\n i,\n propertyField,\n propertyName,\n propertyValue,\n isAspect,\n );\n } else {\n this.addPropertyToQuery(\n i,\n className,\n propertyName,\n propertyValue,\n isAspect,\n this._needsQuote(propertyField),\n isCategory,\n false,\n );\n }\n }\n return true;\n }\n\n private _needsQuote(propertyField: PropertiesField): boolean {\n // list of property types that need quote around property value\n if (propertyField.type.typeName.toLowerCase() === \"string\") {\n return true;\n }\n if (propertyField.type.typeName.toLowerCase() === \"uri\") {\n return true;\n }\n return false;\n }\n\n public addRelatedProperty(\n unionIndex: number,\n propertyField: PropertiesField,\n propertyName: string,\n propertyValue: Primitives.Value,\n isAspect: boolean,\n ) {\n const paths = [...(propertyField.parent?.pathToPrimaryClass ?? [])];\n paths.reverse().forEach((path) => {\n const sourceClassName = path.sourceClassInfo?.name.replace(\":\", \".\");\n const targetClassName = path.targetClassInfo?.name.replace(\":\", \".\");\n const relClassName = path.relationshipInfo?.name.replace(\":\", \".\");\n if (!path.isForwardRelationship) {\n this.addPropertyToQuery(\n unionIndex,\n targetClassName,\n `ECInstanceId`,\n `${relClassName}.SourceECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n this.addPropertyToQuery(\n unionIndex,\n relClassName,\n `TargetECInstanceId`,\n `${sourceClassName}.ECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n if (\n path.sourceClassInfo?.name ===\n propertyField.parent?.contentClassInfo.name\n ) {\n this.addPropertyToQuery(\n unionIndex,\n sourceClassName,\n propertyName,\n propertyValue,\n isAspect,\n this._needsQuote(propertyField),\n false,\n true,\n );\n } else {\n this.addPropertyToQuery(\n unionIndex,\n sourceClassName,\n `ECInstanceId`,\n `${relClassName}.TargetECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n }\n } else {\n this.addPropertyToQuery(\n unionIndex,\n targetClassName,\n `ECInstanceId`,\n `${relClassName}.TargetECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n this.addPropertyToQuery(\n unionIndex,\n relClassName,\n `SourceECInstanceId`,\n `${sourceClassName}.ECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n if (\n path.sourceClassInfo?.name ===\n propertyField.parent?.contentClassInfo.name\n ) {\n this.addPropertyToQuery(\n unionIndex,\n sourceClassName,\n propertyName,\n propertyValue,\n isAspect,\n this._needsQuote(propertyField),\n false,\n true,\n );\n } else {\n this.addPropertyToQuery(\n unionIndex,\n sourceClassName,\n `ECInstanceId`,\n `${relClassName}.SourceECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n }\n }\n });\n }\n\n public addPropertyToQuery(\n unionIndex: number,\n className: string,\n propertyName: string,\n propertyValue: Primitives.Value,\n isAspect: boolean,\n needsQuote: boolean,\n isCategory: boolean,\n isRelational?: boolean,\n ) {\n if (this.query === undefined || this.query.unions.length === 0) {\n this.query = {\n unions: [\n {\n classes: [\n {\n className,\n isAspect,\n isRelational,\n properties: [\n {\n name: propertyName,\n value: propertyValue,\n needsQuote,\n isCategory,\n },\n ],\n },\n ],\n },\n ],\n };\n return;\n }\n\n if (this.query.unions.length <= unionIndex) {\n this.query.unions.push({\n classes: [\n {\n className,\n isAspect,\n isRelational,\n properties: [\n {\n name: propertyName,\n value: propertyValue,\n needsQuote,\n isCategory,\n },\n ],\n },\n ],\n });\n return;\n }\n\n const foundClass = this.query.unions[unionIndex].classes.find(\n (c) => c.className === className,\n );\n if (foundClass) {\n foundClass.isRelational = isRelational;\n if (!foundClass.properties.find((x) => x.name === propertyName)) {\n foundClass.properties.push({\n name: propertyName,\n value: propertyValue,\n needsQuote,\n isCategory,\n });\n }\n } else {\n this.query.unions[unionIndex].classes.push({\n className,\n isRelational,\n properties: [\n {\n name: propertyName,\n value: propertyValue,\n needsQuote,\n isCategory,\n },\n ],\n isAspect,\n });\n }\n }\n\n public async removeProperty(prop: PropertyRecord) {\n if (this.query === undefined || this.query.unions.length === 0) {\n return;\n }\n if (\n this.query.unions.length === 1 &&\n this.query.unions[0].classes.length === 0\n ) {\n return;\n }\n\n const descriptor = await this.dataProvider?.getContentDescriptor();\n const propertyField = (await this.dataProvider?.getFieldByPropertyRecord(\n prop,\n )) as PropertiesField;\n if (!descriptor || !propertyField) {\n return;\n }\n\n const isAspect: boolean =\n propertyField.parent?.pathToPrimaryClass.find(\n (a) =>\n a.relationshipInfo?.name ===\n QueryBuilder.UNIQUE_ASPECT_PRIMARY_CLASS ||\n a.relationshipInfo?.name === QueryBuilder.MULTI_ASPECT_PRIMARY_CLASS,\n ) !== undefined;\n const isNavigation: boolean =\n prop.property.typename.toLowerCase() === \"navigation\";\n const isCategory: boolean = isNavigation && this.isCategory(propertyField);\n\n for (let i = 0; i < propertyField.properties.length; i++) {\n const propertyName = isNavigation\n ? isCategory\n ? `${propertyField.properties[i].property.name}.CodeValue`\n : `${propertyField.properties[i].property.name}.id`\n : propertyField.properties[i].property.name;\n const className = propertyField.properties[\n i\n ].property.classInfo.name.replace(\":\", \".\");\n\n if (\n !isAspect &&\n propertyField.parent?.pathToPrimaryClass &&\n propertyField.parent?.pathToPrimaryClass.length > 0\n ) {\n this.removeRelatedProperty(i, propertyField, propertyName);\n } else {\n this.removePropertyFromQuery(i, className, propertyName);\n }\n }\n }\n\n public removeRelatedProperty(\n unionIndex: number,\n propertyField: PropertiesField,\n propertyName: string,\n ) {\n const paths = [...(propertyField.parent?.pathToPrimaryClass ?? [])];\n paths.reverse().forEach((path) => {\n const sourceClassName = path.sourceClassInfo?.name.replace(\":\", \".\");\n const targetClassName = path.targetClassInfo?.name.replace(\":\", \".\");\n const relClassName = path.relationshipInfo?.name.replace(\":\", \".\");\n if (!path.isForwardRelationship) {\n this.removePropertyFromQuery(\n unionIndex,\n targetClassName,\n `ECInstanceId`,\n );\n this.removePropertyFromQuery(\n unionIndex,\n relClassName,\n `TargetECInstanceId`,\n );\n if (\n path.sourceClassInfo?.name ===\n propertyField.parent?.contentClassInfo.name\n ) {\n this.removePropertyFromQuery(\n unionIndex,\n sourceClassName,\n propertyName,\n );\n } else {\n this.removePropertyFromQuery(\n unionIndex,\n sourceClassName,\n `ECInstanceId`,\n );\n }\n } else {\n this.removePropertyFromQuery(\n unionIndex,\n targetClassName,\n `ECInstanceId`,\n );\n this.removePropertyFromQuery(\n unionIndex,\n relClassName,\n `SourceECInstanceId`,\n );\n if (\n path.sourceClassInfo?.name ===\n propertyField.parent?.contentClassInfo.name\n ) {\n this.removePropertyFromQuery(\n unionIndex,\n sourceClassName,\n propertyName,\n );\n } else {\n this.removePropertyFromQuery(\n unionIndex,\n sourceClassName,\n `ECInstanceId`,\n );\n }\n }\n });\n }\n\n public removePropertyFromQuery(\n unionIndex: number,\n className: string,\n propertyName: string,\n ) {\n const foundClass = this.query?.unions[unionIndex].classes.find(\n (c) => c.className === className,\n );\n if (foundClass) {\n const foundPropertyIndex = foundClass.properties.findIndex(\n (p) => p.name === propertyName,\n );\n if (foundPropertyIndex > -1) {\n foundClass.properties.splice(foundPropertyIndex, 1);\n }\n if (foundClass.properties.length === 0) {\n // remove the entire class if all properties are removed\n const foundClassIndex =\n this.query?.unions[unionIndex].classes.findIndex(\n (c) => c.className === className,\n ) ?? -1;\n if (foundClassIndex > -1) {\n this.query?.unions[unionIndex].classes.splice(foundClassIndex, 1);\n }\n }\n }\n }\n\n public buildQueryString() {\n if (\n this.query === undefined ||\n this.query.unions.length === 0 ||\n this.query.unions[0].classes.length === 0\n ) {\n return \"\";\n }\n\n const unionSegments: string[] = [];\n for (const union of this.query.unions) {\n const querySegments: string[] = [];\n\n const baseClass = union.classes[0];\n const baseClassName = baseClass.className;\n const baseIdName = baseClass.isAspect\n ? `${baseClassName}.Element.id`\n : `${baseClassName}.ECInstanceId`;\n\n const selectSegment = `SELECT ${baseIdName}${baseClass.isAspect ? \" ECInstanceId\" : \"\"} FROM ${baseClassName}`;\n querySegments.push(selectSegment);\n\n if (union.classes.length > 1) {\n for (let i = 1; i < union.classes.length; i++) {\n const joinClass = union.classes[i];\n const joinClassName = joinClass.className;\n const joinIdName = joinClass.isAspect\n ? `${joinClassName}.Element.id`\n : `${joinClassName}.ECInstanceId`;\n\n const joinSegment = joinClass.isRelational\n ? ` JOIN ${joinClassName}`\n : ` JOIN ${joinClassName} ON ${joinIdName} = ${baseIdName}`;\n querySegments.push(joinSegment);\n\n for (let j = 0; j < joinClass.properties.length; j++) {\n const prefix = j === 0 && joinClass.isRelational ? \"ON\" : \"AND\";\n const propertySegment = this._propertySegment(joinClassName, joinClass.properties[j], prefix);\n querySegments.push(propertySegment);\n }\n // when base is regular property, link base to first joined relational property\n if (joinClass.isRelational && !baseClass.isRelational && i === 1) {\n querySegments.push(` AND ${joinIdName} = ${baseIdName}`);\n }\n }\n }\n\n const whereSegment = this._whereSegment(baseClass, baseClassName);\n querySegments.push(whereSegment);\n\n unionSegments.push(querySegments.join(\"\"));\n }\n\n return unionSegments.join(\" UNION \");\n }\n\n private _whereSegment = (\n baseClass: QueryClass,\n baseClassName: string\n ): string => {\n const segments: string[] = [];\n\n const properties = baseClass.properties;\n for (let i = 0; i < properties.length; i++) {\n const prefix = i === 0 ? \"WHERE\" : \"AND\";\n segments.push(this._propertySegment(baseClassName, properties[i], prefix));\n }\n\n return segments.join(\"\");\n }\n\n private _propertySegment(\n className: string,\n property: QueryProperty,\n prefix: string\n ): string {\n const segments: string[] = [];\n\n if (property.isCategory) {\n segments.push(this._categoryQuery(property.value.toString()));\n } else {\n if (property.needsQuote) {\n segments.push(` ${prefix} ${className}.${property.name}='${property.value}'`);\n } else {\n if (this._isFloat(property.value)) {\n segments.push(` ${prefix} ROUND(${className}.${property.name}, `);\n segments.push(`${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`);\n segments.push(`${Number(property.value).toFixed(\n QueryBuilder.DEFAULT_DOUBLE_PRECISION\n )}`);\n } else {\n segments.push(` ${prefix} ${className}.${property.name}=${property.value}`);\n }\n }\n }\n\n return segments.join(\"\");\n }\n\n private _categoryQuery(codeValue: string): string {\n return ` JOIN bis.Category ON bis.Category.ECInstanceId = bis.GeometricElement3d.category.id AND ((bis.Category.CodeValue='${codeValue}') OR (bis.Category.UserLabel='${codeValue}'))`;\n }\n\n private _isFloat(n: unknown): boolean {\n return Number(n) === n && n % 1 !== 0;\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=QueryBuilder.test.d.ts.map
@@ -0,0 +1,156 @@
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
+ import { QueryBuilder } from "../widget/components/QueryBuilder";
6
+ import { assert } from "chai";
7
+ describe("QueryBuilder", () => {
8
+ describe("buildQueryString()", () => {
9
+ const testBuildQueryString = (query, expectedResult) => {
10
+ const sut = new QueryBuilder(undefined);
11
+ sut.query = query;
12
+ const result = sut.buildQueryString();
13
+ assert.strictEqual(result, expectedResult);
14
+ };
15
+ it("should return empty string, when query is undefined", () => testBuildQueryString(undefined, ""));
16
+ it("should return empty string, when query unions are empty", () => testBuildQueryString({ unions: [] }, ""));
17
+ it("should return empty string, when query classes are empty", () => testBuildQueryString({ unions: [{ classes: [] }] }, ""));
18
+ it("should return query string with ROUND, when property is float", () => {
19
+ const baseClass = {
20
+ className: "BaseClassName",
21
+ isAspect: false,
22
+ isRelational: true,
23
+ properties: [],
24
+ };
25
+ const joinClass = {
26
+ className: "JoinClassName",
27
+ isAspect: false,
28
+ isRelational: true,
29
+ properties: [
30
+ {
31
+ name: "propName1",
32
+ needsQuote: false,
33
+ isCategory: false,
34
+ value: 3.14159,
35
+ },
36
+ ],
37
+ };
38
+ const query = {
39
+ unions: [
40
+ { classes: [baseClass, joinClass] },
41
+ ],
42
+ };
43
+ testBuildQueryString(query, "SELECT BaseClassName.ECInstanceId FROM BaseClassName JOIN JoinClassName ON ROUND(JoinClassName.propName1, 4)=3.1416");
44
+ });
45
+ it("should return query string with propery value in quotes, when property needs quotes", () => {
46
+ const baseClass = {
47
+ className: "BaseClassName",
48
+ isAspect: false,
49
+ isRelational: true,
50
+ properties: [],
51
+ };
52
+ const joinClass = {
53
+ className: "JoinClassName",
54
+ isAspect: false,
55
+ isRelational: true,
56
+ properties: [
57
+ {
58
+ name: "propName1",
59
+ needsQuote: true,
60
+ isCategory: false,
61
+ value: "someName",
62
+ },
63
+ ],
64
+ };
65
+ const query = {
66
+ unions: [
67
+ { classes: [baseClass, joinClass] },
68
+ ],
69
+ };
70
+ testBuildQueryString(query, "SELECT BaseClassName.ECInstanceId FROM BaseClassName JOIN JoinClassName ON JoinClassName.propName1='someName'");
71
+ });
72
+ it("should return a category query string, when property is category", () => {
73
+ const baseClass = {
74
+ className: "BaseClassName",
75
+ isAspect: false,
76
+ isRelational: true,
77
+ properties: [],
78
+ };
79
+ const joinClass = {
80
+ className: "JoinClassName",
81
+ isAspect: false,
82
+ isRelational: true,
83
+ properties: [
84
+ {
85
+ name: "propName1",
86
+ needsQuote: false,
87
+ isCategory: true,
88
+ value: "propValue1",
89
+ },
90
+ ],
91
+ };
92
+ const query = {
93
+ unions: [
94
+ { classes: [baseClass, joinClass] },
95
+ ],
96
+ };
97
+ testBuildQueryString(query, "SELECT BaseClassName.ECInstanceId FROM BaseClassName JOIN JoinClassName JOIN bis.Category ON bis.Category.ECInstanceId = bis.GeometricElement3d.category.id AND ((bis.Category.CodeValue='propValue1') OR (bis.Category.UserLabel='propValue1'))");
98
+ });
99
+ it("should return query string with where clause, when base class has properties", () => {
100
+ const baseClass = {
101
+ className: "BaseClassName",
102
+ isAspect: false,
103
+ isRelational: true,
104
+ properties: [
105
+ {
106
+ name: "propName1",
107
+ needsQuote: false,
108
+ isCategory: false,
109
+ value: "propValue1",
110
+ },
111
+ {
112
+ name: "propName2",
113
+ needsQuote: false,
114
+ isCategory: false,
115
+ value: "propValue2",
116
+ },
117
+ ],
118
+ };
119
+ const joinClass = {
120
+ className: "JoinClassName",
121
+ isAspect: false,
122
+ isRelational: true,
123
+ properties: [],
124
+ };
125
+ const query = {
126
+ unions: [
127
+ { classes: [baseClass, joinClass] },
128
+ ],
129
+ };
130
+ testBuildQueryString(query, "SELECT BaseClassName.ECInstanceId FROM BaseClassName JOIN JoinClassName WHERE BaseClassName.propName1=propValue1 AND BaseClassName.propName2=propValue2");
131
+ });
132
+ it("should return query string with UNION, when there are multiple unions", () => {
133
+ const queryClass = {
134
+ className: "ClassName",
135
+ isAspect: false,
136
+ isRelational: true,
137
+ properties: [
138
+ {
139
+ name: "propName1",
140
+ needsQuote: false,
141
+ isCategory: false,
142
+ value: "propValue1",
143
+ },
144
+ ],
145
+ };
146
+ const query = {
147
+ unions: [
148
+ { classes: [queryClass] },
149
+ { classes: [queryClass] },
150
+ ],
151
+ };
152
+ testBuildQueryString(query, "SELECT ClassName.ECInstanceId FROM ClassName WHERE ClassName.propName1=propValue1 UNION SELECT ClassName.ECInstanceId FROM ClassName WHERE ClassName.propName1=propValue1");
153
+ });
154
+ });
155
+ });
156
+ //# sourceMappingURL=QueryBuilder.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBuilder.test.js","sourceRoot":"","sources":["../../../src/test/QueryBuilder.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\nimport { QueryBuilder } from \"../widget/components/QueryBuilder\";\nimport type { Query, QueryClass } from \"../widget/components/QueryBuilder\";\nimport { assert } from \"chai\";\n\ndescribe(\"QueryBuilder\", () => {\n describe(\"buildQueryString()\", () => {\n\n const testBuildQueryString = (query: Query | undefined, expectedResult: string) => {\n const sut = new QueryBuilder(undefined);\n sut.query = query;\n const result = sut.buildQueryString();\n\n assert.strictEqual(result, expectedResult);\n };\n\n it(\"should return empty string, when query is undefined\", () => testBuildQueryString(undefined, \"\"));\n it(\"should return empty string, when query unions are empty\", () => testBuildQueryString({unions: []}, \"\"));\n it(\"should return empty string, when query classes are empty\", () => testBuildQueryString({unions: [{classes: []}]}, \"\"));\n\n it(\"should return query string with ROUND, when property is float\", () => {\n const baseClass: QueryClass = {\n className: \"BaseClassName\",\n isAspect: false,\n isRelational: true,\n properties: [],\n };\n\n const joinClass: QueryClass = {\n className: \"JoinClassName\",\n isAspect: false,\n isRelational: true,\n properties: [\n {\n name: \"propName1\",\n needsQuote: false,\n isCategory: false,\n value: 3.14159,\n },\n ],\n };\n\n const query: Query = {\n unions: [\n {classes: [baseClass, joinClass]},\n ],\n };\n\n testBuildQueryString(query, \"SELECT BaseClassName.ECInstanceId FROM BaseClassName JOIN JoinClassName ON ROUND(JoinClassName.propName1, 4)=3.1416\");\n });\n\n it(\"should return query string with propery value in quotes, when property needs quotes\", () => {\n const baseClass: QueryClass = {\n className: \"BaseClassName\",\n isAspect: false,\n isRelational: true,\n properties: [],\n };\n\n const joinClass: QueryClass = {\n className: \"JoinClassName\",\n isAspect: false,\n isRelational: true,\n properties: [\n {\n name: \"propName1\",\n needsQuote: true,\n isCategory: false,\n value: \"someName\",\n },\n ],\n };\n\n const query: Query = {\n unions: [\n {classes: [baseClass, joinClass]},\n ],\n };\n\n testBuildQueryString(query, \"SELECT BaseClassName.ECInstanceId FROM BaseClassName JOIN JoinClassName ON JoinClassName.propName1='someName'\");\n });\n\n it(\"should return a category query string, when property is category\", () => {\n const baseClass: QueryClass = {\n className: \"BaseClassName\",\n isAspect: false,\n isRelational: true,\n properties: [],\n };\n\n const joinClass: QueryClass = {\n className: \"JoinClassName\",\n isAspect: false,\n isRelational: true,\n properties: [\n {\n name: \"propName1\",\n needsQuote: false,\n isCategory: true,\n value: \"propValue1\",\n },\n ],\n };\n\n const query: Query = {\n unions: [\n {classes: [baseClass, joinClass]},\n ],\n };\n\n testBuildQueryString(query, \"SELECT BaseClassName.ECInstanceId FROM BaseClassName JOIN JoinClassName JOIN bis.Category ON bis.Category.ECInstanceId = bis.GeometricElement3d.category.id AND ((bis.Category.CodeValue='propValue1') OR (bis.Category.UserLabel='propValue1'))\");\n });\n\n it(\"should return query string with where clause, when base class has properties\", () => {\n const baseClass: QueryClass = {\n className: \"BaseClassName\",\n isAspect: false,\n isRelational: true,\n properties: [\n {\n name: \"propName1\",\n needsQuote: false,\n isCategory: false,\n value: \"propValue1\",\n },\n {\n name: \"propName2\",\n needsQuote: false,\n isCategory: false,\n value: \"propValue2\",\n },\n ],\n };\n\n const joinClass: QueryClass = {\n className: \"JoinClassName\",\n isAspect: false,\n isRelational: true,\n properties: [],\n };\n\n const query: Query = {\n unions: [\n {classes: [baseClass, joinClass]},\n ],\n };\n testBuildQueryString(query, \"SELECT BaseClassName.ECInstanceId FROM BaseClassName JOIN JoinClassName WHERE BaseClassName.propName1=propValue1 AND BaseClassName.propName2=propValue2\");\n });\n\n it(\"should return query string with UNION, when there are multiple unions\", () => {\n const queryClass: QueryClass = {\n className: \"ClassName\",\n isAspect: false,\n isRelational: true,\n properties: [\n {\n name: \"propName1\",\n needsQuote: false,\n isCategory: false,\n value: \"propValue1\",\n },\n ],\n };\n\n const query: Query = {\n unions: [\n {classes: [queryClass]},\n {classes: [queryClass]},\n ],\n };\n\n testBuildQueryString(query, \"SELECT ClassName.ECInstanceId FROM ClassName WHERE ClassName.propName1=propValue1 UNION SELECT ClassName.ECInstanceId FROM ClassName WHERE ClassName.propName1=propValue1\");\n });\n });\n});\n"]}
@@ -37,8 +37,10 @@ export declare class QueryBuilder {
37
37
  removeProperty(prop: PropertyRecord): Promise<void>;
38
38
  removeRelatedProperty(unionIndex: number, propertyField: PropertiesField, propertyName: string): void;
39
39
  removePropertyFromQuery(unionIndex: number, className: string, propertyName: string): void;
40
- categoryQuery(codeValue: string): string;
41
40
  buildQueryString(): string;
41
+ private _whereSegment;
42
+ private _propertySegment;
43
+ private _categoryQuery;
42
44
  private _isFloat;
43
45
  }
44
46
  //# sourceMappingURL=QueryBuilder.d.ts.map
@@ -6,6 +6,15 @@ export class QueryBuilder {
6
6
  *
7
7
  */
8
8
  constructor(provider) {
9
+ this._whereSegment = (baseClass, baseClassName) => {
10
+ const segments = [];
11
+ const properties = baseClass.properties;
12
+ for (let i = 0; i < properties.length; i++) {
13
+ const prefix = i === 0 ? "WHERE" : "AND";
14
+ segments.push(this._propertySegment(baseClassName, properties[i], prefix));
15
+ }
16
+ return segments.join("");
17
+ };
9
18
  this.dataProvider = provider;
10
19
  }
11
20
  isCategory(propertyField) {
@@ -274,23 +283,22 @@ export class QueryBuilder {
274
283
  }
275
284
  }
276
285
  }
277
- categoryQuery(codeValue) {
278
- return ` JOIN bis.Category ON bis.Category.ECInstanceId = bis.GeometricElement3d.category.id AND ((bis.Category.CodeValue='${codeValue}') OR (bis.Category.UserLabel='${codeValue}'))`;
279
- }
280
286
  buildQueryString() {
281
287
  if (this.query === undefined ||
282
288
  this.query.unions.length === 0 ||
283
289
  this.query.unions[0].classes.length === 0) {
284
290
  return "";
285
291
  }
286
- let unionQuery = "";
292
+ const unionSegments = [];
287
293
  for (const union of this.query.unions) {
294
+ const querySegments = [];
288
295
  const baseClass = union.classes[0];
289
296
  const baseClassName = baseClass.className;
290
297
  const baseIdName = baseClass.isAspect
291
298
  ? `${baseClassName}.Element.id`
292
299
  : `${baseClassName}.ECInstanceId`;
293
- let queryString = `SELECT ${baseIdName}${baseClass.isAspect ? " ECInstanceId" : ""} FROM ${baseClassName}`;
300
+ const selectSegment = `SELECT ${baseIdName}${baseClass.isAspect ? " ECInstanceId" : ""} FROM ${baseClassName}`;
301
+ querySegments.push(selectSegment);
294
302
  if (union.classes.length > 1) {
295
303
  for (let i = 1; i < union.classes.length; i++) {
296
304
  const joinClass = union.classes[i];
@@ -298,125 +306,51 @@ export class QueryBuilder {
298
306
  const joinIdName = joinClass.isAspect
299
307
  ? `${joinClassName}.Element.id`
300
308
  : `${joinClassName}.ECInstanceId`;
301
- if (joinClass.isRelational) {
302
- queryString += ` JOIN ${joinClassName}`;
303
- if (joinClass.properties.length > 0) {
304
- if (joinClass.properties[0].isCategory) {
305
- queryString += this.categoryQuery(joinClass.properties[0].value.toString());
306
- }
307
- else {
308
- if (joinClass.properties[0].needsQuote) {
309
- queryString += ` ON ${joinClassName}.${joinClass.properties[0].name}='${joinClass.properties[0].value}'`;
310
- }
311
- else {
312
- if (this._isFloat(joinClass.properties[0].value)) {
313
- queryString += ` ON ROUND(${joinClassName}.${joinClass.properties[0].name}, `;
314
- queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;
315
- queryString += `${Number(joinClass.properties[0].value).toFixed(QueryBuilder.DEFAULT_DOUBLE_PRECISION)}`;
316
- }
317
- else {
318
- queryString += ` ON ${joinClassName}.${joinClass.properties[0].name}=${joinClass.properties[0].value}`;
319
- }
320
- }
321
- }
322
- }
323
- // when base is regular property, link base to first joined relational property
324
- if (!baseClass.isRelational && i === 1) {
325
- queryString += ` AND ${joinIdName} = ${baseIdName}`;
326
- }
327
- for (const property of joinClass.properties) {
328
- if (property.isCategory) {
329
- queryString += this.categoryQuery(property.value.toString());
330
- }
331
- else {
332
- if (property.needsQuote) {
333
- queryString += ` AND ${joinClassName}.${property.name}='${property.value}'`;
334
- }
335
- else {
336
- if (this._isFloat(property.value)) {
337
- queryString += ` AND ROUND(${joinClassName}.${property.name}, `;
338
- queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;
339
- queryString += `${Number(property.value).toFixed(QueryBuilder.DEFAULT_DOUBLE_PRECISION)}`;
340
- }
341
- else {
342
- queryString += ` AND ${joinClassName}.${property.name}=${property.value}`;
343
- }
344
- }
345
- }
346
- }
309
+ const joinSegment = joinClass.isRelational
310
+ ? ` JOIN ${joinClassName}`
311
+ : ` JOIN ${joinClassName} ON ${joinIdName} = ${baseIdName}`;
312
+ querySegments.push(joinSegment);
313
+ for (let j = 0; j < joinClass.properties.length; j++) {
314
+ const prefix = j === 0 && joinClass.isRelational ? "ON" : "AND";
315
+ const propertySegment = this._propertySegment(joinClassName, joinClass.properties[j], prefix);
316
+ querySegments.push(propertySegment);
347
317
  }
348
- else {
349
- queryString += ` JOIN ${joinClassName} ON ${joinIdName} = ${baseIdName}`;
350
- for (const property of joinClass.properties) {
351
- if (property.isCategory) {
352
- queryString += this.categoryQuery(property.value.toString());
353
- }
354
- else {
355
- if (property.needsQuote) {
356
- queryString += ` AND ${joinClassName}.${property.name}='${property.value}'`;
357
- }
358
- else {
359
- if (this._isFloat(property.value)) {
360
- queryString += ` AND ROUND(${joinClassName}.${property.name}, `;
361
- queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;
362
- queryString += `${Number(property.value).toFixed(QueryBuilder.DEFAULT_DOUBLE_PRECISION)}`;
363
- }
364
- else {
365
- queryString += ` AND ${joinClassName}.${property.name}=${property.value}`;
366
- }
367
- }
368
- }
369
- }
318
+ // when base is regular property, link base to first joined relational property
319
+ if (joinClass.isRelational && !baseClass.isRelational && i === 1) {
320
+ querySegments.push(` AND ${joinIdName} = ${baseIdName}`);
370
321
  }
371
322
  }
372
323
  }
373
- const properties = baseClass.properties;
374
- if (properties.length > 0) {
375
- if (properties[0].isCategory) {
376
- queryString += this.categoryQuery(properties[0].value.toString());
324
+ const whereSegment = this._whereSegment(baseClass, baseClassName);
325
+ querySegments.push(whereSegment);
326
+ unionSegments.push(querySegments.join(""));
327
+ }
328
+ return unionSegments.join(" UNION ");
329
+ }
330
+ _propertySegment(className, property, prefix) {
331
+ const segments = [];
332
+ if (property.isCategory) {
333
+ segments.push(this._categoryQuery(property.value.toString()));
334
+ }
335
+ else {
336
+ if (property.needsQuote) {
337
+ segments.push(` ${prefix} ${className}.${property.name}='${property.value}'`);
338
+ }
339
+ else {
340
+ if (this._isFloat(property.value)) {
341
+ segments.push(` ${prefix} ROUND(${className}.${property.name}, `);
342
+ segments.push(`${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`);
343
+ segments.push(`${Number(property.value).toFixed(QueryBuilder.DEFAULT_DOUBLE_PRECISION)}`);
377
344
  }
378
345
  else {
379
- if (properties[0].needsQuote) {
380
- queryString += ` WHERE ${baseClassName}.${properties[0].name}='${properties[0].value}'`;
381
- }
382
- else {
383
- if (this._isFloat(properties[0].value)) {
384
- queryString += ` WHERE ROUND(${baseClassName}.${properties[0].name}, `;
385
- queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;
386
- queryString += `${Number(properties[0].value).toFixed(QueryBuilder.DEFAULT_DOUBLE_PRECISION)}`;
387
- }
388
- else {
389
- queryString += ` WHERE ${baseClassName}.${properties[0].name}=${properties[0].value}`;
390
- }
391
- }
392
- }
393
- if (properties.length > 1) {
394
- for (let i = 1; i < properties.length; i++) {
395
- if (properties[i].isCategory) {
396
- queryString += this.categoryQuery(properties[i].value.toString());
397
- }
398
- else {
399
- if (properties[i].needsQuote) {
400
- queryString += ` AND ${baseClassName}.${properties[i].name}='${properties[i].value}'`;
401
- }
402
- else {
403
- if (this._isFloat(properties[i].value)) {
404
- queryString += ` AND ROUND(${baseClassName}.${properties[i].name}, `;
405
- queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;
406
- queryString += `${Number(properties[i].value).toFixed(QueryBuilder.DEFAULT_DOUBLE_PRECISION)}`;
407
- }
408
- else {
409
- queryString += ` AND ${baseClassName}.${properties[i].name}=${properties[i].value}`;
410
- }
411
- }
412
- }
413
- }
346
+ segments.push(` ${prefix} ${className}.${property.name}=${property.value}`);
414
347
  }
415
348
  }
416
- unionQuery += `${queryString} UNION `;
417
349
  }
418
- unionQuery = unionQuery.slice(0, unionQuery.length - 7);
419
- return unionQuery;
350
+ return segments.join("");
351
+ }
352
+ _categoryQuery(codeValue) {
353
+ return ` JOIN bis.Category ON bis.Category.ECInstanceId = bis.GeometricElement3d.category.id AND ((bis.Category.CodeValue='${codeValue}') OR (bis.Category.UserLabel='${codeValue}'))`;
420
354
  }
421
355
  _isFloat(n) {
422
356
  return Number(n) === n && n % 1 !== 0;
@@ -1 +1 @@
1
- {"version":3,"file":"QueryBuilder.js","sourceRoot":"","sources":["../../../../src/widget/components/QueryBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport type { PresentationPropertyDataProvider } from \"@itwin/presentation-components\";\nimport type {\n InstanceKey,\n PropertiesField,\n} from \"@itwin/presentation-common\";\nimport type { Primitives, PropertyRecord } from \"@itwin/appui-abstract\";\nimport { PropertyValueFormat } from \"@itwin/appui-abstract\";\nimport { toaster } from \"@itwin/itwinui-react\";\n\nexport interface Query {\n unions: QueryUnion[];\n}\n\nexport interface QueryUnion {\n classes: QueryClass[];\n}\n\nexport interface QueryClass {\n // schemaName.className\n className: string;\n properties: QueryProperty[];\n isAspect: boolean;\n isRelational?: boolean;\n}\n\nexport interface QueryProperty {\n name: string;\n value: Primitives.Value;\n needsQuote: boolean;\n isCategory: boolean;\n}\n\n/* This class is to build adaptive and dynamic query for find similar property selections */\nexport class QueryBuilder {\n public static readonly MULTI_ASPECT_PRIMARY_CLASS =\n \"BisCore:ElementOwnsMultiAspects\";\n public static readonly UNIQUE_ASPECT_PRIMARY_CLASS =\n \"BisCore:ElementOwnsUniqueAspect\";\n public static readonly DEFAULT_DOUBLE_PRECISION = 4;\n\n public dataProvider: PresentationPropertyDataProvider | undefined;\n public query: Query | undefined;\n\n /**\n *\n */\n constructor(provider: PresentationPropertyDataProvider | undefined) {\n this.dataProvider = provider;\n }\n\n public isCategory(propertyField: PropertiesField): boolean {\n const classInfo =\n propertyField.properties[0].property.navigationPropertyInfo?.classInfo;\n return classInfo?.name === \"BisCore:GeometricElement3dIsInCategory\";\n }\n\n public async addProperty(prop: PropertyRecord): Promise<boolean> {\n // TODO: only handle primitive properties now\n if (prop.value?.valueFormat !== PropertyValueFormat.Primitive) {\n toaster.warning(\"Only primitive types are supported for now.\");\n return false;\n }\n if (prop.value.value === undefined) {\n return false;\n }\n\n function replaceAll(str: string, match: string, replacement: string) {\n return str.split(match).join(replacement);\n }\n // if property value has single quote, escape\n if (\n (typeof prop.value.value === \"string\" ||\n prop.value.value instanceof String) &&\n String(prop.value.value).indexOf(\"'\") >= 0\n ) {\n prop.value.value = replaceAll(prop.value.value.toString(), \"'\", \"''\");\n }\n\n // get descriptor\n const descriptor = await this.dataProvider?.getContentDescriptor();\n const propertyField = (await this.dataProvider?.getFieldByPropertyRecord(\n prop,\n )) as PropertiesField;\n\n if (!descriptor || !propertyField) {\n toaster.negative(\n \"Error. Failed to fetch field for this property record.\",\n );\n return false;\n }\n\n // get the special cases\n const isNavigation: boolean =\n prop.property.typename.toLowerCase() === \"navigation\";\n const isCategory: boolean = isNavigation && this.isCategory(propertyField);\n const isAspect: boolean =\n propertyField.parent?.pathToPrimaryClass.find(\n (a) =>\n a.relationshipInfo?.name ===\n QueryBuilder.UNIQUE_ASPECT_PRIMARY_CLASS ||\n a.relationshipInfo?.name === QueryBuilder.MULTI_ASPECT_PRIMARY_CLASS,\n ) !== undefined;\n\n for (let i = 0; i < propertyField.properties.length; i++) {\n const className = propertyField.properties[\n i\n ].property.classInfo.name.replace(\":\", \".\");\n const propertyName = isNavigation\n ? isCategory\n ? `${propertyField.properties[i].property.name}.CodeValue`\n : `${propertyField.properties[i].property.name}.id`\n : propertyField.properties[i].property.name;\n const propertyValue = isNavigation\n ? isCategory\n ? prop.value.displayValue ?? \"\"\n : (prop.value.value as InstanceKey).id\n : prop.value.value;\n\n if (\n !isAspect &&\n propertyField.parent?.pathToPrimaryClass &&\n propertyField.parent?.pathToPrimaryClass.length > 0\n ) {\n this.addRelatedProperty(\n i,\n propertyField,\n propertyName,\n propertyValue,\n isAspect,\n );\n } else {\n this.addPropertyToQuery(\n i,\n className,\n propertyName,\n propertyValue,\n isAspect,\n this._needsQuote(propertyField),\n isCategory,\n false,\n );\n }\n }\n return true;\n }\n\n private _needsQuote(propertyField: PropertiesField): boolean {\n // list of property types that need quote around property value\n if (propertyField.type.typeName.toLowerCase() === \"string\") {\n return true;\n }\n if (propertyField.type.typeName.toLowerCase() === \"uri\") {\n return true;\n }\n return false;\n }\n\n public addRelatedProperty(\n unionIndex: number,\n propertyField: PropertiesField,\n propertyName: string,\n propertyValue: Primitives.Value,\n isAspect: boolean,\n ) {\n const paths = [...(propertyField.parent?.pathToPrimaryClass ?? [])];\n paths.reverse().forEach((path) => {\n const sourceClassName = path.sourceClassInfo?.name.replace(\":\", \".\");\n const targetClassName = path.targetClassInfo?.name.replace(\":\", \".\");\n const relClassName = path.relationshipInfo?.name.replace(\":\", \".\");\n if (!path.isForwardRelationship) {\n this.addPropertyToQuery(\n unionIndex,\n targetClassName,\n `ECInstanceId`,\n `${relClassName}.SourceECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n this.addPropertyToQuery(\n unionIndex,\n relClassName,\n `TargetECInstanceId`,\n `${sourceClassName}.ECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n if (\n path.sourceClassInfo?.name ===\n propertyField.parent?.contentClassInfo.name\n ) {\n this.addPropertyToQuery(\n unionIndex,\n sourceClassName,\n propertyName,\n propertyValue,\n isAspect,\n this._needsQuote(propertyField),\n false,\n true,\n );\n } else {\n this.addPropertyToQuery(\n unionIndex,\n sourceClassName,\n `ECInstanceId`,\n `${relClassName}.TargetECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n }\n } else {\n this.addPropertyToQuery(\n unionIndex,\n targetClassName,\n `ECInstanceId`,\n `${relClassName}.TargetECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n this.addPropertyToQuery(\n unionIndex,\n relClassName,\n `SourceECInstanceId`,\n `${sourceClassName}.ECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n if (\n path.sourceClassInfo?.name ===\n propertyField.parent?.contentClassInfo.name\n ) {\n this.addPropertyToQuery(\n unionIndex,\n sourceClassName,\n propertyName,\n propertyValue,\n isAspect,\n this._needsQuote(propertyField),\n false,\n true,\n );\n } else {\n this.addPropertyToQuery(\n unionIndex,\n sourceClassName,\n `ECInstanceId`,\n `${relClassName}.SourceECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n }\n }\n });\n }\n\n public addPropertyToQuery(\n unionIndex: number,\n className: string,\n propertyName: string,\n propertyValue: Primitives.Value,\n isAspect: boolean,\n needsQuote: boolean,\n isCategory: boolean,\n isRelational?: boolean,\n ) {\n if (this.query === undefined || this.query.unions.length === 0) {\n this.query = {\n unions: [\n {\n classes: [\n {\n className,\n isAspect,\n isRelational,\n properties: [\n {\n name: propertyName,\n value: propertyValue,\n needsQuote,\n isCategory,\n },\n ],\n },\n ],\n },\n ],\n };\n return;\n }\n\n if (this.query.unions.length <= unionIndex) {\n this.query.unions.push({\n classes: [\n {\n className,\n isAspect,\n isRelational,\n properties: [\n {\n name: propertyName,\n value: propertyValue,\n needsQuote,\n isCategory,\n },\n ],\n },\n ],\n });\n return;\n }\n\n const foundClass = this.query.unions[unionIndex].classes.find(\n (c) => c.className === className,\n );\n if (foundClass) {\n foundClass.isRelational = isRelational;\n if (!foundClass.properties.find((x) => x.name === propertyName)) {\n foundClass.properties.push({\n name: propertyName,\n value: propertyValue,\n needsQuote,\n isCategory,\n });\n }\n } else {\n this.query.unions[unionIndex].classes.push({\n className,\n isRelational,\n properties: [\n {\n name: propertyName,\n value: propertyValue,\n needsQuote,\n isCategory,\n },\n ],\n isAspect,\n });\n }\n }\n\n public async removeProperty(prop: PropertyRecord) {\n if (this.query === undefined || this.query.unions.length === 0) {\n return;\n }\n if (\n this.query.unions.length === 1 &&\n this.query.unions[0].classes.length === 0\n ) {\n return;\n }\n\n const descriptor = await this.dataProvider?.getContentDescriptor();\n const propertyField = (await this.dataProvider?.getFieldByPropertyRecord(\n prop,\n )) as PropertiesField;\n if (!descriptor || !propertyField) {\n return;\n }\n\n const isAspect: boolean =\n propertyField.parent?.pathToPrimaryClass.find(\n (a) =>\n a.relationshipInfo?.name ===\n QueryBuilder.UNIQUE_ASPECT_PRIMARY_CLASS ||\n a.relationshipInfo?.name === QueryBuilder.MULTI_ASPECT_PRIMARY_CLASS,\n ) !== undefined;\n const isNavigation: boolean =\n prop.property.typename.toLowerCase() === \"navigation\";\n const isCategory: boolean = isNavigation && this.isCategory(propertyField);\n\n for (let i = 0; i < propertyField.properties.length; i++) {\n const propertyName = isNavigation\n ? isCategory\n ? `${propertyField.properties[i].property.name}.CodeValue`\n : `${propertyField.properties[i].property.name}.id`\n : propertyField.properties[i].property.name;\n const className = propertyField.properties[\n i\n ].property.classInfo.name.replace(\":\", \".\");\n\n if (\n !isAspect &&\n propertyField.parent?.pathToPrimaryClass &&\n propertyField.parent?.pathToPrimaryClass.length > 0\n ) {\n this.removeRelatedProperty(i, propertyField, propertyName);\n } else {\n this.removePropertyFromQuery(i, className, propertyName);\n }\n }\n }\n\n public removeRelatedProperty(\n unionIndex: number,\n propertyField: PropertiesField,\n propertyName: string,\n ) {\n const paths = [...(propertyField.parent?.pathToPrimaryClass ?? [])];\n paths.reverse().forEach((path) => {\n const sourceClassName = path.sourceClassInfo?.name.replace(\":\", \".\");\n const targetClassName = path.targetClassInfo?.name.replace(\":\", \".\");\n const relClassName = path.relationshipInfo?.name.replace(\":\", \".\");\n if (!path.isForwardRelationship) {\n this.removePropertyFromQuery(\n unionIndex,\n targetClassName,\n `ECInstanceId`,\n );\n this.removePropertyFromQuery(\n unionIndex,\n relClassName,\n `TargetECInstanceId`,\n );\n if (\n path.sourceClassInfo?.name ===\n propertyField.parent?.contentClassInfo.name\n ) {\n this.removePropertyFromQuery(\n unionIndex,\n sourceClassName,\n propertyName,\n );\n } else {\n this.removePropertyFromQuery(\n unionIndex,\n sourceClassName,\n `ECInstanceId`,\n );\n }\n } else {\n this.removePropertyFromQuery(\n unionIndex,\n targetClassName,\n `ECInstanceId`,\n );\n this.removePropertyFromQuery(\n unionIndex,\n relClassName,\n `SourceECInstanceId`,\n );\n if (\n path.sourceClassInfo?.name ===\n propertyField.parent?.contentClassInfo.name\n ) {\n this.removePropertyFromQuery(\n unionIndex,\n sourceClassName,\n propertyName,\n );\n } else {\n this.removePropertyFromQuery(\n unionIndex,\n sourceClassName,\n `ECInstanceId`,\n );\n }\n }\n });\n }\n\n public removePropertyFromQuery(\n unionIndex: number,\n className: string,\n propertyName: string,\n ) {\n const foundClass = this.query?.unions[unionIndex].classes.find(\n (c) => c.className === className,\n );\n if (foundClass) {\n const foundPropertyIndex = foundClass.properties.findIndex(\n (p) => p.name === propertyName,\n );\n if (foundPropertyIndex > -1) {\n foundClass.properties.splice(foundPropertyIndex, 1);\n }\n if (foundClass.properties.length === 0) {\n // remove the entire class if all properties are removed\n const foundClassIndex =\n this.query?.unions[unionIndex].classes.findIndex(\n (c) => c.className === className,\n ) ?? -1;\n if (foundClassIndex > -1) {\n this.query?.unions[unionIndex].classes.splice(foundClassIndex, 1);\n }\n }\n }\n }\n\n public categoryQuery(codeValue: string): string {\n return ` JOIN bis.Category ON bis.Category.ECInstanceId = bis.GeometricElement3d.category.id AND ((bis.Category.CodeValue='${codeValue}') OR (bis.Category.UserLabel='${codeValue}'))`;\n }\n\n public buildQueryString() {\n if (\n this.query === undefined ||\n this.query.unions.length === 0 ||\n this.query.unions[0].classes.length === 0\n ) {\n return \"\";\n }\n\n let unionQuery = \"\";\n for (const union of this.query.unions) {\n const baseClass = union.classes[0];\n const baseClassName = baseClass.className;\n const baseIdName = baseClass.isAspect\n ? `${baseClassName}.Element.id`\n : `${baseClassName}.ECInstanceId`;\n\n let queryString = `SELECT ${baseIdName}${\n baseClass.isAspect ? \" ECInstanceId\" : \"\"\n } FROM ${baseClassName}`;\n\n if (union.classes.length > 1) {\n for (let i = 1; i < union.classes.length; i++) {\n const joinClass = union.classes[i];\n const joinClassName = joinClass.className;\n const joinIdName = joinClass.isAspect\n ? `${joinClassName}.Element.id`\n : `${joinClassName}.ECInstanceId`;\n\n if (joinClass.isRelational) {\n queryString += ` JOIN ${joinClassName}`;\n if (joinClass.properties.length > 0) {\n if (joinClass.properties[0].isCategory) {\n queryString += this.categoryQuery(\n joinClass.properties[0].value.toString(),\n );\n } else {\n if (joinClass.properties[0].needsQuote) {\n queryString += ` ON ${joinClassName}.${joinClass.properties[0].name}='${joinClass.properties[0].value}'`;\n } else {\n if (this._isFloat(joinClass.properties[0].value)) {\n queryString += ` ON ROUND(${joinClassName}.${joinClass.properties[0].name}, `;\n queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;\n queryString += `${Number(\n joinClass.properties[0].value,\n ).toFixed(QueryBuilder.DEFAULT_DOUBLE_PRECISION)}`;\n } else {\n queryString += ` ON ${joinClassName}.${joinClass.properties[0].name}=${joinClass.properties[0].value}`;\n }\n }\n }\n }\n // when base is regular property, link base to first joined relational property\n if (!baseClass.isRelational && i === 1) {\n queryString += ` AND ${joinIdName} = ${baseIdName}`;\n }\n for (const property of joinClass.properties) {\n if (property.isCategory) {\n queryString += this.categoryQuery(property.value.toString());\n } else {\n if (property.needsQuote) {\n queryString += ` AND ${joinClassName}.${property.name}='${property.value}'`;\n } else {\n if (this._isFloat(property.value)) {\n queryString += ` AND ROUND(${joinClassName}.${property.name}, `;\n queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;\n queryString += `${Number(property.value).toFixed(\n QueryBuilder.DEFAULT_DOUBLE_PRECISION,\n )}`;\n } else {\n queryString += ` AND ${joinClassName}.${property.name}=${property.value}`;\n }\n }\n }\n }\n } else {\n queryString += ` JOIN ${joinClassName} ON ${joinIdName} = ${baseIdName}`;\n for (const property of joinClass.properties) {\n if (property.isCategory) {\n queryString += this.categoryQuery(property.value.toString());\n } else {\n if (property.needsQuote) {\n queryString += ` AND ${joinClassName}.${property.name}='${property.value}'`;\n } else {\n if (this._isFloat(property.value)) {\n queryString += ` AND ROUND(${joinClassName}.${property.name}, `;\n queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;\n queryString += `${Number(property.value).toFixed(\n QueryBuilder.DEFAULT_DOUBLE_PRECISION,\n )}`;\n } else {\n queryString += ` AND ${joinClassName}.${property.name}=${property.value}`;\n }\n }\n }\n }\n }\n }\n }\n\n const properties = baseClass.properties;\n if (properties.length > 0) {\n if (properties[0].isCategory) {\n queryString += this.categoryQuery(properties[0].value.toString());\n } else {\n if (properties[0].needsQuote) {\n queryString += ` WHERE ${baseClassName}.${properties[0].name}='${properties[0].value}'`;\n } else {\n if (this._isFloat(properties[0].value)) {\n queryString += ` WHERE ROUND(${baseClassName}.${properties[0].name}, `;\n queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;\n queryString += `${Number(properties[0].value).toFixed(\n QueryBuilder.DEFAULT_DOUBLE_PRECISION,\n )}`;\n } else {\n queryString += ` WHERE ${baseClassName}.${properties[0].name}=${properties[0].value}`;\n }\n }\n }\n if (properties.length > 1) {\n for (let i = 1; i < properties.length; i++) {\n if (properties[i].isCategory) {\n queryString += this.categoryQuery(properties[i].value.toString());\n } else {\n if (properties[i].needsQuote) {\n queryString += ` AND ${baseClassName}.${properties[i].name}='${properties[i].value}'`;\n } else {\n if (this._isFloat(properties[i].value)) {\n queryString += ` AND ROUND(${baseClassName}.${properties[i].name}, `;\n queryString += `${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`;\n queryString += `${Number(properties[i].value).toFixed(\n QueryBuilder.DEFAULT_DOUBLE_PRECISION,\n )}`;\n } else {\n queryString += ` AND ${baseClassName}.${properties[i].name}=${properties[i].value}`;\n }\n }\n }\n }\n }\n }\n unionQuery += `${queryString} UNION `;\n }\n unionQuery = unionQuery.slice(0, unionQuery.length - 7);\n return unionQuery;\n }\n\n private _isFloat(n: unknown): boolean {\n return Number(n) === n && n % 1 !== 0;\n }\n}\n"]}
1
+ {"version":3,"file":"QueryBuilder.js","sourceRoot":"","sources":["../../../../src/widget/components/QueryBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport type { PresentationPropertyDataProvider } from \"@itwin/presentation-components\";\nimport type {\n InstanceKey,\n PropertiesField,\n} from \"@itwin/presentation-common\";\nimport type { Primitives, PropertyRecord } from \"@itwin/appui-abstract\";\nimport { PropertyValueFormat } from \"@itwin/appui-abstract\";\nimport { toaster } from \"@itwin/itwinui-react\";\n\nexport interface Query {\n unions: QueryUnion[];\n}\n\nexport interface QueryUnion {\n classes: QueryClass[];\n}\n\nexport interface QueryClass {\n // schemaName.className\n className: string;\n properties: QueryProperty[];\n isAspect: boolean;\n isRelational?: boolean;\n}\n\nexport interface QueryProperty {\n name: string;\n value: Primitives.Value;\n needsQuote: boolean;\n isCategory: boolean;\n}\n\n/* This class is to build adaptive and dynamic query for find similar property selections */\nexport class QueryBuilder {\n public static readonly MULTI_ASPECT_PRIMARY_CLASS =\n \"BisCore:ElementOwnsMultiAspects\";\n public static readonly UNIQUE_ASPECT_PRIMARY_CLASS =\n \"BisCore:ElementOwnsUniqueAspect\";\n public static readonly DEFAULT_DOUBLE_PRECISION = 4;\n\n public dataProvider: PresentationPropertyDataProvider | undefined;\n public query: Query | undefined;\n\n /**\n *\n */\n constructor(provider: PresentationPropertyDataProvider | undefined) {\n this.dataProvider = provider;\n }\n\n public isCategory(propertyField: PropertiesField): boolean {\n const classInfo =\n propertyField.properties[0].property.navigationPropertyInfo?.classInfo;\n return classInfo?.name === \"BisCore:GeometricElement3dIsInCategory\";\n }\n\n public async addProperty(prop: PropertyRecord): Promise<boolean> {\n // TODO: only handle primitive properties now\n if (prop.value?.valueFormat !== PropertyValueFormat.Primitive) {\n toaster.warning(\"Only primitive types are supported for now.\");\n return false;\n }\n if (prop.value.value === undefined) {\n return false;\n }\n\n function replaceAll(str: string, match: string, replacement: string) {\n return str.split(match).join(replacement);\n }\n // if property value has single quote, escape\n if (\n (typeof prop.value.value === \"string\" ||\n prop.value.value instanceof String) &&\n String(prop.value.value).indexOf(\"'\") >= 0\n ) {\n prop.value.value = replaceAll(prop.value.value.toString(), \"'\", \"''\");\n }\n\n // get descriptor\n const descriptor = await this.dataProvider?.getContentDescriptor();\n const propertyField = (await this.dataProvider?.getFieldByPropertyRecord(\n prop,\n )) as PropertiesField;\n\n if (!descriptor || !propertyField) {\n toaster.negative(\n \"Error. Failed to fetch field for this property record.\",\n );\n return false;\n }\n\n // get the special cases\n const isNavigation: boolean =\n prop.property.typename.toLowerCase() === \"navigation\";\n const isCategory: boolean = isNavigation && this.isCategory(propertyField);\n const isAspect: boolean =\n propertyField.parent?.pathToPrimaryClass.find(\n (a) =>\n a.relationshipInfo?.name ===\n QueryBuilder.UNIQUE_ASPECT_PRIMARY_CLASS ||\n a.relationshipInfo?.name === QueryBuilder.MULTI_ASPECT_PRIMARY_CLASS,\n ) !== undefined;\n\n for (let i = 0; i < propertyField.properties.length; i++) {\n const className = propertyField.properties[\n i\n ].property.classInfo.name.replace(\":\", \".\");\n const propertyName = isNavigation\n ? isCategory\n ? `${propertyField.properties[i].property.name}.CodeValue`\n : `${propertyField.properties[i].property.name}.id`\n : propertyField.properties[i].property.name;\n const propertyValue = isNavigation\n ? isCategory\n ? prop.value.displayValue ?? \"\"\n : (prop.value.value as InstanceKey).id\n : prop.value.value;\n\n if (\n !isAspect &&\n propertyField.parent?.pathToPrimaryClass &&\n propertyField.parent?.pathToPrimaryClass.length > 0\n ) {\n this.addRelatedProperty(\n i,\n propertyField,\n propertyName,\n propertyValue,\n isAspect,\n );\n } else {\n this.addPropertyToQuery(\n i,\n className,\n propertyName,\n propertyValue,\n isAspect,\n this._needsQuote(propertyField),\n isCategory,\n false,\n );\n }\n }\n return true;\n }\n\n private _needsQuote(propertyField: PropertiesField): boolean {\n // list of property types that need quote around property value\n if (propertyField.type.typeName.toLowerCase() === \"string\") {\n return true;\n }\n if (propertyField.type.typeName.toLowerCase() === \"uri\") {\n return true;\n }\n return false;\n }\n\n public addRelatedProperty(\n unionIndex: number,\n propertyField: PropertiesField,\n propertyName: string,\n propertyValue: Primitives.Value,\n isAspect: boolean,\n ) {\n const paths = [...(propertyField.parent?.pathToPrimaryClass ?? [])];\n paths.reverse().forEach((path) => {\n const sourceClassName = path.sourceClassInfo?.name.replace(\":\", \".\");\n const targetClassName = path.targetClassInfo?.name.replace(\":\", \".\");\n const relClassName = path.relationshipInfo?.name.replace(\":\", \".\");\n if (!path.isForwardRelationship) {\n this.addPropertyToQuery(\n unionIndex,\n targetClassName,\n `ECInstanceId`,\n `${relClassName}.SourceECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n this.addPropertyToQuery(\n unionIndex,\n relClassName,\n `TargetECInstanceId`,\n `${sourceClassName}.ECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n if (\n path.sourceClassInfo?.name ===\n propertyField.parent?.contentClassInfo.name\n ) {\n this.addPropertyToQuery(\n unionIndex,\n sourceClassName,\n propertyName,\n propertyValue,\n isAspect,\n this._needsQuote(propertyField),\n false,\n true,\n );\n } else {\n this.addPropertyToQuery(\n unionIndex,\n sourceClassName,\n `ECInstanceId`,\n `${relClassName}.TargetECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n }\n } else {\n this.addPropertyToQuery(\n unionIndex,\n targetClassName,\n `ECInstanceId`,\n `${relClassName}.TargetECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n this.addPropertyToQuery(\n unionIndex,\n relClassName,\n `SourceECInstanceId`,\n `${sourceClassName}.ECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n if (\n path.sourceClassInfo?.name ===\n propertyField.parent?.contentClassInfo.name\n ) {\n this.addPropertyToQuery(\n unionIndex,\n sourceClassName,\n propertyName,\n propertyValue,\n isAspect,\n this._needsQuote(propertyField),\n false,\n true,\n );\n } else {\n this.addPropertyToQuery(\n unionIndex,\n sourceClassName,\n `ECInstanceId`,\n `${relClassName}.SourceECInstanceId`,\n isAspect,\n false,\n false,\n true,\n );\n }\n }\n });\n }\n\n public addPropertyToQuery(\n unionIndex: number,\n className: string,\n propertyName: string,\n propertyValue: Primitives.Value,\n isAspect: boolean,\n needsQuote: boolean,\n isCategory: boolean,\n isRelational?: boolean,\n ) {\n if (this.query === undefined || this.query.unions.length === 0) {\n this.query = {\n unions: [\n {\n classes: [\n {\n className,\n isAspect,\n isRelational,\n properties: [\n {\n name: propertyName,\n value: propertyValue,\n needsQuote,\n isCategory,\n },\n ],\n },\n ],\n },\n ],\n };\n return;\n }\n\n if (this.query.unions.length <= unionIndex) {\n this.query.unions.push({\n classes: [\n {\n className,\n isAspect,\n isRelational,\n properties: [\n {\n name: propertyName,\n value: propertyValue,\n needsQuote,\n isCategory,\n },\n ],\n },\n ],\n });\n return;\n }\n\n const foundClass = this.query.unions[unionIndex].classes.find(\n (c) => c.className === className,\n );\n if (foundClass) {\n foundClass.isRelational = isRelational;\n if (!foundClass.properties.find((x) => x.name === propertyName)) {\n foundClass.properties.push({\n name: propertyName,\n value: propertyValue,\n needsQuote,\n isCategory,\n });\n }\n } else {\n this.query.unions[unionIndex].classes.push({\n className,\n isRelational,\n properties: [\n {\n name: propertyName,\n value: propertyValue,\n needsQuote,\n isCategory,\n },\n ],\n isAspect,\n });\n }\n }\n\n public async removeProperty(prop: PropertyRecord) {\n if (this.query === undefined || this.query.unions.length === 0) {\n return;\n }\n if (\n this.query.unions.length === 1 &&\n this.query.unions[0].classes.length === 0\n ) {\n return;\n }\n\n const descriptor = await this.dataProvider?.getContentDescriptor();\n const propertyField = (await this.dataProvider?.getFieldByPropertyRecord(\n prop,\n )) as PropertiesField;\n if (!descriptor || !propertyField) {\n return;\n }\n\n const isAspect: boolean =\n propertyField.parent?.pathToPrimaryClass.find(\n (a) =>\n a.relationshipInfo?.name ===\n QueryBuilder.UNIQUE_ASPECT_PRIMARY_CLASS ||\n a.relationshipInfo?.name === QueryBuilder.MULTI_ASPECT_PRIMARY_CLASS,\n ) !== undefined;\n const isNavigation: boolean =\n prop.property.typename.toLowerCase() === \"navigation\";\n const isCategory: boolean = isNavigation && this.isCategory(propertyField);\n\n for (let i = 0; i < propertyField.properties.length; i++) {\n const propertyName = isNavigation\n ? isCategory\n ? `${propertyField.properties[i].property.name}.CodeValue`\n : `${propertyField.properties[i].property.name}.id`\n : propertyField.properties[i].property.name;\n const className = propertyField.properties[\n i\n ].property.classInfo.name.replace(\":\", \".\");\n\n if (\n !isAspect &&\n propertyField.parent?.pathToPrimaryClass &&\n propertyField.parent?.pathToPrimaryClass.length > 0\n ) {\n this.removeRelatedProperty(i, propertyField, propertyName);\n } else {\n this.removePropertyFromQuery(i, className, propertyName);\n }\n }\n }\n\n public removeRelatedProperty(\n unionIndex: number,\n propertyField: PropertiesField,\n propertyName: string,\n ) {\n const paths = [...(propertyField.parent?.pathToPrimaryClass ?? [])];\n paths.reverse().forEach((path) => {\n const sourceClassName = path.sourceClassInfo?.name.replace(\":\", \".\");\n const targetClassName = path.targetClassInfo?.name.replace(\":\", \".\");\n const relClassName = path.relationshipInfo?.name.replace(\":\", \".\");\n if (!path.isForwardRelationship) {\n this.removePropertyFromQuery(\n unionIndex,\n targetClassName,\n `ECInstanceId`,\n );\n this.removePropertyFromQuery(\n unionIndex,\n relClassName,\n `TargetECInstanceId`,\n );\n if (\n path.sourceClassInfo?.name ===\n propertyField.parent?.contentClassInfo.name\n ) {\n this.removePropertyFromQuery(\n unionIndex,\n sourceClassName,\n propertyName,\n );\n } else {\n this.removePropertyFromQuery(\n unionIndex,\n sourceClassName,\n `ECInstanceId`,\n );\n }\n } else {\n this.removePropertyFromQuery(\n unionIndex,\n targetClassName,\n `ECInstanceId`,\n );\n this.removePropertyFromQuery(\n unionIndex,\n relClassName,\n `SourceECInstanceId`,\n );\n if (\n path.sourceClassInfo?.name ===\n propertyField.parent?.contentClassInfo.name\n ) {\n this.removePropertyFromQuery(\n unionIndex,\n sourceClassName,\n propertyName,\n );\n } else {\n this.removePropertyFromQuery(\n unionIndex,\n sourceClassName,\n `ECInstanceId`,\n );\n }\n }\n });\n }\n\n public removePropertyFromQuery(\n unionIndex: number,\n className: string,\n propertyName: string,\n ) {\n const foundClass = this.query?.unions[unionIndex].classes.find(\n (c) => c.className === className,\n );\n if (foundClass) {\n const foundPropertyIndex = foundClass.properties.findIndex(\n (p) => p.name === propertyName,\n );\n if (foundPropertyIndex > -1) {\n foundClass.properties.splice(foundPropertyIndex, 1);\n }\n if (foundClass.properties.length === 0) {\n // remove the entire class if all properties are removed\n const foundClassIndex =\n this.query?.unions[unionIndex].classes.findIndex(\n (c) => c.className === className,\n ) ?? -1;\n if (foundClassIndex > -1) {\n this.query?.unions[unionIndex].classes.splice(foundClassIndex, 1);\n }\n }\n }\n }\n\n public buildQueryString() {\n if (\n this.query === undefined ||\n this.query.unions.length === 0 ||\n this.query.unions[0].classes.length === 0\n ) {\n return \"\";\n }\n\n const unionSegments: string[] = [];\n for (const union of this.query.unions) {\n const querySegments: string[] = [];\n\n const baseClass = union.classes[0];\n const baseClassName = baseClass.className;\n const baseIdName = baseClass.isAspect\n ? `${baseClassName}.Element.id`\n : `${baseClassName}.ECInstanceId`;\n\n const selectSegment = `SELECT ${baseIdName}${baseClass.isAspect ? \" ECInstanceId\" : \"\"} FROM ${baseClassName}`;\n querySegments.push(selectSegment);\n\n if (union.classes.length > 1) {\n for (let i = 1; i < union.classes.length; i++) {\n const joinClass = union.classes[i];\n const joinClassName = joinClass.className;\n const joinIdName = joinClass.isAspect\n ? `${joinClassName}.Element.id`\n : `${joinClassName}.ECInstanceId`;\n\n const joinSegment = joinClass.isRelational\n ? ` JOIN ${joinClassName}`\n : ` JOIN ${joinClassName} ON ${joinIdName} = ${baseIdName}`;\n querySegments.push(joinSegment);\n\n for (let j = 0; j < joinClass.properties.length; j++) {\n const prefix = j === 0 && joinClass.isRelational ? \"ON\" : \"AND\";\n const propertySegment = this._propertySegment(joinClassName, joinClass.properties[j], prefix);\n querySegments.push(propertySegment);\n }\n // when base is regular property, link base to first joined relational property\n if (joinClass.isRelational && !baseClass.isRelational && i === 1) {\n querySegments.push(` AND ${joinIdName} = ${baseIdName}`);\n }\n }\n }\n\n const whereSegment = this._whereSegment(baseClass, baseClassName);\n querySegments.push(whereSegment);\n\n unionSegments.push(querySegments.join(\"\"));\n }\n\n return unionSegments.join(\" UNION \");\n }\n\n private _whereSegment = (\n baseClass: QueryClass,\n baseClassName: string\n ): string => {\n const segments: string[] = [];\n\n const properties = baseClass.properties;\n for (let i = 0; i < properties.length; i++) {\n const prefix = i === 0 ? \"WHERE\" : \"AND\";\n segments.push(this._propertySegment(baseClassName, properties[i], prefix));\n }\n\n return segments.join(\"\");\n }\n\n private _propertySegment(\n className: string,\n property: QueryProperty,\n prefix: string\n ): string {\n const segments: string[] = [];\n\n if (property.isCategory) {\n segments.push(this._categoryQuery(property.value.toString()));\n } else {\n if (property.needsQuote) {\n segments.push(` ${prefix} ${className}.${property.name}='${property.value}'`);\n } else {\n if (this._isFloat(property.value)) {\n segments.push(` ${prefix} ROUND(${className}.${property.name}, `);\n segments.push(`${QueryBuilder.DEFAULT_DOUBLE_PRECISION})=`);\n segments.push(`${Number(property.value).toFixed(\n QueryBuilder.DEFAULT_DOUBLE_PRECISION\n )}`);\n } else {\n segments.push(` ${prefix} ${className}.${property.name}=${property.value}`);\n }\n }\n }\n\n return segments.join(\"\");\n }\n\n private _categoryQuery(codeValue: string): string {\n return ` JOIN bis.Category ON bis.Category.ECInstanceId = bis.GeometricElement3d.category.id AND ((bis.Category.CodeValue='${codeValue}') OR (bis.Category.UserLabel='${codeValue}'))`;\n }\n\n private _isFloat(n: unknown): boolean {\n return Number(n) === n && n % 1 !== 0;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/grouping-mapping-widget",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
4
4
  "description": "An iTwin.js 3D Viewer Widget that interfaces with the iTwin Reporting Platform.",
5
5
  "keywords": [
6
6
  "Bentley",
@@ -77,6 +77,7 @@
77
77
  "@testing-library/jest-dom": "^5.16.3",
78
78
  "@testing-library/react": "^12.1.4",
79
79
  "@testing-library/user-event": "^14.1.1",
80
+ "@types/chai": "4.2.11",
80
81
  "@types/i18next": "^8.4.2",
81
82
  "@types/jest": "^27.4.1",
82
83
  "@types/node": "^14.14.20",
@@ -87,6 +88,7 @@
87
88
  "@types/testing-library__jest-dom": "^5.14.3",
88
89
  "@typescript-eslint/eslint-plugin": "^5.3.1",
89
90
  "@typescript-eslint/parser": "^5.10.1",
91
+ "chai": "^4.2.0",
90
92
  "cpx2": "^3.0.0",
91
93
  "eslint": "^7.32.0",
92
94
  "eslint-plugin-node": "^11.1.0",