@itwin/core-backend 5.14.0-dev.21 → 5.14.0-dev.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/ECDb.d.ts +11 -6
- package/lib/cjs/ECDb.d.ts.map +1 -1
- package/lib/cjs/ECDb.js +11 -6
- package/lib/cjs/ECDb.js.map +1 -1
- package/lib/cjs/ECSqlStatement.d.ts +2 -2
- package/lib/cjs/ECSqlStatement.js +2 -2
- package/lib/cjs/ECSqlStatement.js.map +1 -1
- package/lib/cjs/IModelDb.d.ts +12 -10
- package/lib/cjs/IModelDb.d.ts.map +1 -1
- package/lib/cjs/IModelDb.js +19 -12
- package/lib/cjs/IModelDb.js.map +1 -1
- package/lib/cjs/annotations/ElementDrivesTextAnnotation.d.ts +90 -5
- package/lib/cjs/annotations/ElementDrivesTextAnnotation.d.ts.map +1 -1
- package/lib/cjs/annotations/ElementDrivesTextAnnotation.js +59 -1
- package/lib/cjs/annotations/ElementDrivesTextAnnotation.js.map +1 -1
- package/lib/cjs/internal/annotations/fieldSpecs.d.ts +82 -0
- package/lib/cjs/internal/annotations/fieldSpecs.d.ts.map +1 -0
- package/lib/cjs/internal/annotations/fieldSpecs.js +187 -0
- package/lib/cjs/internal/annotations/fieldSpecs.js.map +1 -0
- package/lib/cjs/internal/annotations/fields.d.ts +39 -2
- package/lib/cjs/internal/annotations/fields.d.ts.map +1 -1
- package/lib/cjs/internal/annotations/fields.js +140 -13
- package/lib/cjs/internal/annotations/fields.js.map +1 -1
- package/lib/esm/ECDb.d.ts +11 -6
- package/lib/esm/ECDb.d.ts.map +1 -1
- package/lib/esm/ECDb.js +11 -6
- package/lib/esm/ECDb.js.map +1 -1
- package/lib/esm/ECSqlStatement.d.ts +2 -2
- package/lib/esm/ECSqlStatement.js +2 -2
- package/lib/esm/ECSqlStatement.js.map +1 -1
- package/lib/esm/IModelDb.d.ts +12 -10
- package/lib/esm/IModelDb.d.ts.map +1 -1
- package/lib/esm/IModelDb.js +19 -12
- package/lib/esm/IModelDb.js.map +1 -1
- package/lib/esm/annotations/ElementDrivesTextAnnotation.d.ts +90 -5
- package/lib/esm/annotations/ElementDrivesTextAnnotation.d.ts.map +1 -1
- package/lib/esm/annotations/ElementDrivesTextAnnotation.js +60 -2
- package/lib/esm/annotations/ElementDrivesTextAnnotation.js.map +1 -1
- package/lib/esm/internal/annotations/fieldSpecs.d.ts +82 -0
- package/lib/esm/internal/annotations/fieldSpecs.d.ts.map +1 -0
- package/lib/esm/internal/annotations/fieldSpecs.js +179 -0
- package/lib/esm/internal/annotations/fieldSpecs.js.map +1 -0
- package/lib/esm/internal/annotations/fields.d.ts +39 -2
- package/lib/esm/internal/annotations/fields.d.ts.map +1 -1
- package/lib/esm/internal/annotations/fields.js +140 -13
- package/lib/esm/internal/annotations/fields.js.map +1 -1
- package/lib/esm/test/AnnotationTestUtils.d.ts +9 -0
- package/lib/esm/test/AnnotationTestUtils.d.ts.map +1 -1
- package/lib/esm/test/AnnotationTestUtils.js +17 -0
- package/lib/esm/test/AnnotationTestUtils.js.map +1 -1
- package/lib/esm/test/annotations/FieldFormat.test.d.ts +2 -0
- package/lib/esm/test/annotations/FieldFormat.test.d.ts.map +1 -0
- package/lib/esm/test/annotations/FieldFormat.test.js +738 -0
- package/lib/esm/test/annotations/FieldFormat.test.js.map +1 -0
- package/lib/esm/test/annotations/FieldFormattingLifecycle.test.d.ts +2 -0
- package/lib/esm/test/annotations/FieldFormattingLifecycle.test.d.ts.map +1 -0
- package/lib/esm/test/annotations/FieldFormattingLifecycle.test.js +323 -0
- package/lib/esm/test/annotations/FieldFormattingLifecycle.test.js.map +1 -0
- package/lib/esm/test/annotations/FieldSpecs.test.d.ts +2 -0
- package/lib/esm/test/annotations/FieldSpecs.test.d.ts.map +1 -0
- package/lib/esm/test/annotations/FieldSpecs.test.js +54 -0
- package/lib/esm/test/annotations/FieldSpecs.test.js.map +1 -0
- package/lib/esm/test/annotations/Fields.test.js +221 -27
- package/lib/esm/test/annotations/Fields.test.js.map +1 -1
- package/lib/esm/test/ecdb/QueryReaders.test.js +105 -30
- package/lib/esm/test/ecdb/QueryReaders.test.js.map +1 -1
- package/package.json +15 -13
|
@@ -1,14 +1,51 @@
|
|
|
1
|
-
import { FieldRun,
|
|
1
|
+
import { FieldRun, RelationshipProps, TextBlock } from "@itwin/core-common";
|
|
2
2
|
import { IModelDb } from "../../IModelDb";
|
|
3
3
|
import { Id64String } from "@itwin/core-bentley";
|
|
4
|
+
import { FieldFormatting, ResolvedFieldValue } from "./fieldSpecs";
|
|
4
5
|
import type { EditTxn } from "../../EditTxn";
|
|
6
|
+
/** The per-evaluation state [[updateField]] needs: which element's fields to recompute, how to
|
|
7
|
+
* read a field's property value, and how to format quantities.
|
|
8
|
+
*/
|
|
5
9
|
export interface UpdateFieldsContext {
|
|
10
|
+
/** When set, only fields whose [FieldPropertyHost.elementId]($common) matches are recomputed —
|
|
11
|
+
* an edit to one source element leaves the annotation's other fields untouched.
|
|
12
|
+
*/
|
|
6
13
|
readonly hostElementId: Id64String | undefined;
|
|
7
|
-
|
|
14
|
+
/** Reads the value a field points at, or `undefined` if it cannot be resolved — including
|
|
15
|
+
* every field when the source element was deleted.
|
|
16
|
+
*/
|
|
17
|
+
getProperty(field: FieldRun): ResolvedFieldValue | undefined;
|
|
18
|
+
/** The formats `"quantity"` and `"coordinate"` values resolve through. [[updateField]] builds
|
|
19
|
+
* a [FormatterSpec]($core-quantity) per field from the FormatSet named by
|
|
20
|
+
* [QuantityFieldFormatOptions.formatSet]($common), falling back to the adopted FormatSet and
|
|
21
|
+
* the schemas; a value none of them can format falls back to `value.toString()`.
|
|
22
|
+
* [[createUpdateContext]] always supplies the iModel's formatting; only hand-built contexts in
|
|
23
|
+
* tests that never format a quantity leave it out.
|
|
24
|
+
*/
|
|
25
|
+
readonly formatting?: FieldFormatting;
|
|
8
26
|
}
|
|
9
27
|
export declare function createUpdateContext(hostElementId: string | undefined, iModel: IModelDb, deleted: boolean): UpdateFieldsContext;
|
|
28
|
+
/** Recomputes a single field's cached display string synchronously. Returns true iff
|
|
29
|
+
* cachedContent changed.
|
|
30
|
+
*
|
|
31
|
+
* Resolving the property value and formatting it are both fallible. A failure of either is
|
|
32
|
+
* logged and degrades *this* field to [FieldRun.invalidContentIndicator]($common); other
|
|
33
|
+
* fields in the same block are unaffected.
|
|
34
|
+
*/
|
|
10
35
|
export declare function updateField(field: FieldRun, context: UpdateFieldsContext): boolean;
|
|
36
|
+
/** Re-evaluates every [FieldRun]($common) in `textBlock` synchronously and returns the number
|
|
37
|
+
* whose cached display string changed. Fields targeting an element other than
|
|
38
|
+
* `context.hostElementId` (when set) are skipped.
|
|
39
|
+
*/
|
|
11
40
|
export declare function updateFields(textBlock: TextBlock, context: UpdateFieldsContext): number;
|
|
41
|
+
/** Re-evaluates the fields of the `props.targetId` annotation in response to a source-element
|
|
42
|
+
* change (`deleted=false`) or delete (`deleted=true`). Invoked from
|
|
43
|
+
* [[ElementDrivesTextAnnotation.onRootChangedArg]] / `onDeletedDependencyArg`.
|
|
44
|
+
*/
|
|
12
45
|
export declare function updateElementFields(props: RelationshipProps, txn: EditTxn, deleted: boolean): void;
|
|
46
|
+
/** Re-evaluates every field of the given annotation element against its current property
|
|
47
|
+
* values. Invoked from [[ElementDrivesTextAnnotation.updateFieldDependencies]] when
|
|
48
|
+
* establishing / refreshing relationships.
|
|
49
|
+
*/
|
|
13
50
|
export declare function updateAllFields(annotationElementId: Id64String, txn: EditTxn): void;
|
|
14
51
|
//# sourceMappingURL=fields.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../../../src/internal/annotations/fields.ts"],"names":[],"mappings":"AAKA,OAAO,EAA0C,QAAQ,
|
|
1
|
+
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../../../src/internal/annotations/fields.ts"],"names":[],"mappings":"AAKA,OAAO,EAA0C,QAAQ,EAA8E,iBAAiB,EAAE,SAAS,EAA8B,MAAM,oBAAoB,CAAC;AAC5N,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAyB,UAAU,EAAU,MAAM,qBAAqB,CAAC;AAKhF,OAAO,EAAE,eAAe,EAAuC,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACxG,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AA0B7C;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,QAAQ,CAAC,aAAa,EAAE,UAAU,GAAG,SAAS,CAAC;IAE/C;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,kBAAkB,GAAG,SAAS,CAAC;IAE7D;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC;CACvC;AA+OD,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,mBAAmB,CAM9H;AA0CD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CA0BlF;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,mBAAmB,GAAG,MAAM,CASvF;AAyBD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAElG;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,mBAAmB,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAEnF"}
|
|
@@ -15,7 +15,9 @@ const BackendLoggerCategory_1 = require("../../BackendLoggerCategory");
|
|
|
15
15
|
const ElementDrivesTextAnnotation_1 = require("../../annotations/ElementDrivesTextAnnotation");
|
|
16
16
|
const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
|
|
17
17
|
const ECSqlInstanceReshaper_1 = require("../ECSqlInstanceReshaper");
|
|
18
|
-
|
|
18
|
+
const fieldSpecs_1 = require("./fieldSpecs");
|
|
19
|
+
// Resolves the property a field points at into a [[ResolvedFieldValue]] — primitive value plus, for
|
|
20
|
+
// `"quantity"` / `"coordinate"` types, the property-side KoQ and persistence unit.
|
|
19
21
|
function getFieldPropertyValue(field, iModel) {
|
|
20
22
|
const host = field.propertyHost;
|
|
21
23
|
const schemaItem = iModel.schemaContext.getSchemaItemSync(host.schemaName, host.className);
|
|
@@ -23,7 +25,7 @@ function getFieldPropertyValue(field, iModel) {
|
|
|
23
25
|
return undefined;
|
|
24
26
|
}
|
|
25
27
|
let ecClass = schemaItem;
|
|
26
|
-
const { propertyName, accessors } = field.propertyPath;
|
|
28
|
+
const { propertyName, accessors, jsonAccessors } = field.propertyPath;
|
|
27
29
|
let ecProp = ecClass.getPropertySync(propertyName);
|
|
28
30
|
if (!ecProp) {
|
|
29
31
|
return undefined;
|
|
@@ -115,15 +117,81 @@ function getFieldPropertyValue(field, iModel) {
|
|
|
115
117
|
}
|
|
116
118
|
}
|
|
117
119
|
}
|
|
120
|
+
// The ultimate result must be a primitive value.
|
|
121
|
+
if (undefined === curValue.primitive) {
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
// `jsonAccessors` continue the walk inside a serialized JSON string. There is no schema behind a JSON blob, so the
|
|
125
|
+
// property must declare itself as JSON via its extended type; an un-indexed JSON property resolves to the raw string.
|
|
126
|
+
if (jsonAccessors && jsonAccessors.length > 0) {
|
|
127
|
+
if (!isJsonProperty(ecProp) || typeof curValue.primitive !== "string") {
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
return readJsonLeaf(curValue.primitive, jsonAccessors);
|
|
131
|
+
}
|
|
118
132
|
const propertyType = determineFieldPropertyType(ecProp);
|
|
119
133
|
if (!propertyType) {
|
|
120
134
|
return undefined;
|
|
121
135
|
}
|
|
122
|
-
//
|
|
123
|
-
|
|
136
|
+
// Property-side KoQ + persistence unit only. Overrides in `formatOptions.quantity` are
|
|
137
|
+
// merged at formatting time (see `collectFieldQuantityPairs`) so these serve as the fallback
|
|
138
|
+
// when the override doesn't resolve.
|
|
139
|
+
let kindOfQuantityFullName;
|
|
140
|
+
let persistenceUnitFullName;
|
|
141
|
+
if (propertyType === "quantity" || propertyType === "coordinate") {
|
|
142
|
+
const koq = ecProp.kindOfQuantity ? ecProp.getKindOfQuantitySync() : undefined;
|
|
143
|
+
kindOfQuantityFullName = koq?.fullName;
|
|
144
|
+
persistenceUnitFullName = koq?.persistenceUnit?.fullName;
|
|
145
|
+
}
|
|
146
|
+
return { value: curValue.primitive, type: propertyType, kindOfQuantityFullName, persistenceUnitFullName };
|
|
147
|
+
}
|
|
148
|
+
function isJsonProperty(prop) {
|
|
149
|
+
return prop.isPrimitive() && !prop.isArray() && prop.primitiveType === ecschema_metadata_1.PrimitiveType.String && prop.extendedTypeName === "Json";
|
|
150
|
+
}
|
|
151
|
+
/** Applies [FieldPropertyPath.jsonAccessors]($common) to a string property holding serialized JSON,
|
|
152
|
+
* as a walk entirely separate from the EC one: there is no schema behind a JSON blob, so no EC
|
|
153
|
+
* metadata is consulted.
|
|
154
|
+
*
|
|
155
|
+
* Returns `undefined` when `raw` is not JSON, when an accessor does not resolve, or when the path
|
|
156
|
+
* stops anywhere but a scalar — including on a JSON `null`, which is not a
|
|
157
|
+
* [FieldPrimitiveValue]($common).
|
|
158
|
+
*/
|
|
159
|
+
function readJsonLeaf(raw, accessors) {
|
|
160
|
+
let cur;
|
|
161
|
+
try {
|
|
162
|
+
cur = JSON.parse(raw);
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// Not valid JSON; treat as a normal string.
|
|
124
166
|
return undefined;
|
|
125
167
|
}
|
|
126
|
-
|
|
168
|
+
for (const accessor of accessors) {
|
|
169
|
+
// A number indexes an array and a string keys an object; anything else doesn't resolve.
|
|
170
|
+
const isIndex = typeof accessor === "number";
|
|
171
|
+
if (typeof cur !== "object" || null === cur || Array.isArray(cur) !== isIndex) {
|
|
172
|
+
return undefined;
|
|
173
|
+
}
|
|
174
|
+
if (isIndex) {
|
|
175
|
+
cur = cur[accessor < 0 ? cur.length + accessor : accessor];
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
// Own keys only, so a key missing from the JSON can't resolve through Object.prototype.
|
|
179
|
+
cur = Object.hasOwn(cur, accessor) ? cur[accessor] : undefined;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// JSON carries no type metadata, so the leaf's JavaScript type decides the field property type.
|
|
183
|
+
// A numeric leaf is typed `"quantity"` but has no property-side KoQ, so only the field's own
|
|
184
|
+
// `kindOfQuantity` + `persistenceUnit` overrides can name a format for it.
|
|
185
|
+
switch (typeof cur) {
|
|
186
|
+
case "number":
|
|
187
|
+
return { value: cur, type: "quantity" };
|
|
188
|
+
case "boolean":
|
|
189
|
+
return { value: cur, type: "boolean" };
|
|
190
|
+
case "string":
|
|
191
|
+
return { value: cur, type: "string" };
|
|
192
|
+
default:
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
127
195
|
}
|
|
128
196
|
function determineFieldPropertyType(prop) {
|
|
129
197
|
if (prop.isEnumeration()) {
|
|
@@ -145,16 +213,18 @@ function determineFieldPropertyType(prop) {
|
|
|
145
213
|
case ecschema_metadata_1.PrimitiveType.DateTime:
|
|
146
214
|
return "datetime";
|
|
147
215
|
case ecschema_metadata_1.PrimitiveType.Double:
|
|
216
|
+
case ecschema_metadata_1.PrimitiveType.Integer:
|
|
148
217
|
case ecschema_metadata_1.PrimitiveType.Long:
|
|
218
|
+
// Any numeric property is a potential quantity. Classifying one as "quantity" is not an
|
|
219
|
+
// assertion that it *has* units -- it only decides whether the KoQ/units pipeline is
|
|
220
|
+
// consulted. A number that resolves no spec falls back to the same `toString()` the
|
|
221
|
+
// "string" formatter would have produced, so counts and identifiers still render bare.
|
|
149
222
|
return "quantity";
|
|
150
223
|
case ecschema_metadata_1.PrimitiveType.Point2d:
|
|
151
224
|
case ecschema_metadata_1.PrimitiveType.Point3d:
|
|
152
225
|
return "coordinate";
|
|
153
226
|
case ecschema_metadata_1.PrimitiveType.Binary:
|
|
154
227
|
return prop.extendedTypeName === "BeGuid" ? "string" : undefined;
|
|
155
|
-
case ecschema_metadata_1.PrimitiveType.Integer:
|
|
156
|
-
case ecschema_metadata_1.PrimitiveType.Long:
|
|
157
|
-
return "string";
|
|
158
228
|
default:
|
|
159
229
|
return undefined;
|
|
160
230
|
}
|
|
@@ -165,9 +235,53 @@ function createUpdateContext(hostElementId, iModel, deleted) {
|
|
|
165
235
|
return {
|
|
166
236
|
hostElementId,
|
|
167
237
|
getProperty: deleted ? () => undefined : (field) => getFieldPropertyValue(field, iModel),
|
|
238
|
+
formatting: (0, fieldSpecs_1.getFieldFormatting)(iModel),
|
|
168
239
|
};
|
|
169
240
|
}
|
|
170
|
-
|
|
241
|
+
/** Resolves the [FormatterSpec]($core-quantity) this field should render its magnitudes through,
|
|
242
|
+
* returning a callback bound to it, or `undefined` when not a quantity or coordinate, no formats
|
|
243
|
+
* were supplied, or no format resolves for any of the (KindOfQuantity, persistence unit) pairs the
|
|
244
|
+
* field may format through. In that last case the shortfall is logged: a persistence unit or
|
|
245
|
+
* format unit outside the bundled BIS set, a KindOfQuantity with no presentation format, or a
|
|
246
|
+
* format whose units belong to a different phenomenon than the persisted value. A
|
|
247
|
+
* `persistenceUnit` override that disagrees with the property's own unit is ignored and logged
|
|
248
|
+
* too; the property's unit is what the stored magnitude means.
|
|
249
|
+
*/
|
|
250
|
+
function resolveFormatMagnitude(value, field, context) {
|
|
251
|
+
const formatting = context.formatting;
|
|
252
|
+
if (!formatting || (value.type !== "quantity" && value.type !== "coordinate")) {
|
|
253
|
+
return undefined;
|
|
254
|
+
}
|
|
255
|
+
const quantityOptions = field.formatOptions?.quantity;
|
|
256
|
+
const { spec, candidates, ignoredPersistenceUnit } = (0, fieldSpecs_1.lookupFieldSpec)(quantityOptions, value, formatting);
|
|
257
|
+
if (ignoredPersistenceUnit) {
|
|
258
|
+
core_bentley_1.Logger.logWarning(BackendLoggerCategory_1.BackendLoggerCategory.IModelDb, "Ignoring persistenceUnit override that disagrees with the property's own persistence unit", () => ({
|
|
259
|
+
elementId: field.propertyHost.elementId,
|
|
260
|
+
propertyName: field.propertyPath.propertyName,
|
|
261
|
+
persistenceUnit: ignoredPersistenceUnit,
|
|
262
|
+
propertyPersistenceUnit: value.persistenceUnitFullName,
|
|
263
|
+
}));
|
|
264
|
+
}
|
|
265
|
+
if (!spec) {
|
|
266
|
+
if (candidates.length > 0) {
|
|
267
|
+
core_bentley_1.Logger.logWarning(BackendLoggerCategory_1.BackendLoggerCategory.IModelDb, "No format resolved for text annotation field; rendering raw value", () => ({
|
|
268
|
+
elementId: field.propertyHost.elementId,
|
|
269
|
+
propertyName: field.propertyPath.propertyName,
|
|
270
|
+
formatSet: quantityOptions?.formatSet,
|
|
271
|
+
tried: candidates.map((c) => `${c.name} in ${c.persistenceUnitName}`),
|
|
272
|
+
}));
|
|
273
|
+
}
|
|
274
|
+
return undefined;
|
|
275
|
+
}
|
|
276
|
+
return (magnitude) => spec.applyFormatting(magnitude);
|
|
277
|
+
}
|
|
278
|
+
/** Recomputes a single field's cached display string synchronously. Returns true iff
|
|
279
|
+
* cachedContent changed.
|
|
280
|
+
*
|
|
281
|
+
* Resolving the property value and formatting it are both fallible. A failure of either is
|
|
282
|
+
* logged and degrades *this* field to [FieldRun.invalidContentIndicator]($common); other
|
|
283
|
+
* fields in the same block are unaffected.
|
|
284
|
+
*/
|
|
171
285
|
function updateField(field, context) {
|
|
172
286
|
if (context.hostElementId && context.hostElementId !== field.propertyHost.elementId) {
|
|
173
287
|
return false;
|
|
@@ -176,7 +290,11 @@ function updateField(field, context) {
|
|
|
176
290
|
try {
|
|
177
291
|
const propValue = context.getProperty(field);
|
|
178
292
|
if (undefined !== propValue) {
|
|
179
|
-
newContent = (0, core_common_1.formatFieldValue)(
|
|
293
|
+
newContent = (0, core_common_1.formatFieldValue)({
|
|
294
|
+
value: propValue,
|
|
295
|
+
options: field.formatOptions,
|
|
296
|
+
formatMagnitude: resolveFormatMagnitude(propValue, field, context),
|
|
297
|
+
});
|
|
180
298
|
}
|
|
181
299
|
}
|
|
182
300
|
catch (err) {
|
|
@@ -189,8 +307,10 @@ function updateField(field, context) {
|
|
|
189
307
|
field.setCachedContent(newContent);
|
|
190
308
|
return true;
|
|
191
309
|
}
|
|
192
|
-
|
|
193
|
-
|
|
310
|
+
/** Re-evaluates every [FieldRun]($common) in `textBlock` synchronously and returns the number
|
|
311
|
+
* whose cached display string changed. Fields targeting an element other than
|
|
312
|
+
* `context.hostElementId` (when set) are skipped.
|
|
313
|
+
*/
|
|
194
314
|
function updateFields(textBlock, context) {
|
|
195
315
|
let numUpdated = 0;
|
|
196
316
|
for (const { child } of (0, core_common_1.traverseTextBlockComponent)(textBlock)) {
|
|
@@ -222,10 +342,17 @@ function doUpdateFields(txn, annotationId, sourceId, deleted) {
|
|
|
222
342
|
core_bentley_1.Logger.logError(BackendLoggerCategory_1.BackendLoggerCategory.IModelDb, err);
|
|
223
343
|
}
|
|
224
344
|
}
|
|
225
|
-
|
|
345
|
+
/** Re-evaluates the fields of the `props.targetId` annotation in response to a source-element
|
|
346
|
+
* change (`deleted=false`) or delete (`deleted=true`). Invoked from
|
|
347
|
+
* [[ElementDrivesTextAnnotation.onRootChangedArg]] / `onDeletedDependencyArg`.
|
|
348
|
+
*/
|
|
226
349
|
function updateElementFields(props, txn, deleted) {
|
|
227
350
|
doUpdateFields(txn, props.targetId, props.sourceId, deleted);
|
|
228
351
|
}
|
|
352
|
+
/** Re-evaluates every field of the given annotation element against its current property
|
|
353
|
+
* values. Invoked from [[ElementDrivesTextAnnotation.updateFieldDependencies]] when
|
|
354
|
+
* establishing / refreshing relationships.
|
|
355
|
+
*/
|
|
229
356
|
function updateAllFields(annotationElementId, txn) {
|
|
230
357
|
doUpdateFields(txn, annotationElementId, undefined, false);
|
|
231
358
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fields.js","sourceRoot":"","sources":["../../../../src/internal/annotations/fields.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { FieldPrimitiveValue, FieldPropertyType, FieldRun, FieldValue, formatFieldValue, QueryBinder, QueryRowFormat, RelationshipProps, TextBlock, traverseTextBlockComponent } from \"@itwin/core-common\";\r\nimport { IModelDb } from \"../../IModelDb\";\r\nimport { assert, expectDefined, Id64String, Logger } from \"@itwin/core-bentley\";\r\nimport { BackendLoggerCategory } from \"../../BackendLoggerCategory\";\r\nimport { isITextAnnotation } from \"../../annotations/ElementDrivesTextAnnotation\";\r\nimport { AnyClass, EntityClass, PrimitiveType, Property, PropertyType, StructArrayProperty } from \"@itwin/ecschema-metadata\";\r\nimport { reshapePropertyValue } from \"../ECSqlInstanceReshaper\";\r\nimport type { EditTxn } from \"../../EditTxn\";\r\ninterface FieldStructValue { [key: string]: any }\r\n\r\n// An intermediate value obtained while evaluating a FieldPropertyPath.\r\ntype FieldValueType = {\r\n primitive: FieldPrimitiveValue;\r\n struct?: never;\r\n primitiveArray?: never;\r\n structArray?: never;\r\n} | {\r\n primitive?: never;\r\n struct: FieldStructValue;\r\n primitiveArray?: never;\r\n structArray?: never;\r\n} | {\r\n primitive?: never;\r\n struct?: never;\r\n primitiveArray: FieldPrimitiveValue[];\r\n structArray?: never;\r\n} | {\r\n primitive?: never;\r\n struct?: never;\r\n primitiveArray?: never;\r\n structArray: FieldStructValue[];\r\n}\r\n\r\nexport interface UpdateFieldsContext {\r\n readonly hostElementId: Id64String | undefined;\r\n\r\n getProperty(field: FieldRun): FieldValue | undefined\r\n}\r\n\r\n// Resolve the raw primitive value of the property that a field points to.\r\nfunction getFieldPropertyValue(field: FieldRun, iModel: IModelDb): FieldValue | undefined {\r\n const host = field.propertyHost;\r\n const schemaItem = iModel.schemaContext.getSchemaItemSync(host.schemaName, host.className);\r\n if (!EntityClass.isEntityClass(schemaItem)) {\r\n return undefined;\r\n }\r\n\r\n let ecClass: AnyClass = schemaItem;\r\n const { propertyName, accessors } = field.propertyPath;\r\n let ecProp = ecClass.getPropertySync(propertyName);\r\n if (!ecProp) {\r\n return undefined;\r\n }\r\n\r\n const isAspect = ecClass.isSync(\"ElementAspect\", \"BisCore\");\r\n const where = ` WHERE ${isAspect ? \"Element.Id\" : \"ECInstanceId\"}=:elementId`;\r\n // `propertyName` may itself be a struct/array/point/navigation property, so its value can't be\r\n // decomposed into scalar sub-columns ahead of time. Query using the non-deprecated\r\n // UseECSqlPropertyNames format and reshape the value into the legacy UseJsPropertyNames shape using\r\n // ECSchema metadata (see ECSqlInstanceReshaper for why a naive, non-schema-aware rename isn't safe here).\r\n let curValue: FieldValueType | undefined = iModel.withQueryReader(`SELECT ${propertyName} FROM ${host.schemaName}.${host.className} ${where}`, (reader): FieldValueType | undefined => {\r\n if (!reader.step()) {\r\n return undefined;\r\n }\r\n\r\n const rawRootValue = reader.current[0];\r\n if (undefined === rawRootValue) {\r\n return undefined;\r\n }\r\n\r\n ecProp = expectDefined(ecProp);\r\n const rootValue = reshapePropertyValue(rawRootValue, ecProp, iModel);\r\n if (ecProp.isArray()) {\r\n return ecProp.isStruct() ? { structArray: rootValue } : { primitiveArray: rootValue };\r\n }\r\n\r\n if (ecProp.isStruct()) {\r\n ecClass = ecProp.structClass;\r\n return { struct: rootValue };\r\n }\r\n\r\n if (ecProp.isPrimitive()) {\r\n return {\r\n primitive: ecProp.primitiveType === PrimitiveType.DateTime ? new Date(rootValue) : rootValue,\r\n };\r\n }\r\n\r\n return undefined;\r\n }, new QueryBinder().bindId(\"elementId\", host.elementId), { rowFormat: QueryRowFormat.UseECSqlPropertyNames });\r\n\r\n if (undefined === curValue) {\r\n return undefined;\r\n }\r\n\r\n if (accessors) {\r\n for (const accessor of accessors) {\r\n if (undefined !== curValue.primitive) {\r\n // Can't index into a primitive.\r\n return undefined;\r\n }\r\n\r\n if (typeof accessor === \"number\") {\r\n const array: FieldPrimitiveValue[] | FieldStructValue[] | undefined = curValue.primitiveArray ?? curValue.structArray;\r\n if (!array) {\r\n return undefined;\r\n }\r\n\r\n const index: number = accessor < 0 ? (array.length + accessor) : accessor;\r\n const item: FieldPrimitiveValue | FieldStructValue = array[index];\r\n if (undefined === item) {\r\n return undefined;\r\n } else if (curValue.primitiveArray) {\r\n curValue = { primitive: curValue.primitiveArray[index] };\r\n } else {\r\n assert(undefined !== curValue.structArray);\r\n assert(ecProp instanceof StructArrayProperty);\r\n\r\n ecClass = ecProp.structClass;\r\n curValue = { struct: curValue.structArray[index] };\r\n }\r\n } else {\r\n if (undefined === curValue.struct) {\r\n return undefined;\r\n }\r\n\r\n const item: any = curValue.struct[accessor];\r\n if (undefined === item) {\r\n return undefined;\r\n }\r\n\r\n ecProp = ecClass.getPropertySync(accessor);\r\n if (!ecProp) {\r\n return undefined;\r\n }\r\n\r\n if (ecProp.isArray()) {\r\n curValue = ecProp.isStruct() ? { structArray: item } : { primitiveArray: item };\r\n } else if (ecProp.isStruct()) {\r\n ecClass = ecProp.structClass;\r\n curValue = { struct: item };\r\n } else if (ecProp.isPrimitive()) {\r\n curValue = { primitive: item };\r\n } else {\r\n return undefined;\r\n }\r\n }\r\n }\r\n }\r\n\r\n const propertyType = determineFieldPropertyType(ecProp);\r\n if (!propertyType) {\r\n return undefined;\r\n }\r\n\r\n // The ultimate result must be a primitive value.\r\n if (undefined === curValue.primitive) {\r\n return undefined;\r\n }\r\n\r\n return { value: curValue.primitive, type: propertyType };\r\n}\r\n\r\nfunction determineFieldPropertyType(prop: Property): FieldPropertyType | undefined {\r\n if (prop.isEnumeration()) {\r\n switch (prop.propertyType) {\r\n case PropertyType.Integer_Enumeration:\r\n return \"int-enum\";\r\n case PropertyType.String_Enumeration:\r\n return \"string-enum\";\r\n default:\r\n return undefined;\r\n }\r\n }\r\n\r\n if (prop.isPrimitive()) {\r\n switch (prop.primitiveType) {\r\n case PrimitiveType.Boolean:\r\n return \"boolean\";\r\n case PrimitiveType.String:\r\n return prop.extendedTypeName === \"DateTime\" ? \"datetime\" : \"string\";\r\n case PrimitiveType.DateTime:\r\n return \"datetime\";\r\n case PrimitiveType.Double:\r\n case PrimitiveType.Long:\r\n return \"quantity\";\r\n case PrimitiveType.Point2d:\r\n case PrimitiveType.Point3d:\r\n return \"coordinate\";\r\n case PrimitiveType.Binary:\r\n return prop.extendedTypeName === \"BeGuid\" ? \"string\" : undefined;\r\n case PrimitiveType.Integer:\r\n case PrimitiveType.Long:\r\n return \"string\";\r\n default:\r\n return undefined;\r\n }\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\nexport function createUpdateContext(hostElementId: string | undefined, iModel: IModelDb, deleted: boolean): UpdateFieldsContext {\r\n return {\r\n hostElementId,\r\n getProperty: deleted ? () => undefined : (field) => getFieldPropertyValue(field, iModel),\r\n };\r\n}\r\n\r\n// Recompute the display value of a single field, return false if it couldn't be evaluated.\r\nexport function updateField(field: FieldRun, context: UpdateFieldsContext): boolean {\r\n if (context.hostElementId && context.hostElementId !== field.propertyHost.elementId) {\r\n return false;\r\n }\r\n\r\n let newContent: string | undefined;\r\n try {\r\n const propValue = context.getProperty(field);\r\n if (undefined !== propValue) {\r\n newContent = formatFieldValue(propValue, field.formatOptions);\r\n }\r\n } catch (err) {\r\n Logger.logError(BackendLoggerCategory.IModelDb, err);\r\n }\r\n\r\n newContent = newContent ?? FieldRun.invalidContentIndicator;\r\n if (newContent === field.cachedContent) {\r\n return false;\r\n }\r\n\r\n field.setCachedContent(newContent);\r\n return true;\r\n}\r\n\r\n// Re-evaluates the display strings for all fields that target the element specified by `context` and returns the number\r\n// of fields whose display strings changed as a result.\r\nexport function updateFields(textBlock: TextBlock, context: UpdateFieldsContext): number {\r\n let numUpdated = 0;\r\n for (const { child } of traverseTextBlockComponent(textBlock)) {\r\n if (child.type === \"field\" && updateField(child, context)) {\r\n ++numUpdated;\r\n }\r\n }\r\n\r\n return numUpdated;\r\n}\r\n\r\nfunction doUpdateFields(txn: EditTxn, annotationId: Id64String, sourceId: Id64String | undefined, deleted: boolean): void {\r\n const iModel = txn.iModel;\r\n try {\r\n const target = iModel.elements.getElement(annotationId);\r\n if (isITextAnnotation(target)) {\r\n const context = createUpdateContext(sourceId, iModel, deleted);\r\n const updatedBlocks = [];\r\n for (const block of target.getTextBlocks()) {\r\n if (updateFields(block.textBlock, context)) {\r\n updatedBlocks.push(block);\r\n }\r\n }\r\n\r\n if (updatedBlocks.length > 0) {\r\n target.updateTextBlocks(updatedBlocks);\r\n target.update(txn);\r\n }\r\n }\r\n } catch (err) {\r\n Logger.logError(BackendLoggerCategory.IModelDb, err);\r\n }\r\n}\r\n\r\n// Invoked by ElementDrivesTextAnnotation to update fields in target element when source element changes or is deleted.\r\nexport function updateElementFields(props: RelationshipProps, txn: EditTxn, deleted: boolean): void {\r\n doUpdateFields(txn, props.targetId, props.sourceId, deleted);\r\n}\r\n\r\nexport function updateAllFields(annotationElementId: Id64String, txn: EditTxn): void {\r\n doUpdateFields(txn, annotationElementId, undefined, false);\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"fields.js","sourceRoot":"","sources":["../../../../src/internal/annotations/fields.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { FieldPrimitiveValue, FieldPropertyType, FieldRun, FieldValue, formatFieldValue, FormatMagnitude, QueryBinder, QueryRowFormat, RelationshipProps, TextBlock, traverseTextBlockComponent } from \"@itwin/core-common\";\r\nimport { IModelDb } from \"../../IModelDb\";\r\nimport { assert, expectDefined, Id64String, Logger } from \"@itwin/core-bentley\";\r\nimport { BackendLoggerCategory } from \"../../BackendLoggerCategory\";\r\nimport { isITextAnnotation } from \"../../annotations/ElementDrivesTextAnnotation\";\r\nimport { AnyClass, EntityClass, PrimitiveType, Property, PropertyType, StructArrayProperty } from \"@itwin/ecschema-metadata\";\r\nimport { reshapePropertyValue } from \"../ECSqlInstanceReshaper\";\r\nimport { FieldFormatting, getFieldFormatting, lookupFieldSpec, ResolvedFieldValue } from \"./fieldSpecs\";\r\nimport type { EditTxn } from \"../../EditTxn\";\r\ninterface FieldStructValue { [key: string]: any }\r\n\r\n// An intermediate value obtained while evaluating a FieldPropertyPath.\r\ntype FieldValueType = {\r\n primitive: FieldPrimitiveValue;\r\n struct?: never;\r\n primitiveArray?: never;\r\n structArray?: never;\r\n} | {\r\n primitive?: never;\r\n struct: FieldStructValue;\r\n primitiveArray?: never;\r\n structArray?: never;\r\n} | {\r\n primitive?: never;\r\n struct?: never;\r\n primitiveArray: FieldPrimitiveValue[];\r\n structArray?: never;\r\n} | {\r\n primitive?: never;\r\n struct?: never;\r\n primitiveArray?: never;\r\n structArray: FieldStructValue[];\r\n}\r\n\r\n/** The per-evaluation state [[updateField]] needs: which element's fields to recompute, how to\r\n * read a field's property value, and how to format quantities.\r\n */\r\nexport interface UpdateFieldsContext {\r\n /** When set, only fields whose [FieldPropertyHost.elementId]($common) matches are recomputed —\r\n * an edit to one source element leaves the annotation's other fields untouched.\r\n */\r\n readonly hostElementId: Id64String | undefined;\r\n\r\n /** Reads the value a field points at, or `undefined` if it cannot be resolved — including\r\n * every field when the source element was deleted.\r\n */\r\n getProperty(field: FieldRun): ResolvedFieldValue | undefined;\r\n\r\n /** The formats `\"quantity\"` and `\"coordinate\"` values resolve through. [[updateField]] builds\r\n * a [FormatterSpec]($core-quantity) per field from the FormatSet named by\r\n * [QuantityFieldFormatOptions.formatSet]($common), falling back to the adopted FormatSet and\r\n * the schemas; a value none of them can format falls back to `value.toString()`.\r\n * [[createUpdateContext]] always supplies the iModel's formatting; only hand-built contexts in\r\n * tests that never format a quantity leave it out.\r\n */\r\n readonly formatting?: FieldFormatting;\r\n}\r\n\r\n// Resolves the property a field points at into a [[ResolvedFieldValue]] — primitive value plus, for\r\n// `\"quantity\"` / `\"coordinate\"` types, the property-side KoQ and persistence unit.\r\nfunction getFieldPropertyValue(field: FieldRun, iModel: IModelDb): ResolvedFieldValue | undefined {\r\n const host = field.propertyHost;\r\n const schemaItem = iModel.schemaContext.getSchemaItemSync(host.schemaName, host.className);\r\n if (!EntityClass.isEntityClass(schemaItem)) {\r\n return undefined;\r\n }\r\n\r\n let ecClass: AnyClass = schemaItem;\r\n const { propertyName, accessors, jsonAccessors } = field.propertyPath;\r\n let ecProp = ecClass.getPropertySync(propertyName);\r\n if (!ecProp) {\r\n return undefined;\r\n }\r\n\r\n const isAspect = ecClass.isSync(\"ElementAspect\", \"BisCore\");\r\n const where = ` WHERE ${isAspect ? \"Element.Id\" : \"ECInstanceId\"}=:elementId`;\r\n // `propertyName` may itself be a struct/array/point/navigation property, so its value can't be\r\n // decomposed into scalar sub-columns ahead of time. Query using the non-deprecated\r\n // UseECSqlPropertyNames format and reshape the value into the legacy UseJsPropertyNames shape using\r\n // ECSchema metadata (see ECSqlInstanceReshaper for why a naive, non-schema-aware rename isn't safe here).\r\n let curValue: FieldValueType | undefined = iModel.withQueryReader(`SELECT ${propertyName} FROM ${host.schemaName}.${host.className} ${where}`, (reader): FieldValueType | undefined => {\r\n if (!reader.step()) {\r\n return undefined;\r\n }\r\n\r\n const rawRootValue = reader.current[0];\r\n if (undefined === rawRootValue) {\r\n return undefined;\r\n }\r\n\r\n ecProp = expectDefined(ecProp);\r\n const rootValue = reshapePropertyValue(rawRootValue, ecProp, iModel);\r\n if (ecProp.isArray()) {\r\n return ecProp.isStruct() ? { structArray: rootValue } : { primitiveArray: rootValue };\r\n }\r\n\r\n if (ecProp.isStruct()) {\r\n ecClass = ecProp.structClass;\r\n return { struct: rootValue };\r\n }\r\n\r\n if (ecProp.isPrimitive()) {\r\n return {\r\n primitive: ecProp.primitiveType === PrimitiveType.DateTime ? new Date(rootValue) : rootValue,\r\n };\r\n }\r\n\r\n return undefined;\r\n }, new QueryBinder().bindId(\"elementId\", host.elementId), { rowFormat: QueryRowFormat.UseECSqlPropertyNames });\r\n\r\n if (undefined === curValue) {\r\n return undefined;\r\n }\r\n\r\n if (accessors) {\r\n for (const accessor of accessors) {\r\n if (undefined !== curValue.primitive) {\r\n // Can't index into a primitive.\r\n return undefined;\r\n }\r\n\r\n if (typeof accessor === \"number\") {\r\n const array: FieldPrimitiveValue[] | FieldStructValue[] | undefined = curValue.primitiveArray ?? curValue.structArray;\r\n if (!array) {\r\n return undefined;\r\n }\r\n\r\n const index: number = accessor < 0 ? (array.length + accessor) : accessor;\r\n const item: FieldPrimitiveValue | FieldStructValue = array[index];\r\n if (undefined === item) {\r\n return undefined;\r\n } else if (curValue.primitiveArray) {\r\n curValue = { primitive: curValue.primitiveArray[index] };\r\n } else {\r\n assert(undefined !== curValue.structArray);\r\n assert(ecProp instanceof StructArrayProperty);\r\n\r\n ecClass = ecProp.structClass;\r\n curValue = { struct: curValue.structArray[index] };\r\n }\r\n } else {\r\n if (undefined === curValue.struct) {\r\n return undefined;\r\n }\r\n\r\n const item: any = curValue.struct[accessor];\r\n if (undefined === item) {\r\n return undefined;\r\n }\r\n\r\n ecProp = ecClass.getPropertySync(accessor);\r\n if (!ecProp) {\r\n return undefined;\r\n }\r\n\r\n if (ecProp.isArray()) {\r\n curValue = ecProp.isStruct() ? { structArray: item } : { primitiveArray: item };\r\n } else if (ecProp.isStruct()) {\r\n ecClass = ecProp.structClass;\r\n curValue = { struct: item };\r\n } else if (ecProp.isPrimitive()) {\r\n curValue = { primitive: item };\r\n } else {\r\n return undefined;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // The ultimate result must be a primitive value.\r\n if (undefined === curValue.primitive) {\r\n return undefined;\r\n }\r\n\r\n // `jsonAccessors` continue the walk inside a serialized JSON string. There is no schema behind a JSON blob, so the\r\n // property must declare itself as JSON via its extended type; an un-indexed JSON property resolves to the raw string.\r\n if (jsonAccessors && jsonAccessors.length > 0) {\r\n if (!isJsonProperty(ecProp) || typeof curValue.primitive !== \"string\") {\r\n return undefined;\r\n }\r\n\r\n return readJsonLeaf(curValue.primitive, jsonAccessors);\r\n }\r\n\r\n const propertyType = determineFieldPropertyType(ecProp);\r\n if (!propertyType) {\r\n return undefined;\r\n }\r\n\r\n // Property-side KoQ + persistence unit only. Overrides in `formatOptions.quantity` are\r\n // merged at formatting time (see `collectFieldQuantityPairs`) so these serve as the fallback\r\n // when the override doesn't resolve.\r\n let kindOfQuantityFullName: string | undefined;\r\n let persistenceUnitFullName: string | undefined;\r\n if (propertyType === \"quantity\" || propertyType === \"coordinate\") {\r\n const koq = ecProp.kindOfQuantity ? ecProp.getKindOfQuantitySync() : undefined;\r\n kindOfQuantityFullName = koq?.fullName;\r\n persistenceUnitFullName = koq?.persistenceUnit?.fullName;\r\n }\r\n\r\n return { value: curValue.primitive, type: propertyType, kindOfQuantityFullName, persistenceUnitFullName };\r\n}\r\n\r\nfunction isJsonProperty(prop: Property): boolean {\r\n return prop.isPrimitive() && !prop.isArray() && prop.primitiveType === PrimitiveType.String && prop.extendedTypeName === \"Json\";\r\n}\r\n\r\n/** Applies [FieldPropertyPath.jsonAccessors]($common) to a string property holding serialized JSON,\r\n * as a walk entirely separate from the EC one: there is no schema behind a JSON blob, so no EC\r\n * metadata is consulted.\r\n *\r\n * Returns `undefined` when `raw` is not JSON, when an accessor does not resolve, or when the path\r\n * stops anywhere but a scalar — including on a JSON `null`, which is not a\r\n * [FieldPrimitiveValue]($common).\r\n */\r\nfunction readJsonLeaf(raw: string, accessors: ReadonlyArray<string | number>): FieldValue | undefined {\r\n let cur: any;\r\n try {\r\n cur = JSON.parse(raw);\r\n } catch {\r\n // Not valid JSON; treat as a normal string.\r\n return undefined;\r\n }\r\n\r\n for (const accessor of accessors) {\r\n // A number indexes an array and a string keys an object; anything else doesn't resolve.\r\n const isIndex = typeof accessor === \"number\";\r\n if (typeof cur !== \"object\" || null === cur || Array.isArray(cur) !== isIndex) {\r\n return undefined;\r\n }\r\n\r\n if (isIndex) {\r\n cur = cur[accessor < 0 ? cur.length + accessor : accessor];\r\n } else {\r\n // Own keys only, so a key missing from the JSON can't resolve through Object.prototype.\r\n cur = Object.hasOwn(cur, accessor) ? cur[accessor] : undefined;\r\n }\r\n }\r\n\r\n // JSON carries no type metadata, so the leaf's JavaScript type decides the field property type.\r\n // A numeric leaf is typed `\"quantity\"` but has no property-side KoQ, so only the field's own\r\n // `kindOfQuantity` + `persistenceUnit` overrides can name a format for it.\r\n switch (typeof cur) {\r\n case \"number\":\r\n return { value: cur, type: \"quantity\" };\r\n case \"boolean\":\r\n return { value: cur, type: \"boolean\" };\r\n case \"string\":\r\n return { value: cur, type: \"string\" };\r\n default:\r\n return undefined;\r\n }\r\n}\r\n\r\nfunction determineFieldPropertyType(prop: Property): FieldPropertyType | undefined {\r\n if (prop.isEnumeration()) {\r\n switch (prop.propertyType) {\r\n case PropertyType.Integer_Enumeration:\r\n return \"int-enum\";\r\n case PropertyType.String_Enumeration:\r\n return \"string-enum\";\r\n default:\r\n return undefined;\r\n }\r\n }\r\n\r\n if (prop.isPrimitive()) {\r\n switch (prop.primitiveType) {\r\n case PrimitiveType.Boolean:\r\n return \"boolean\";\r\n case PrimitiveType.String:\r\n return prop.extendedTypeName === \"DateTime\" ? \"datetime\" : \"string\";\r\n case PrimitiveType.DateTime:\r\n return \"datetime\";\r\n case PrimitiveType.Double:\r\n case PrimitiveType.Integer:\r\n case PrimitiveType.Long:\r\n // Any numeric property is a potential quantity. Classifying one as \"quantity\" is not an\r\n // assertion that it *has* units -- it only decides whether the KoQ/units pipeline is\r\n // consulted. A number that resolves no spec falls back to the same `toString()` the\r\n // \"string\" formatter would have produced, so counts and identifiers still render bare.\r\n return \"quantity\";\r\n case PrimitiveType.Point2d:\r\n case PrimitiveType.Point3d:\r\n return \"coordinate\";\r\n case PrimitiveType.Binary:\r\n return prop.extendedTypeName === \"BeGuid\" ? \"string\" : undefined;\r\n default:\r\n return undefined;\r\n }\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\nexport function createUpdateContext(hostElementId: string | undefined, iModel: IModelDb, deleted: boolean): UpdateFieldsContext {\r\n return {\r\n hostElementId,\r\n getProperty: deleted ? () => undefined : (field) => getFieldPropertyValue(field, iModel),\r\n formatting: getFieldFormatting(iModel),\r\n };\r\n}\r\n\r\n/** Resolves the [FormatterSpec]($core-quantity) this field should render its magnitudes through,\r\n * returning a callback bound to it, or `undefined` when not a quantity or coordinate, no formats\r\n * were supplied, or no format resolves for any of the (KindOfQuantity, persistence unit) pairs the\r\n * field may format through. In that last case the shortfall is logged: a persistence unit or\r\n * format unit outside the bundled BIS set, a KindOfQuantity with no presentation format, or a\r\n * format whose units belong to a different phenomenon than the persisted value. A\r\n * `persistenceUnit` override that disagrees with the property's own unit is ignored and logged\r\n * too; the property's unit is what the stored magnitude means.\r\n */\r\nfunction resolveFormatMagnitude(value: ResolvedFieldValue, field: FieldRun, context: UpdateFieldsContext): FormatMagnitude | undefined {\r\n const formatting = context.formatting;\r\n if (!formatting || (value.type !== \"quantity\" && value.type !== \"coordinate\")) {\r\n return undefined;\r\n }\r\n\r\n const quantityOptions = field.formatOptions?.quantity;\r\n const { spec, candidates, ignoredPersistenceUnit } = lookupFieldSpec(quantityOptions, value, formatting);\r\n if (ignoredPersistenceUnit) {\r\n Logger.logWarning(BackendLoggerCategory.IModelDb, \"Ignoring persistenceUnit override that disagrees with the property's own persistence unit\", () => ({\r\n elementId: field.propertyHost.elementId,\r\n propertyName: field.propertyPath.propertyName,\r\n persistenceUnit: ignoredPersistenceUnit,\r\n propertyPersistenceUnit: value.persistenceUnitFullName,\r\n }));\r\n }\r\n if (!spec) {\r\n if (candidates.length > 0) {\r\n Logger.logWarning(BackendLoggerCategory.IModelDb, \"No format resolved for text annotation field; rendering raw value\", () => ({\r\n elementId: field.propertyHost.elementId,\r\n propertyName: field.propertyPath.propertyName,\r\n formatSet: quantityOptions?.formatSet,\r\n tried: candidates.map((c) => `${c.name} in ${c.persistenceUnitName}`),\r\n }));\r\n }\r\n return undefined;\r\n }\r\n\r\n return (magnitude) => spec.applyFormatting(magnitude);\r\n}\r\n\r\n/** Recomputes a single field's cached display string synchronously. Returns true iff\r\n * cachedContent changed.\r\n *\r\n * Resolving the property value and formatting it are both fallible. A failure of either is\r\n * logged and degrades *this* field to [FieldRun.invalidContentIndicator]($common); other\r\n * fields in the same block are unaffected.\r\n */\r\nexport function updateField(field: FieldRun, context: UpdateFieldsContext): boolean {\r\n if (context.hostElementId && context.hostElementId !== field.propertyHost.elementId) {\r\n return false;\r\n }\r\n\r\n let newContent: string | undefined;\r\n try {\r\n const propValue = context.getProperty(field);\r\n if (undefined !== propValue) {\r\n newContent = formatFieldValue({\r\n value: propValue,\r\n options: field.formatOptions,\r\n formatMagnitude: resolveFormatMagnitude(propValue, field, context),\r\n });\r\n }\r\n } catch (err) {\r\n Logger.logError(BackendLoggerCategory.IModelDb, err);\r\n }\r\n\r\n newContent = newContent ?? FieldRun.invalidContentIndicator;\r\n if (newContent === field.cachedContent) {\r\n return false;\r\n }\r\n\r\n field.setCachedContent(newContent);\r\n return true;\r\n}\r\n\r\n/** Re-evaluates every [FieldRun]($common) in `textBlock` synchronously and returns the number\r\n * whose cached display string changed. Fields targeting an element other than\r\n * `context.hostElementId` (when set) are skipped.\r\n */\r\nexport function updateFields(textBlock: TextBlock, context: UpdateFieldsContext): number {\r\n let numUpdated = 0;\r\n for (const { child } of traverseTextBlockComponent(textBlock)) {\r\n if (child.type === \"field\" && updateField(child, context)) {\r\n ++numUpdated;\r\n }\r\n }\r\n\r\n return numUpdated;\r\n}\r\n\r\nfunction doUpdateFields(txn: EditTxn, annotationId: Id64String, sourceId: Id64String | undefined, deleted: boolean): void {\r\n const iModel = txn.iModel;\r\n try {\r\n const target = iModel.elements.getElement(annotationId);\r\n if (isITextAnnotation(target)) {\r\n const context = createUpdateContext(sourceId, iModel, deleted);\r\n const updatedBlocks = [];\r\n for (const block of target.getTextBlocks()) {\r\n if (updateFields(block.textBlock, context)) {\r\n updatedBlocks.push(block);\r\n }\r\n }\r\n\r\n if (updatedBlocks.length > 0) {\r\n target.updateTextBlocks(updatedBlocks);\r\n target.update(txn);\r\n }\r\n }\r\n } catch (err) {\r\n Logger.logError(BackendLoggerCategory.IModelDb, err);\r\n }\r\n}\r\n\r\n/** Re-evaluates the fields of the `props.targetId` annotation in response to a source-element\r\n * change (`deleted=false`) or delete (`deleted=true`). Invoked from\r\n * [[ElementDrivesTextAnnotation.onRootChangedArg]] / `onDeletedDependencyArg`.\r\n */\r\nexport function updateElementFields(props: RelationshipProps, txn: EditTxn, deleted: boolean): void {\r\n doUpdateFields(txn, props.targetId, props.sourceId, deleted);\r\n}\r\n\r\n/** Re-evaluates every field of the given annotation element against its current property\r\n * values. Invoked from [[ElementDrivesTextAnnotation.updateFieldDependencies]] when\r\n * establishing / refreshing relationships.\r\n */\r\nexport function updateAllFields(annotationElementId: Id64String, txn: EditTxn): void {\r\n doUpdateFields(txn, annotationElementId, undefined, false);\r\n}\r\n"]}
|
package/lib/esm/ECDb.d.ts
CHANGED
|
@@ -260,11 +260,13 @@ export declare class ECDb implements Disposable {
|
|
|
260
260
|
prepareSqliteStatement(sql: string, logErrors?: boolean): SqliteStatement;
|
|
261
261
|
/** @internal */
|
|
262
262
|
get [_nativeDb](): IModelJsNative.ECDb;
|
|
263
|
-
/**
|
|
263
|
+
/** Creates a reader for asynchronous ECSQL query execution.
|
|
264
|
+
* Execution starts when the reader is consumed using asynchronous iteration or awaited calls to `step()` or `toArray()`.
|
|
265
|
+
* Results are fetched and buffered in batches. For synchronous, callback-scoped execution, use [[withQueryReader]].
|
|
264
266
|
*
|
|
265
267
|
* See also:
|
|
266
|
-
* - [
|
|
267
|
-
* - [
|
|
268
|
+
* - [Choosing a query reader]($docs/learning/backend/ExecutingECSQL)
|
|
269
|
+
* - [Asynchronous query examples]($docs/learning/ECSQLCodeExamples)
|
|
268
270
|
* - [ECSQL Row Format]($docs/learning/ECSQLRowFormat)
|
|
269
271
|
*
|
|
270
272
|
* @param params The values to bind to the parameters (if the ECSQL has any).
|
|
@@ -273,11 +275,14 @@ export declare class ECDb implements Disposable {
|
|
|
273
275
|
* @public
|
|
274
276
|
* */
|
|
275
277
|
createQueryReader(ecsql: string, params?: QueryBinder, config?: QueryOptions): ECSqlReader;
|
|
276
|
-
/**
|
|
278
|
+
/** Executes a callback with a synchronous ECSQL reader on the owning database connection.
|
|
279
|
+
* The reader steps one row at a time without buffering result batches. Finish using it before the callback completes.
|
|
280
|
+
* Return materialized rows or computed values rather than the reader. For asynchronous execution, use [[createQueryReader]].
|
|
281
|
+
* The prepared statement may be reused from the statement cache between completed calls.
|
|
277
282
|
*
|
|
278
283
|
* See also:
|
|
279
|
-
* - [
|
|
280
|
-
* - [
|
|
284
|
+
* - [Choosing a query reader]($docs/learning/backend/ExecutingECSQL)
|
|
285
|
+
* - [Synchronous query examples]($docs/learning/backend/WithQueryReaderCodeExamples)
|
|
281
286
|
* - [ECSQL Row Format]($docs/learning/ECSQLRowFormat)
|
|
282
287
|
* @param ecsql The ECSQL query to execute.
|
|
283
288
|
* @param callback the callback to invoke on the prepared ECSqlSyncReader
|
package/lib/esm/ECDb.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ECDb.d.ts","sourceRoot":"","sources":["../../src/ECDb.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ECDb.d.ts","sourceRoot":"","sources":["../../src/ECDb.ts"],"names":[],"mappings":"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"}
|
package/lib/esm/ECDb.js
CHANGED
|
@@ -473,11 +473,13 @@ export class ECDb {
|
|
|
473
473
|
assert(undefined !== this._nativeDb);
|
|
474
474
|
return this._nativeDb;
|
|
475
475
|
}
|
|
476
|
-
/**
|
|
476
|
+
/** Creates a reader for asynchronous ECSQL query execution.
|
|
477
|
+
* Execution starts when the reader is consumed using asynchronous iteration or awaited calls to `step()` or `toArray()`.
|
|
478
|
+
* Results are fetched and buffered in batches. For synchronous, callback-scoped execution, use [[withQueryReader]].
|
|
477
479
|
*
|
|
478
480
|
* See also:
|
|
479
|
-
* - [
|
|
480
|
-
* - [
|
|
481
|
+
* - [Choosing a query reader]($docs/learning/backend/ExecutingECSQL)
|
|
482
|
+
* - [Asynchronous query examples]($docs/learning/ECSQLCodeExamples)
|
|
481
483
|
* - [ECSQL Row Format]($docs/learning/ECSQLRowFormat)
|
|
482
484
|
*
|
|
483
485
|
* @param params The values to bind to the parameters (if the ECSQL has any).
|
|
@@ -496,11 +498,14 @@ export class ECDb {
|
|
|
496
498
|
};
|
|
497
499
|
return new ECSqlReader(executor, ecsql, params, config);
|
|
498
500
|
}
|
|
499
|
-
/**
|
|
501
|
+
/** Executes a callback with a synchronous ECSQL reader on the owning database connection.
|
|
502
|
+
* The reader steps one row at a time without buffering result batches. Finish using it before the callback completes.
|
|
503
|
+
* Return materialized rows or computed values rather than the reader. For asynchronous execution, use [[createQueryReader]].
|
|
504
|
+
* The prepared statement may be reused from the statement cache between completed calls.
|
|
500
505
|
*
|
|
501
506
|
* See also:
|
|
502
|
-
* - [
|
|
503
|
-
* - [
|
|
507
|
+
* - [Choosing a query reader]($docs/learning/backend/ExecutingECSQL)
|
|
508
|
+
* - [Synchronous query examples]($docs/learning/backend/WithQueryReaderCodeExamples)
|
|
504
509
|
* - [ECSQL Row Format]($docs/learning/ECSQLRowFormat)
|
|
505
510
|
* @param ecsql The ECSQL query to execute.
|
|
506
511
|
* @param callback the callback to invoke on the prepared ECSqlSyncReader
|