@itwin/ecschema-metadata 5.12.0-dev.8 → 5.13.0-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -1
- package/lib/cjs/Localization/SchemaLocalization.d.ts +1 -1
- package/lib/cjs/Localization/SchemaLocalization.d.ts.map +1 -1
- package/lib/cjs/Localization/SchemaLocalization.js.map +1 -1
- package/lib/cjs/SchemaView/SchemaManifest.d.ts +81 -0
- package/lib/cjs/SchemaView/SchemaManifest.d.ts.map +1 -0
- package/lib/cjs/SchemaView/SchemaManifest.js +131 -0
- package/lib/cjs/SchemaView/SchemaManifest.js.map +1 -0
- package/lib/cjs/{SchemaView.d.ts → SchemaView/SchemaView.d.ts} +23 -90
- package/lib/cjs/SchemaView/SchemaView.d.ts.map +1 -0
- package/lib/cjs/{SchemaView.js → SchemaView/SchemaView.js} +32 -198
- package/lib/cjs/SchemaView/SchemaView.js.map +1 -0
- package/lib/cjs/SchemaView/SchemaViewBinaryReader.d.ts +37 -0
- package/lib/cjs/SchemaView/SchemaViewBinaryReader.d.ts.map +1 -0
- package/lib/cjs/{SchemaViewBinaryReader.js → SchemaView/SchemaViewBinaryReader.js} +84 -43
- package/lib/cjs/SchemaView/SchemaViewBinaryReader.js.map +1 -0
- package/lib/cjs/SchemaView/SchemaViewBuilder.d.ts +116 -0
- package/lib/cjs/SchemaView/SchemaViewBuilder.d.ts.map +1 -0
- package/lib/cjs/SchemaView/SchemaViewBuilder.js +230 -0
- package/lib/cjs/SchemaView/SchemaViewBuilder.js.map +1 -0
- package/lib/cjs/{SchemaViewInterfaces.d.ts → SchemaView/SchemaViewInterfaces.d.ts} +1 -1
- package/lib/cjs/SchemaView/SchemaViewInterfaces.d.ts.map +1 -0
- package/lib/cjs/SchemaView/SchemaViewInterfaces.js.map +1 -0
- package/lib/cjs/SchemaView/SchemaViewManager.d.ts +114 -0
- package/lib/cjs/SchemaView/SchemaViewManager.d.ts.map +1 -0
- package/lib/cjs/SchemaView/SchemaViewManager.js +184 -0
- package/lib/cjs/SchemaView/SchemaViewManager.js.map +1 -0
- package/lib/cjs/ecschema-metadata.d.ts +6 -3
- package/lib/cjs/ecschema-metadata.d.ts.map +1 -1
- package/lib/cjs/ecschema-metadata.js +6 -3
- package/lib/cjs/ecschema-metadata.js.map +1 -1
- package/lib/esm/Localization/SchemaLocalization.d.ts +1 -1
- package/lib/esm/Localization/SchemaLocalization.d.ts.map +1 -1
- package/lib/esm/Localization/SchemaLocalization.js.map +1 -1
- package/lib/esm/SchemaView/SchemaManifest.d.ts +81 -0
- package/lib/esm/SchemaView/SchemaManifest.d.ts.map +1 -0
- package/lib/esm/SchemaView/SchemaManifest.js +127 -0
- package/lib/esm/SchemaView/SchemaManifest.js.map +1 -0
- package/lib/esm/{SchemaView.d.ts → SchemaView/SchemaView.d.ts} +23 -90
- package/lib/esm/SchemaView/SchemaView.d.ts.map +1 -0
- package/lib/esm/{SchemaView.js → SchemaView/SchemaView.js} +32 -197
- package/lib/esm/SchemaView/SchemaView.js.map +1 -0
- package/lib/esm/SchemaView/SchemaViewBinaryReader.d.ts +37 -0
- package/lib/esm/SchemaView/SchemaViewBinaryReader.d.ts.map +1 -0
- package/lib/esm/{SchemaViewBinaryReader.js → SchemaView/SchemaViewBinaryReader.js} +82 -43
- package/lib/esm/SchemaView/SchemaViewBinaryReader.js.map +1 -0
- package/lib/esm/SchemaView/SchemaViewBuilder.d.ts +116 -0
- package/lib/esm/SchemaView/SchemaViewBuilder.d.ts.map +1 -0
- package/lib/esm/SchemaView/SchemaViewBuilder.js +226 -0
- package/lib/esm/SchemaView/SchemaViewBuilder.js.map +1 -0
- package/lib/esm/{SchemaViewInterfaces.d.ts → SchemaView/SchemaViewInterfaces.d.ts} +1 -1
- package/lib/esm/SchemaView/SchemaViewInterfaces.d.ts.map +1 -0
- package/lib/esm/SchemaView/SchemaViewInterfaces.js.map +1 -0
- package/lib/esm/SchemaView/SchemaViewManager.d.ts +114 -0
- package/lib/esm/SchemaView/SchemaViewManager.d.ts.map +1 -0
- package/lib/esm/SchemaView/SchemaViewManager.js +180 -0
- package/lib/esm/SchemaView/SchemaViewManager.js.map +1 -0
- package/lib/esm/ecschema-metadata.d.ts +6 -3
- package/lib/esm/ecschema-metadata.d.ts.map +1 -1
- package/lib/esm/ecschema-metadata.js +6 -3
- package/lib/esm/ecschema-metadata.js.map +1 -1
- package/package.json +8 -8
- package/lib/cjs/SchemaView.d.ts.map +0 -1
- package/lib/cjs/SchemaView.js.map +0 -1
- package/lib/cjs/SchemaViewBinaryReader.d.ts +0 -16
- package/lib/cjs/SchemaViewBinaryReader.d.ts.map +0 -1
- package/lib/cjs/SchemaViewBinaryReader.js.map +0 -1
- package/lib/cjs/SchemaViewInterfaces.d.ts.map +0 -1
- package/lib/cjs/SchemaViewInterfaces.js.map +0 -1
- package/lib/esm/SchemaView.d.ts.map +0 -1
- package/lib/esm/SchemaView.js.map +0 -1
- package/lib/esm/SchemaViewBinaryReader.d.ts +0 -16
- package/lib/esm/SchemaViewBinaryReader.d.ts.map +0 -1
- package/lib/esm/SchemaViewBinaryReader.js.map +0 -1
- package/lib/esm/SchemaViewInterfaces.d.ts.map +0 -1
- package/lib/esm/SchemaViewInterfaces.js.map +0 -1
- /package/lib/cjs/{SchemaViewInterfaces.js → SchemaView/SchemaViewInterfaces.js} +0 -0
- /package/lib/esm/{SchemaViewInterfaces.js → SchemaView/SchemaViewInterfaces.js} +0 -0
|
@@ -0,0 +1,226 @@
|
|
|
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
|
+
/** @packageDocumentation
|
|
6
|
+
* @module Schema
|
|
7
|
+
*/
|
|
8
|
+
import { SchemaView } from "./SchemaView";
|
|
9
|
+
/** Builder for constructing an immutable `SchemaView`.
|
|
10
|
+
*
|
|
11
|
+
* Collects data during binary blob parsing, then freezes it into a view.
|
|
12
|
+
* Handles string interning and property definition deduplication.
|
|
13
|
+
*
|
|
14
|
+
* Consumers should not use this directly - read views via `IModelDb.getSchemaView`
|
|
15
|
+
* / `IModelConnection.getSchemaView` (or `SchemaView.fromBinary` if you have a raw blob).
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export class SchemaViewBuilder {
|
|
19
|
+
_strings = [""]; // SID 0 = empty string
|
|
20
|
+
_lowerStrings = [""];
|
|
21
|
+
_stringMap = new Map(); // original value -> SID
|
|
22
|
+
_schemas = [];
|
|
23
|
+
_classes = [];
|
|
24
|
+
_classMixins = [];
|
|
25
|
+
_propDefs = [];
|
|
26
|
+
_propertyRefs = [];
|
|
27
|
+
_relConstraints = [];
|
|
28
|
+
_constraintClassRefs = [];
|
|
29
|
+
_enumerations = [];
|
|
30
|
+
_enumerators = [];
|
|
31
|
+
_koqs = [];
|
|
32
|
+
_propCategories = [];
|
|
33
|
+
// For PropertyDef dedup
|
|
34
|
+
_propDefMap = new Map(); // signature string -> defIdx
|
|
35
|
+
// Lookup maps - owned by the builder so a husk can share and extend them across fragment merges.
|
|
36
|
+
// `build()` and each merge call `extendLookupMaps()`; the view receives these same Map objects
|
|
37
|
+
// via `assembleData()`, so in-place growth is visible.
|
|
38
|
+
_schemaByName = new Map();
|
|
39
|
+
_schemaByAlias = new Map();
|
|
40
|
+
_classByName = new Map();
|
|
41
|
+
_enumByName = new Map();
|
|
42
|
+
_koqByName = new Map();
|
|
43
|
+
_catByName = new Map();
|
|
44
|
+
_lookupMapsBuiltUpto = 0; // number of schemas whose lookup entries are already built
|
|
45
|
+
/** Intern a string, returning its SID. Empty/undefined strings return 0.
|
|
46
|
+
* Interning is case-sensitive - "MyLabel" and "MYLABEL" get distinct SIDs.
|
|
47
|
+
* The `lowerStrings` array provides case-insensitive lookup without mutating display values.
|
|
48
|
+
*/
|
|
49
|
+
internString(value) {
|
|
50
|
+
if (value === undefined || value === "")
|
|
51
|
+
return 0;
|
|
52
|
+
const existing = this._stringMap.get(value);
|
|
53
|
+
if (existing !== undefined)
|
|
54
|
+
return existing;
|
|
55
|
+
const sid = this._strings.length;
|
|
56
|
+
this._strings.push(value);
|
|
57
|
+
this._lowerStrings.push(value.toLowerCase());
|
|
58
|
+
this._stringMap.set(value, sid);
|
|
59
|
+
return sid;
|
|
60
|
+
}
|
|
61
|
+
/** Add a schema. Returns its index. */
|
|
62
|
+
addSchema(data) {
|
|
63
|
+
const idx = this._schemas.length;
|
|
64
|
+
this._schemas.push(data);
|
|
65
|
+
return idx;
|
|
66
|
+
}
|
|
67
|
+
/** Add a class. Returns its index. Must be called after the owning schema. */
|
|
68
|
+
addClass(data) {
|
|
69
|
+
const idx = this._classes.length;
|
|
70
|
+
this._classes.push(data);
|
|
71
|
+
return idx;
|
|
72
|
+
}
|
|
73
|
+
/** Add a property definition with deduplication. Returns the def index (possibly existing). */
|
|
74
|
+
addPropertyDef(data) {
|
|
75
|
+
const sig = this._propDefSignature(data);
|
|
76
|
+
const existing = this._propDefMap.get(sig);
|
|
77
|
+
if (existing !== undefined)
|
|
78
|
+
return existing;
|
|
79
|
+
const idx = this._propDefs.length;
|
|
80
|
+
this._propDefs.push(data);
|
|
81
|
+
this._propDefMap.set(sig, idx);
|
|
82
|
+
return idx;
|
|
83
|
+
}
|
|
84
|
+
/** Append a property reference to the flat refs array. */
|
|
85
|
+
addPropertyRef(ref) {
|
|
86
|
+
this._propertyRefs.push(ref);
|
|
87
|
+
}
|
|
88
|
+
/** Add an enumeration. Returns its index. */
|
|
89
|
+
addEnumeration(data) {
|
|
90
|
+
const idx = this._enumerations.length;
|
|
91
|
+
this._enumerations.push(data);
|
|
92
|
+
return idx;
|
|
93
|
+
}
|
|
94
|
+
/** Append an enumerator to the flat enumerators array. */
|
|
95
|
+
addEnumerator(data) {
|
|
96
|
+
this._enumerators.push(data);
|
|
97
|
+
}
|
|
98
|
+
/** Add a KindOfQuantity. Returns its index. */
|
|
99
|
+
addKoq(data) {
|
|
100
|
+
const idx = this._koqs.length;
|
|
101
|
+
this._koqs.push(data);
|
|
102
|
+
return idx;
|
|
103
|
+
}
|
|
104
|
+
/** Add a PropertyCategory. Returns its index. */
|
|
105
|
+
addPropertyCategory(data) {
|
|
106
|
+
const idx = this._propCategories.length;
|
|
107
|
+
this._propCategories.push(data);
|
|
108
|
+
return idx;
|
|
109
|
+
}
|
|
110
|
+
/** Add a relationship constraint. Returns its index. */
|
|
111
|
+
addRelConstraint(data) {
|
|
112
|
+
const idx = this._relConstraints.length;
|
|
113
|
+
this._relConstraints.push(data);
|
|
114
|
+
return idx;
|
|
115
|
+
}
|
|
116
|
+
/** Append a constraint class reference to the flat array. */
|
|
117
|
+
addConstraintClassRef(classIdx) {
|
|
118
|
+
this._constraintClassRefs.push(classIdx);
|
|
119
|
+
}
|
|
120
|
+
/** Append a mixin class reference to the flat array. */
|
|
121
|
+
addClassMixin(classIdx) {
|
|
122
|
+
this._classMixins.push(classIdx);
|
|
123
|
+
}
|
|
124
|
+
/** The current count of property refs (used to set ownPropStart on ClassData). */
|
|
125
|
+
get propertyRefCount() { return this._propertyRefs.length; }
|
|
126
|
+
/** The current count of enumerators (used to set enumeratorStart on EnumerationData). */
|
|
127
|
+
get enumeratorCount() { return this._enumerators.length; }
|
|
128
|
+
/** The current count of constraint class refs (used to set classRefStart). */
|
|
129
|
+
get constraintClassRefCount() { return this._constraintClassRefs.length; }
|
|
130
|
+
/** The current count of class mixins (used to set mixinStartIdx). */
|
|
131
|
+
get classMixinCount() { return this._classMixins.length; }
|
|
132
|
+
// The counts below are the base indices fragment merging uses to translate a fragment's local
|
|
133
|
+
// indices into global ones.
|
|
134
|
+
/** The current count of schemas. @internal */
|
|
135
|
+
get schemaCount() { return this._schemas.length; }
|
|
136
|
+
/** The current count of classes. @internal */
|
|
137
|
+
get classCount() { return this._classes.length; }
|
|
138
|
+
/** The current count of enumerations. @internal */
|
|
139
|
+
get enumerationCount() { return this._enumerations.length; }
|
|
140
|
+
/** The current count of KindOfQuantities. @internal */
|
|
141
|
+
get koqCount() { return this._koqs.length; }
|
|
142
|
+
/** The current count of property categories. @internal */
|
|
143
|
+
get propCategoryCount() { return this._propCategories.length; }
|
|
144
|
+
/** Get a string by SID. @internal */
|
|
145
|
+
getString(sid) { return this._strings[sid]; }
|
|
146
|
+
/** Replace class data at the given index (used during deferred cross-ref resolution). @internal */
|
|
147
|
+
updateClass(classIdx, data) { this._classes[classIdx] = data; }
|
|
148
|
+
/** Update range fields on a schema (used after all items for a schema are collected). @internal */
|
|
149
|
+
updateSchemaRanges(schemaIdx, ranges) {
|
|
150
|
+
const s = this._schemas[schemaIdx];
|
|
151
|
+
this._schemas[schemaIdx] = { ...s, ...ranges };
|
|
152
|
+
}
|
|
153
|
+
/** Freeze all data and produce an immutable SchemaView. */
|
|
154
|
+
build(schemaToken) {
|
|
155
|
+
this.extendLookupMaps();
|
|
156
|
+
return new SchemaView(this.assembleData(), schemaToken);
|
|
157
|
+
}
|
|
158
|
+
/** Build lookup-map entries for any schemas added since the last call. Idempotent and
|
|
159
|
+
* append-only, so it is safe to call after each fragment merge. A schema's item ranges must
|
|
160
|
+
* already be finalized (via `updateSchemaRanges`) before it is processed.
|
|
161
|
+
* @internal */
|
|
162
|
+
extendLookupMaps() {
|
|
163
|
+
for (let i = this._lookupMapsBuiltUpto; i < this._schemas.length; i++) {
|
|
164
|
+
const s = this._schemas[i];
|
|
165
|
+
this._schemaByName.set(this._lowerStrings[s.nameStringIdx], i);
|
|
166
|
+
if (s.aliasStringIdx !== 0)
|
|
167
|
+
this._schemaByAlias.set(this._lowerStrings[s.aliasStringIdx], i);
|
|
168
|
+
// Build class-by-name map for this schema
|
|
169
|
+
const classMap = new Map();
|
|
170
|
+
for (let c = s.classRangeStart; c < s.classRangeStart + s.classCount; c++)
|
|
171
|
+
classMap.set(this._lowerStrings[this._classes[c].nameStringIdx], c);
|
|
172
|
+
this._classByName.set(i, classMap);
|
|
173
|
+
// Build enum-by-name map for this schema
|
|
174
|
+
const eMap = new Map();
|
|
175
|
+
for (let e = s.enumRangeStart; e < s.enumRangeStart + s.enumCount; e++)
|
|
176
|
+
eMap.set(this._lowerStrings[this._enumerations[e].nameStringIdx], e);
|
|
177
|
+
this._enumByName.set(i, eMap);
|
|
178
|
+
// Build koq-by-name map for this schema
|
|
179
|
+
const kMap = new Map();
|
|
180
|
+
for (let k = s.koqRangeStart; k < s.koqRangeStart + s.koqCount; k++)
|
|
181
|
+
kMap.set(this._lowerStrings[this._koqs[k].nameStringIdx], k);
|
|
182
|
+
this._koqByName.set(i, kMap);
|
|
183
|
+
// Build category-by-name map for this schema
|
|
184
|
+
const cMap = new Map();
|
|
185
|
+
for (let p = s.catRangeStart; p < s.catRangeStart + s.catCount; p++)
|
|
186
|
+
cMap.set(this._lowerStrings[this._propCategories[p].nameStringIdx], p);
|
|
187
|
+
this._catByName.set(i, cMap);
|
|
188
|
+
}
|
|
189
|
+
this._lookupMapsBuiltUpto = this._schemas.length;
|
|
190
|
+
}
|
|
191
|
+
/** Assemble a {@link SchemaViewData} bag that references this builder's live arrays and lookup
|
|
192
|
+
* maps. Continued building - fragment merges that append to the arrays and extend the maps in
|
|
193
|
+
* place - is visible through the shared references, so a husk holding this data sees merged
|
|
194
|
+
* schemas without rebuilding. @internal */
|
|
195
|
+
assembleData() {
|
|
196
|
+
return {
|
|
197
|
+
strings: this._strings,
|
|
198
|
+
lowerStrings: this._lowerStrings,
|
|
199
|
+
schemas: this._schemas,
|
|
200
|
+
classes: this._classes,
|
|
201
|
+
classMixins: this._classMixins,
|
|
202
|
+
propDefs: this._propDefs,
|
|
203
|
+
propertyRefs: this._propertyRefs,
|
|
204
|
+
relConstraints: this._relConstraints,
|
|
205
|
+
constraintClassRefs: this._constraintClassRefs,
|
|
206
|
+
enumerations: this._enumerations,
|
|
207
|
+
enumerators: this._enumerators,
|
|
208
|
+
koqs: this._koqs,
|
|
209
|
+
propCategories: this._propCategories,
|
|
210
|
+
schemaByName: this._schemaByName,
|
|
211
|
+
schemaByAlias: this._schemaByAlias,
|
|
212
|
+
classByName: this._classByName,
|
|
213
|
+
enumByName: this._enumByName,
|
|
214
|
+
koqByName: this._koqByName,
|
|
215
|
+
catByName: this._catByName,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/** Produce a dedup signature for a PropertyDef. Label and priority are excluded because
|
|
219
|
+
* they are per-PropertyRef overrides, not part of the structural definition.
|
|
220
|
+
* Uses SIDs (not lowercase strings) for name/description so that case-preserving names
|
|
221
|
+
* stay distinct - matching the C++ writer's dedup behavior. */
|
|
222
|
+
_propDefSignature(def) {
|
|
223
|
+
return `${def.nameStringIdx}|${def.kind}|${def.primitiveType}|${def.extTypeStringIdx}|${def.enumIdx}|${def.koqIdx}|${def.structClassIdx}|${def.navRelClassIdx}|${def.navDirection}|${def.categoryIdx}|${def.isReadOnly ? 1 : 0}|${def.isHidden ? 1 : 0}|${def.arrayMinOccurs}|${def.arrayMaxOccurs}|${def.descriptionStringIdx}`;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=SchemaViewBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaViewBuilder.js","sourceRoot":"","sources":["../../../src/SchemaView/SchemaViewBuilder.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/** @packageDocumentation\n * @module Schema\n */\n\nimport type { ClassData, EnumerationData, EnumeratorData, KoqData, PropCategoryData, PropertyDef, PropertyRef, RelConstraintData, SchemaData } from \"./SchemaViewInterfaces\";\nimport { SchemaView, type SchemaViewData } from \"./SchemaView\";\n\n/** Builder for constructing an immutable `SchemaView`.\n *\n * Collects data during binary blob parsing, then freezes it into a view.\n * Handles string interning and property definition deduplication.\n *\n * Consumers should not use this directly - read views via `IModelDb.getSchemaView`\n * / `IModelConnection.getSchemaView` (or `SchemaView.fromBinary` if you have a raw blob).\n * @internal\n */\nexport class SchemaViewBuilder {\n private readonly _strings: string[] = [\"\"]; // SID 0 = empty string\n private readonly _lowerStrings: string[] = [\"\"];\n private readonly _stringMap = new Map<string, number>(); // original value -> SID\n\n private readonly _schemas: SchemaData[] = [];\n private readonly _classes: ClassData[] = [];\n private readonly _classMixins: number[] = [];\n private readonly _propDefs: PropertyDef[] = [];\n private readonly _propertyRefs: PropertyRef[] = [];\n private readonly _relConstraints: RelConstraintData[] = [];\n private readonly _constraintClassRefs: number[] = [];\n private readonly _enumerations: EnumerationData[] = [];\n private readonly _enumerators: EnumeratorData[] = [];\n private readonly _koqs: KoqData[] = [];\n private readonly _propCategories: PropCategoryData[] = [];\n\n // For PropertyDef dedup\n private readonly _propDefMap = new Map<string, number>(); // signature string -> defIdx\n\n // Lookup maps - owned by the builder so a husk can share and extend them across fragment merges.\n // `build()` and each merge call `extendLookupMaps()`; the view receives these same Map objects\n // via `assembleData()`, so in-place growth is visible.\n private readonly _schemaByName = new Map<string, number>();\n private readonly _schemaByAlias = new Map<string, number>();\n private readonly _classByName = new Map<number, Map<string, number>>();\n private readonly _enumByName = new Map<number, Map<string, number>>();\n private readonly _koqByName = new Map<number, Map<string, number>>();\n private readonly _catByName = new Map<number, Map<string, number>>();\n private _lookupMapsBuiltUpto = 0; // number of schemas whose lookup entries are already built\n\n /** Intern a string, returning its SID. Empty/undefined strings return 0.\n * Interning is case-sensitive - \"MyLabel\" and \"MYLABEL\" get distinct SIDs.\n * The `lowerStrings` array provides case-insensitive lookup without mutating display values.\n */\n public internString(value: string | undefined): number {\n if (value === undefined || value === \"\") return 0;\n const existing = this._stringMap.get(value);\n if (existing !== undefined) return existing;\n const sid = this._strings.length;\n this._strings.push(value);\n this._lowerStrings.push(value.toLowerCase());\n this._stringMap.set(value, sid);\n return sid;\n }\n\n /** Add a schema. Returns its index. */\n public addSchema(data: SchemaData): number {\n const idx = this._schemas.length;\n this._schemas.push(data);\n return idx;\n }\n\n /** Add a class. Returns its index. Must be called after the owning schema. */\n public addClass(data: ClassData): number {\n const idx = this._classes.length;\n this._classes.push(data);\n return idx;\n }\n\n /** Add a property definition with deduplication. Returns the def index (possibly existing). */\n public addPropertyDef(data: PropertyDef): number {\n const sig = this._propDefSignature(data);\n const existing = this._propDefMap.get(sig);\n if (existing !== undefined) return existing;\n\n const idx = this._propDefs.length;\n this._propDefs.push(data);\n this._propDefMap.set(sig, idx);\n return idx;\n }\n\n /** Append a property reference to the flat refs array. */\n public addPropertyRef(ref: PropertyRef): void {\n this._propertyRefs.push(ref);\n }\n\n /** Add an enumeration. Returns its index. */\n public addEnumeration(data: EnumerationData): number {\n const idx = this._enumerations.length;\n this._enumerations.push(data);\n return idx;\n }\n\n /** Append an enumerator to the flat enumerators array. */\n public addEnumerator(data: EnumeratorData): void {\n this._enumerators.push(data);\n }\n\n /** Add a KindOfQuantity. Returns its index. */\n public addKoq(data: KoqData): number {\n const idx = this._koqs.length;\n this._koqs.push(data);\n return idx;\n }\n\n /** Add a PropertyCategory. Returns its index. */\n public addPropertyCategory(data: PropCategoryData): number {\n const idx = this._propCategories.length;\n this._propCategories.push(data);\n return idx;\n }\n\n /** Add a relationship constraint. Returns its index. */\n public addRelConstraint(data: RelConstraintData): number {\n const idx = this._relConstraints.length;\n this._relConstraints.push(data);\n return idx;\n }\n\n /** Append a constraint class reference to the flat array. */\n public addConstraintClassRef(classIdx: number): void {\n this._constraintClassRefs.push(classIdx);\n }\n\n /** Append a mixin class reference to the flat array. */\n public addClassMixin(classIdx: number): void {\n this._classMixins.push(classIdx);\n }\n\n /** The current count of property refs (used to set ownPropStart on ClassData). */\n public get propertyRefCount(): number { return this._propertyRefs.length; }\n\n /** The current count of enumerators (used to set enumeratorStart on EnumerationData). */\n public get enumeratorCount(): number { return this._enumerators.length; }\n\n /** The current count of constraint class refs (used to set classRefStart). */\n public get constraintClassRefCount(): number { return this._constraintClassRefs.length; }\n\n /** The current count of class mixins (used to set mixinStartIdx). */\n public get classMixinCount(): number { return this._classMixins.length; }\n\n // The counts below are the base indices fragment merging uses to translate a fragment's local\n // indices into global ones.\n\n /** The current count of schemas. @internal */\n public get schemaCount(): number { return this._schemas.length; }\n\n /** The current count of classes. @internal */\n public get classCount(): number { return this._classes.length; }\n\n /** The current count of enumerations. @internal */\n public get enumerationCount(): number { return this._enumerations.length; }\n\n /** The current count of KindOfQuantities. @internal */\n public get koqCount(): number { return this._koqs.length; }\n\n /** The current count of property categories. @internal */\n public get propCategoryCount(): number { return this._propCategories.length; }\n\n /** Get a string by SID. @internal */\n public getString(sid: number): string { return this._strings[sid]; }\n\n /** Replace class data at the given index (used during deferred cross-ref resolution). @internal */\n public updateClass(classIdx: number, data: ClassData): void { this._classes[classIdx] = data; }\n\n /** Update range fields on a schema (used after all items for a schema are collected). @internal */\n public updateSchemaRanges(schemaIdx: number, ranges: { classRangeStart: number; classCount: number; enumRangeStart: number; enumCount: number; koqRangeStart: number; koqCount: number; catRangeStart: number; catCount: number }): void {\n const s = this._schemas[schemaIdx];\n this._schemas[schemaIdx] = { ...s, ...ranges };\n }\n\n /** Freeze all data and produce an immutable SchemaView. */\n public build(schemaToken?: string): SchemaView {\n this.extendLookupMaps();\n return new SchemaView(this.assembleData(), schemaToken);\n }\n\n /** Build lookup-map entries for any schemas added since the last call. Idempotent and\n * append-only, so it is safe to call after each fragment merge. A schema's item ranges must\n * already be finalized (via `updateSchemaRanges`) before it is processed.\n * @internal */\n public extendLookupMaps(): void {\n for (let i = this._lookupMapsBuiltUpto; i < this._schemas.length; i++) {\n const s = this._schemas[i];\n this._schemaByName.set(this._lowerStrings[s.nameStringIdx], i);\n if (s.aliasStringIdx !== 0)\n this._schemaByAlias.set(this._lowerStrings[s.aliasStringIdx], i);\n\n // Build class-by-name map for this schema\n const classMap = new Map<string, number>();\n for (let c = s.classRangeStart; c < s.classRangeStart + s.classCount; c++)\n classMap.set(this._lowerStrings[this._classes[c].nameStringIdx], c);\n this._classByName.set(i, classMap);\n\n // Build enum-by-name map for this schema\n const eMap = new Map<string, number>();\n for (let e = s.enumRangeStart; e < s.enumRangeStart + s.enumCount; e++)\n eMap.set(this._lowerStrings[this._enumerations[e].nameStringIdx], e);\n this._enumByName.set(i, eMap);\n\n // Build koq-by-name map for this schema\n const kMap = new Map<string, number>();\n for (let k = s.koqRangeStart; k < s.koqRangeStart + s.koqCount; k++)\n kMap.set(this._lowerStrings[this._koqs[k].nameStringIdx], k);\n this._koqByName.set(i, kMap);\n\n // Build category-by-name map for this schema\n const cMap = new Map<string, number>();\n for (let p = s.catRangeStart; p < s.catRangeStart + s.catCount; p++)\n cMap.set(this._lowerStrings[this._propCategories[p].nameStringIdx], p);\n this._catByName.set(i, cMap);\n }\n this._lookupMapsBuiltUpto = this._schemas.length;\n }\n\n /** Assemble a {@link SchemaViewData} bag that references this builder's live arrays and lookup\n * maps. Continued building - fragment merges that append to the arrays and extend the maps in\n * place - is visible through the shared references, so a husk holding this data sees merged\n * schemas without rebuilding. @internal */\n public assembleData(): SchemaViewData {\n return {\n strings: this._strings,\n lowerStrings: this._lowerStrings,\n schemas: this._schemas,\n classes: this._classes,\n classMixins: this._classMixins,\n propDefs: this._propDefs,\n propertyRefs: this._propertyRefs,\n relConstraints: this._relConstraints,\n constraintClassRefs: this._constraintClassRefs,\n enumerations: this._enumerations,\n enumerators: this._enumerators,\n koqs: this._koqs,\n propCategories: this._propCategories,\n schemaByName: this._schemaByName,\n schemaByAlias: this._schemaByAlias,\n classByName: this._classByName,\n enumByName: this._enumByName,\n koqByName: this._koqByName,\n catByName: this._catByName,\n };\n }\n\n /** Produce a dedup signature for a PropertyDef. Label and priority are excluded because\n * they are per-PropertyRef overrides, not part of the structural definition.\n * Uses SIDs (not lowercase strings) for name/description so that case-preserving names\n * stay distinct - matching the C++ writer's dedup behavior. */\n private _propDefSignature(def: PropertyDef): string {\n return `${def.nameStringIdx}|${def.kind}|${def.primitiveType}|${def.extTypeStringIdx}|${def.enumIdx}|${def.koqIdx}|${def.structClassIdx}|${def.navRelClassIdx}|${def.navDirection}|${def.categoryIdx}|${def.isReadOnly ? 1 : 0}|${def.isHidden ? 1 : 0}|${def.arrayMinOccurs}|${def.arrayMaxOccurs}|${def.descriptionStringIdx}`;\n }\n}\n"]}
|
|
@@ -55,7 +55,7 @@ export declare enum SchemaViewPrimitiveType {
|
|
|
55
55
|
String = 2305,
|
|
56
56
|
IGeometry = 2561
|
|
57
57
|
}
|
|
58
|
-
import { StrengthDirection, StrengthType } from "
|
|
58
|
+
import { StrengthDirection, StrengthType } from "../ECObjects";
|
|
59
59
|
/** Internal storage for a schema. Schemas own contiguous ranges of classes, enums, KoQs, and categories.
|
|
60
60
|
* @internal
|
|
61
61
|
*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaViewInterfaces.d.ts","sourceRoot":"","sources":["../../../src/SchemaView/SchemaViewInterfaces.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaViewInterfaces.js","sourceRoot":"","sources":["../../../src/SchemaView/SchemaViewInterfaces.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAEzC;;GAEG;AACH,MAAM,CAAN,IAAY,SASX;AATD,WAAY,SAAS;IACnB,6CAAU,CAAA;IACV,yDAAgB,CAAA;IAChB,6CAAU,CAAA;IACV,+DAAmB,CAAA;IACnB,yFAAyF;IACzF,2CAAS,CAAA;IACT,uDAAuD;IACvD,yCAAQ,CAAA;AACV,CAAC,EATW,SAAS,KAAT,SAAS,QASpB;AAED;;GAEG;AACH,MAAM,CAAN,IAAY,aAIX;AAJD,WAAY,aAAa;IACvB,iDAAQ,CAAA;IACR,yDAAY,CAAA;IACZ,qDAAU,CAAA;AACZ,CAAC,EAJW,aAAa,KAAb,aAAa,QAIxB;AAED;;GAEG;AACH,MAAM,CAAN,IAAY,YAMX;AAND,WAAY,YAAY;IACtB,yDAAa,CAAA;IACb,mDAAU,CAAA;IACV,mEAAkB,CAAA;IAClB,6DAAe,CAAA;IACf,2DAAc,CAAA;AAChB,CAAC,EANW,YAAY,KAAZ,YAAY,QAMvB;AAED;;GAEG;AACH,MAAM,CAAN,IAAY,uBAYX;AAZD,WAAY,uBAAuB;IACjC,uFAAoB,CAAA;IACpB,2EAAc,CAAA;IACd,6EAAe,CAAA;IACf,+EAAgB,CAAA;IAChB,4EAAc,CAAA;IACd,8EAAe,CAAA;IACf,wEAAY,CAAA;IACZ,8EAAe,CAAA;IACf,8EAAe,CAAA;IACf,4EAAc,CAAA;IACd,kFAAiB,CAAA;AACnB,CAAC,EAZW,uBAAuB,KAAvB,uBAAuB,QAYlC","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/** @packageDocumentation\n * @module Schema\n */\n\n/** The binary format version that this TS reader supports.\n * The C++ writer in imodel-native must produce this version (or negotiate down to it).\n * Frontend callers should always request this version explicitly via `PRAGMA schema_view(N)`.\n * Backend callers may omit it since native and backend are bundled together.\n * @beta\n */\nexport const schemaViewFormatVersion = 1;\n\n/** Matches ec_Class.Type values in ECDb.\n * @beta\n */\nexport enum ClassType {\n Entity = 0,\n Relationship = 1,\n Struct = 2,\n CustomAttribute = 3,\n /** Not stored in ec_Class.Type - synthesized from IsMixin CA during cache population. */\n Mixin = 4,\n /** Synthesized from the QueryView custom attribute. */\n View = 5,\n}\n\n/** Matches ec_Class.Modifier values.\n * @beta\n */\nexport enum ClassModifier {\n None = 0,\n Abstract = 1,\n Sealed = 2,\n}\n\n/** Matches ec_Property.Kind values.\n * @beta\n */\nexport enum PropertyKind {\n Primitive = 0,\n Struct = 1,\n PrimitiveArray = 2,\n StructArray = 3,\n Navigation = 4,\n}\n\n/** Matches ec_ PrimitiveType values.\n * @beta\n */\nexport enum SchemaViewPrimitiveType {\n Uninitialized = 0x00,\n Binary = 0x101,\n Boolean = 0x201,\n DateTime = 0x301,\n Double = 0x401,\n Integer = 0x501,\n Long = 0x601,\n Point2d = 0x701,\n Point3d = 0x801,\n String = 0x901,\n IGeometry = 0xa01,\n}\n\nimport { StrengthDirection, StrengthType } from \"../ECObjects\";\n\n/** Internal storage for a schema. Schemas own contiguous ranges of classes, enums, KoQs, and categories.\n * @internal\n */\nexport interface SchemaData {\n /** Row ID from ec_Schema - use with ECDbMeta queries, e.g. `SELECT * FROM meta.ECSchemaDef WHERE ECInstanceId = ?`. */\n readonly ecInstanceId: number;\n readonly nameStringIdx: number;\n readonly aliasStringIdx: number;\n readonly labelStringIdx: number;\n readonly descriptionStringIdx: number;\n readonly versionRead: number;\n readonly versionWrite: number;\n readonly versionMinor: number;\n readonly classRangeStart: number;\n readonly classCount: number;\n readonly enumRangeStart: number;\n readonly enumCount: number;\n readonly koqRangeStart: number;\n readonly koqCount: number;\n readonly catRangeStart: number;\n readonly catCount: number;\n readonly isHidden: boolean;\n}\n\n/** Internal storage for a class.\n * @internal\n */\nexport interface ClassData {\n /** Row ID from ec_Class - use with ECDbMeta queries, e.g. `SELECT * FROM meta.ECClassDef WHERE ECInstanceId = ?`. */\n readonly ecInstanceId: number;\n readonly schemaIdx: number;\n readonly nameStringIdx: number;\n readonly labelStringIdx: number;\n readonly descriptionStringIdx: number;\n readonly type: ClassType;\n readonly modifier: ClassModifier;\n readonly baseClassIdx: number;\n readonly mixinStartIdx: number;\n readonly mixinCount: number;\n readonly ownPropStart: number;\n readonly ownPropCount: number;\n readonly strength: StrengthType;\n readonly strengthDirection: StrengthDirection;\n readonly sourceConstraintIdx: number;\n readonly targetConstraintIdx: number;\n /** Tri-state hidden status from the `HiddenClass` / `HiddenSchema` custom attributes.\n *\n * This is the *direct* status of this class. It does NOT propagate through class\n * inheritance. Use `SchemaView.Class.isEffectivelyHidden` for hierarchy-aware checks.\n *\n * - `true`: `HiddenClass(Show!=true)` is applied, OR the owning schema has\n * `HiddenSchema(ShowClasses!=true)` and this class does not override with `HiddenClass(Show=true)`.\n * - `false`: `HiddenClass(Show=true)` is explicitly applied. This overrides schema-level\n * hiding and breaks the inheritance chain for `isEffectivelyHidden` on derived classes.\n * - `undefined`: No `HiddenClass` CA and the schema does not hide its classes. Neutral -\n * `isEffectivelyHidden` will look up the base class chain to decide.\n *\n * Binary encoding: 0 = undefined, 1 = true, 2 = false.\n */\n readonly isHidden: boolean | undefined;\n}\n\n/** Shared, deduplicated property definition. Many properties may reference the same def.\n * The definition holds the structural shape of a property - name, kind, type, cross-references.\n * Per-class overrides (label, priority) live in `PropertyRef`, not here, so that properties\n * with identical shape but different labels still share a single definition.\n * @internal\n */\nexport interface PropertyDef {\n readonly nameStringIdx: number;\n readonly descriptionStringIdx: number;\n readonly kind: PropertyKind;\n readonly primitiveType: SchemaViewPrimitiveType;\n readonly extTypeStringIdx: number;\n readonly enumIdx: number;\n readonly koqIdx: number;\n readonly structClassIdx: number;\n readonly navRelClassIdx: number;\n readonly navDirection: StrengthDirection;\n readonly categoryIdx: number;\n readonly isReadOnly: boolean;\n readonly isHidden: boolean;\n readonly arrayMinOccurs: number | undefined;\n readonly arrayMaxOccurs: number | undefined;\n}\n\n/** A reference from a specific class to a shared property definition.\n * Label and priority are per-reference (not per-definition) because EC allows class overrides\n * of these attributes. A property displayed in ClassA may have a different label than in ClassB\n * even though the underlying definition (name, type, etc.) is identical.\n *\n * `ecInstanceId` is the ec_Property.Id row ID, stored here (not on PropertyDef) because each\n * class-property pair has a unique row even when the structural definition is deduplicated.\n * @internal\n */\nexport interface PropertyRef {\n /** Row ID from ec_Property - use with ECDbMeta queries, e.g. `SELECT * FROM meta.ECPropertyDef WHERE ECInstanceId = ?`. */\n readonly ecInstanceId: number;\n readonly defIdx: number;\n readonly labelStringIdx: number;\n readonly priority: number;\n}\n\n/** Internal storage for a relationship constraint.\n * @internal\n */\nexport interface RelConstraintData {\n readonly abstractConstraintIdx: number;\n readonly polymorphic: boolean;\n readonly multiplicityLower: number;\n readonly multiplicityUpper: number;\n readonly roleLabelStringIdx: number;\n readonly classRefStart: number;\n readonly classRefCount: number;\n}\n\n/** Internal storage for an enumeration.\n * @internal\n */\nexport interface EnumerationData {\n /** Row ID from ec_Enumeration - use with ECDbMeta queries, e.g. `SELECT * FROM meta.ECEnumerationDef WHERE ECInstanceId = ?`. */\n readonly ecInstanceId: number;\n readonly schemaIdx: number;\n readonly nameStringIdx: number;\n readonly labelStringIdx: number;\n readonly descriptionStringIdx: number;\n readonly primitiveType: SchemaViewPrimitiveType;\n readonly isStrict: boolean;\n readonly enumeratorStart: number;\n readonly enumeratorCount: number;\n}\n\n/** Internal storage for an enumerator.\n * @internal\n */\nexport interface EnumeratorData {\n readonly nameStringIdx: number;\n readonly labelStringIdx: number;\n readonly descriptionStringIdx: number;\n readonly value: number | string;\n}\n\n/** Internal storage for a KindOfQuantity.\n * @internal\n */\nexport interface KoqData {\n /** Row ID from ec_KindOfQuantity - use with ECDbMeta queries, e.g. `SELECT * FROM meta.ECKindOfQuantityDef WHERE ECInstanceId = ?`. */\n readonly ecInstanceId: number;\n readonly schemaIdx: number;\n readonly nameStringIdx: number;\n readonly labelStringIdx: number;\n readonly descriptionStringIdx: number;\n readonly persistenceUnitStringIdx: number;\n readonly presentationFormatsStringIdx: number;\n readonly relativeError: number;\n}\n\n/** Internal storage for a PropertyCategory.\n * @internal\n */\nexport interface PropCategoryData {\n /** Row ID from ec_PropertyCategory - use with ECDbMeta queries, e.g. `SELECT * FROM meta.ECPropertyCategoryDef WHERE ECInstanceId = ?`. */\n readonly ecInstanceId: number;\n readonly schemaIdx: number;\n readonly nameStringIdx: number;\n readonly labelStringIdx: number;\n readonly descriptionStringIdx: number;\n readonly priority: number;\n}\n"]}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/** @packageDocumentation
|
|
2
|
+
* @module Schema
|
|
3
|
+
*/
|
|
4
|
+
import { SchemaManifest } from "./SchemaManifest";
|
|
5
|
+
import { SchemaView } from "./SchemaView";
|
|
6
|
+
/** One schema-view blob with its cache-invalidation token, as fetched by a
|
|
7
|
+
* {@link SchemaViewDataProvider}. Full and fragment blobs share this shape.
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export interface SchemaViewBlob {
|
|
11
|
+
/** The binary schema metadata (the `data` column of `PRAGMA schema_view` / `schema_view_fragment`). */
|
|
12
|
+
readonly data: Uint8Array;
|
|
13
|
+
/** Schema-identity hash of the iModel's whole schema set (the `schemaToken` column). Empty string when unavailable. */
|
|
14
|
+
readonly schemaToken: string;
|
|
15
|
+
}
|
|
16
|
+
/** The data source a {@link SchemaViewManager} loads schema-view data from, implemented by the hosts
|
|
17
|
+
* that own the query APIs: `IModelDb` on the backend and `IModelConnection` on the frontend. The
|
|
18
|
+
* manager deals only in schema names, blobs and the manifest; everything transport-specific - pragma
|
|
19
|
+
* strings, format-version pinning - belongs to the provider.
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
export interface SchemaViewDataProvider {
|
|
23
|
+
/** Fetch the blob containing every schema in the iModel (`PRAGMA schema_view`). */
|
|
24
|
+
fetchFullBlob(): Promise<SchemaViewBlob>;
|
|
25
|
+
/** Fetch one blob containing exactly the given schemas (`PRAGMA schema_view_fragment`). The
|
|
26
|
+
* requested set is always dependency-closed - the manager computes the reference closure from the
|
|
27
|
+
* manifest before calling. */
|
|
28
|
+
fetchFragmentBlob(schemaNames: readonly string[]): Promise<SchemaViewBlob>;
|
|
29
|
+
/** Fetch the reference graph of every schema in the iModel, built from ECDbMeta
|
|
30
|
+
* (`meta.ECSchemaDef` + `meta.SchemaHasSchemaReferences`; see {@link SchemaManifest.fromRows}). */
|
|
31
|
+
fetchManifest(): Promise<SchemaManifest>;
|
|
32
|
+
/** Fetch the current schema-identity token (`PRAGMA checksum(schema_token)`). */
|
|
33
|
+
fetchSchemaToken(): Promise<string>;
|
|
34
|
+
}
|
|
35
|
+
/** Options for `getSchemaView` (see `IModelDb.getSchemaView` / `IModelConnection.getSchemaView`,
|
|
36
|
+
* which delegate to {@link SchemaViewManager.getSchemaView}).
|
|
37
|
+
* @beta
|
|
38
|
+
*/
|
|
39
|
+
export interface GetSchemaViewArgs {
|
|
40
|
+
/** When provided, return a view loaded with at least these schemas plus their references, instead
|
|
41
|
+
* of every schema in the iModel.
|
|
42
|
+
*
|
|
43
|
+
* The view accumulates: one instance is reused across calls, so a later request - with different
|
|
44
|
+
* schemas or with no filter at all - merges the still-missing schemas into the same view and
|
|
45
|
+
* everything requested earlier stays available. It resets when the iModel's schemas change.
|
|
46
|
+
*
|
|
47
|
+
* Names the iModel does not contain are ignored. Omitting this option loads all schemas, identical
|
|
48
|
+
* to calling `getSchemaView()` with no arguments.
|
|
49
|
+
*/
|
|
50
|
+
readonly schemas?: readonly string[];
|
|
51
|
+
/** When `true`, discard whatever is currently loaded and rebuild the view from scratch before
|
|
52
|
+
* returning it. The previously returned view instance (if any) is marked outdated. Like every other
|
|
53
|
+
* request this is serialized behind any in-flight load, so it never leaves the view in an invalid
|
|
54
|
+
* intermediate state.
|
|
55
|
+
* @internal
|
|
56
|
+
*/
|
|
57
|
+
readonly forceReload?: boolean;
|
|
58
|
+
}
|
|
59
|
+
/** Owns the lifetime of one iModel's {@link (SchemaView:class)}: lazy loading, incremental (filtered)
|
|
60
|
+
* hydration, serialization of concurrent requests, and invalidation. Hosts (`IModelDb`,
|
|
61
|
+
* `IModelConnection`) hold one instance and delegate to it; all data access goes through the
|
|
62
|
+
* host-implemented {@link SchemaViewDataProvider}.
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
65
|
+
export declare class SchemaViewManager {
|
|
66
|
+
private readonly _dataProvider;
|
|
67
|
+
/** The single accumulating view, held as a promise so all requests chain onto it and never overlap.
|
|
68
|
+
* Undefined (or resolving to undefined) means nothing is loaded. */
|
|
69
|
+
private _viewPromise?;
|
|
70
|
+
/** Reference graph for incremental loading; undefined when the view is (or will be) fully loaded. */
|
|
71
|
+
private _manifest?;
|
|
72
|
+
/** Schema-identity token the manifest - and thus every fragment merged under it - belongs to. */
|
|
73
|
+
private _manifestToken?;
|
|
74
|
+
/** Lower-cased names already merged into the view (incremental mode only). */
|
|
75
|
+
private readonly _loadedSchemaNames;
|
|
76
|
+
constructor(dataProvider: SchemaViewDataProvider);
|
|
77
|
+
/** Get the schema view, loading whatever the request needs that is not present yet. See
|
|
78
|
+
* {@link GetSchemaViewArgs} for filtering and reload semantics; hosts document the full
|
|
79
|
+
* user-facing contract on their `getSchemaView` methods.
|
|
80
|
+
*/
|
|
81
|
+
getSchemaView(args?: GetSchemaViewArgs): Promise<SchemaView>;
|
|
82
|
+
/** Throw away the current schema view. Called by the host when schemas may have changed (e.g.
|
|
83
|
+
* `IModelDb.clearCaches` after a schema import). Chains behind any in-flight load and marks the
|
|
84
|
+
* discarded view outdated; the next getSchemaView starts over.
|
|
85
|
+
*/
|
|
86
|
+
reset(): void;
|
|
87
|
+
/** Check whether the iModel's schemas have changed since the current view was built, and discard
|
|
88
|
+
* the view only if they have. For hosts that *cannot* determine whether an operation actually
|
|
89
|
+
* modified schemas - e.g. `BriefcaseConnection.pullChanges` on the frontend, whose IPC response
|
|
90
|
+
* carries only the new changeset id, not the applied changesets' types. Discarding after every
|
|
91
|
+
* such operation would reload unnecessarily in the common case where schemas are unchanged, so
|
|
92
|
+
* this compares the cheap schema-identity token instead.
|
|
93
|
+
* @note If the token cannot be fetched, the view is discarded rather than risking stale metadata.
|
|
94
|
+
*/
|
|
95
|
+
invalidateIfChanged(): Promise<void>;
|
|
96
|
+
/** Serialized body of {@link SchemaViewManager.invalidateIfChanged}. Resolves to the view to keep,
|
|
97
|
+
* or to `undefined` when it was discarded and the next getSchemaView has to start over.
|
|
98
|
+
*/
|
|
99
|
+
private _invalidateIfChanged;
|
|
100
|
+
/** Serialized body of {@link SchemaViewManager.getSchemaView}. On failure it resets and rejects,
|
|
101
|
+
* so the next call starts over.
|
|
102
|
+
*/
|
|
103
|
+
private _loadSchemaView;
|
|
104
|
+
/** Clear the incremental schema-view bookkeeping. */
|
|
105
|
+
private _resetIncrementalState;
|
|
106
|
+
/** Ensures the requested schemas (or all schemas, when no filter is given) are present in
|
|
107
|
+
* `currentView` (or a freshly created view) and returns it. The first load fixes the strategy:
|
|
108
|
+
* no filter fetches everything as one full blob; a filter fetches fragments and keeps the
|
|
109
|
+
* manifest and loaded-name set so later calls extend the same view. Once every schema is loaded
|
|
110
|
+
* the incremental state is dropped, collapsing back to full mode.
|
|
111
|
+
*/
|
|
112
|
+
private _ensureSchemasLoaded;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=SchemaViewManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaViewManager.d.ts","sourceRoot":"","sources":["../../../src/SchemaView/SchemaViewManager.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,uGAAuG;IACvG,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,uHAAuH;IACvH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,mFAAmF;IACnF,aAAa,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IAEzC;;kCAE8B;IAC9B,iBAAiB,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAE3E;uGACmG;IACnG,aAAa,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IAEzC,iFAAiF;IACjF,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CACrC;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAErC;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;GAKG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;IAEvD;wEACoE;IACpE,OAAO,CAAC,YAAY,CAAC,CAAkC;IAEvD,qGAAqG;IACrG,OAAO,CAAC,SAAS,CAAC,CAAiB;IAEnC,iGAAiG;IACjG,OAAO,CAAC,cAAc,CAAC,CAAS;IAEhC,8EAA8E;IAC9E,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqB;gBAErC,YAAY,EAAE,sBAAsB;IAIvD;;;OAGG;IACU,aAAa,CAAC,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;IAOzE;;;OAGG;IACI,KAAK,IAAI,IAAI;IASpB;;;;;;;OAOG;IACU,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAWjD;;OAEG;YACW,oBAAoB;IAyBlC;;OAEG;YACW,eAAe;IA0B7B,qDAAqD;IACrD,OAAO,CAAC,sBAAsB;IAM9B;;;;;OAKG;YACW,oBAAoB;CAgDnC"}
|
|
@@ -0,0 +1,180 @@
|
|
|
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
|
+
/** @packageDocumentation
|
|
6
|
+
* @module Schema
|
|
7
|
+
*/
|
|
8
|
+
import { SchemaView } from "./SchemaView";
|
|
9
|
+
/** Owns the lifetime of one iModel's {@link (SchemaView:class)}: lazy loading, incremental (filtered)
|
|
10
|
+
* hydration, serialization of concurrent requests, and invalidation. Hosts (`IModelDb`,
|
|
11
|
+
* `IModelConnection`) hold one instance and delegate to it; all data access goes through the
|
|
12
|
+
* host-implemented {@link SchemaViewDataProvider}.
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export class SchemaViewManager {
|
|
16
|
+
_dataProvider;
|
|
17
|
+
/** The single accumulating view, held as a promise so all requests chain onto it and never overlap.
|
|
18
|
+
* Undefined (or resolving to undefined) means nothing is loaded. */
|
|
19
|
+
_viewPromise;
|
|
20
|
+
/** Reference graph for incremental loading; undefined when the view is (or will be) fully loaded. */
|
|
21
|
+
_manifest;
|
|
22
|
+
/** Schema-identity token the manifest - and thus every fragment merged under it - belongs to. */
|
|
23
|
+
_manifestToken;
|
|
24
|
+
/** Lower-cased names already merged into the view (incremental mode only). */
|
|
25
|
+
_loadedSchemaNames = new Set();
|
|
26
|
+
constructor(dataProvider) {
|
|
27
|
+
this._dataProvider = dataProvider;
|
|
28
|
+
}
|
|
29
|
+
/** Get the schema view, loading whatever the request needs that is not present yet. See
|
|
30
|
+
* {@link GetSchemaViewArgs} for filtering and reload semantics; hosts document the full
|
|
31
|
+
* user-facing contract on their `getSchemaView` methods.
|
|
32
|
+
*/
|
|
33
|
+
async getSchemaView(args) {
|
|
34
|
+
const previous = this._viewPromise;
|
|
35
|
+
const next = this._loadSchemaView(previous, args?.schemas, args?.forceReload === true);
|
|
36
|
+
this._viewPromise = next;
|
|
37
|
+
return next;
|
|
38
|
+
}
|
|
39
|
+
/** Throw away the current schema view. Called by the host when schemas may have changed (e.g.
|
|
40
|
+
* `IModelDb.clearCaches` after a schema import). Chains behind any in-flight load and marks the
|
|
41
|
+
* discarded view outdated; the next getSchemaView starts over.
|
|
42
|
+
*/
|
|
43
|
+
reset() {
|
|
44
|
+
if (this._viewPromise) {
|
|
45
|
+
this._viewPromise = this._viewPromise.then((view) => { view?.markOutdated(); this._resetIncrementalState(); return undefined; }, () => { this._resetIncrementalState(); return undefined; });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/** Check whether the iModel's schemas have changed since the current view was built, and discard
|
|
49
|
+
* the view only if they have. For hosts that *cannot* determine whether an operation actually
|
|
50
|
+
* modified schemas - e.g. `BriefcaseConnection.pullChanges` on the frontend, whose IPC response
|
|
51
|
+
* carries only the new changeset id, not the applied changesets' types. Discarding after every
|
|
52
|
+
* such operation would reload unnecessarily in the common case where schemas are unchanged, so
|
|
53
|
+
* this compares the cheap schema-identity token instead.
|
|
54
|
+
* @note If the token cannot be fetched, the view is discarded rather than risking stale metadata.
|
|
55
|
+
*/
|
|
56
|
+
async invalidateIfChanged() {
|
|
57
|
+
const previous = this._viewPromise;
|
|
58
|
+
if (previous === undefined)
|
|
59
|
+
return;
|
|
60
|
+
// Queue the check on the same chain as loading, so a getSchemaView arriving while the token is
|
|
61
|
+
// in flight cannot swap in a new promise for the same stale view and hide the schema change.
|
|
62
|
+
const next = this._invalidateIfChanged(previous);
|
|
63
|
+
this._viewPromise = next;
|
|
64
|
+
await next;
|
|
65
|
+
}
|
|
66
|
+
/** Serialized body of {@link SchemaViewManager.invalidateIfChanged}. Resolves to the view to keep,
|
|
67
|
+
* or to `undefined` when it was discarded and the next getSchemaView has to start over.
|
|
68
|
+
*/
|
|
69
|
+
async _invalidateIfChanged(previous) {
|
|
70
|
+
let existing;
|
|
71
|
+
try {
|
|
72
|
+
existing = await previous;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
if (existing === undefined)
|
|
78
|
+
return undefined;
|
|
79
|
+
// A view without a token (e.g. built directly from a SchemaViewBuilder) cannot be verified by
|
|
80
|
+
// token; views loaded through this manager always carry one.
|
|
81
|
+
if (existing.schemaToken === "")
|
|
82
|
+
return existing;
|
|
83
|
+
try {
|
|
84
|
+
if (await this._dataProvider.fetchSchemaToken() === existing.schemaToken)
|
|
85
|
+
return existing;
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// Cannot verify the cached view: drop it rather than risk stale metadata.
|
|
89
|
+
}
|
|
90
|
+
existing.markOutdated();
|
|
91
|
+
this._resetIncrementalState();
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
/** Serialized body of {@link SchemaViewManager.getSchemaView}. On failure it resets and rejects,
|
|
95
|
+
* so the next call starts over.
|
|
96
|
+
*/
|
|
97
|
+
async _loadSchemaView(previous, schemas, forceReload) {
|
|
98
|
+
let currentView;
|
|
99
|
+
if (previous !== undefined) {
|
|
100
|
+
try {
|
|
101
|
+
currentView = await previous;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
currentView = undefined; // the failed load already reset; start over
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (forceReload) {
|
|
108
|
+
currentView?.markOutdated();
|
|
109
|
+
currentView = undefined;
|
|
110
|
+
this._resetIncrementalState();
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
return await this._ensureSchemasLoaded(currentView, schemas);
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
// A failed merge may have left the view partially extended - discard everything.
|
|
117
|
+
currentView?.markOutdated();
|
|
118
|
+
this._resetIncrementalState();
|
|
119
|
+
throw err;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/** Clear the incremental schema-view bookkeeping. */
|
|
123
|
+
_resetIncrementalState() {
|
|
124
|
+
this._manifest = undefined;
|
|
125
|
+
this._manifestToken = undefined;
|
|
126
|
+
this._loadedSchemaNames.clear();
|
|
127
|
+
}
|
|
128
|
+
/** Ensures the requested schemas (or all schemas, when no filter is given) are present in
|
|
129
|
+
* `currentView` (or a freshly created view) and returns it. The first load fixes the strategy:
|
|
130
|
+
* no filter fetches everything as one full blob; a filter fetches fragments and keeps the
|
|
131
|
+
* manifest and loaded-name set so later calls extend the same view. Once every schema is loaded
|
|
132
|
+
* the incremental state is dropped, collapsing back to full mode.
|
|
133
|
+
*/
|
|
134
|
+
async _ensureSchemasLoaded(currentView, schemas, isRetry = false) {
|
|
135
|
+
const isFirstLoad = currentView === undefined;
|
|
136
|
+
// No manifest means everything is loaded; in incremental mode a filtered request is satisfied as
|
|
137
|
+
// soon as every requested name is present.
|
|
138
|
+
if (!isFirstLoad &&
|
|
139
|
+
(this._manifest === undefined ||
|
|
140
|
+
(schemas !== undefined && schemas.every((name) => this._loadedSchemaNames.has(name.toLowerCase())))))
|
|
141
|
+
return currentView;
|
|
142
|
+
if (isFirstLoad && schemas === undefined) {
|
|
143
|
+
const blob = await this._dataProvider.fetchFullBlob();
|
|
144
|
+
const schemaView = SchemaView.fromBinary(blob.data, blob.schemaToken);
|
|
145
|
+
this._resetIncrementalState();
|
|
146
|
+
return schemaView;
|
|
147
|
+
}
|
|
148
|
+
if (this._manifest === undefined) {
|
|
149
|
+
// Token first: any schema change after this point shows up as a token mismatch below.
|
|
150
|
+
this._manifestToken = await this._dataProvider.fetchSchemaToken();
|
|
151
|
+
this._manifest = await this._dataProvider.fetchManifest();
|
|
152
|
+
}
|
|
153
|
+
const manifest = this._manifest;
|
|
154
|
+
const requested = schemas ?? manifest.getAvailableSchemaNames();
|
|
155
|
+
const namesToLoad = manifest.getSchemaClosure(requested).filter((name) => !this._loadedSchemaNames.has(name.toLowerCase()));
|
|
156
|
+
const husk = currentView ?? SchemaView.createMergeable(this._manifestToken);
|
|
157
|
+
if (namesToLoad.length > 0) {
|
|
158
|
+
const blob = await this._dataProvider.fetchFragmentBlob(namesToLoad);
|
|
159
|
+
if (blob.schemaToken !== this._manifestToken) {
|
|
160
|
+
// Schemas changed between the manifest and fragment fetches. Everything loaded so far
|
|
161
|
+
// belongs to the old revision - discard it and start over, once.
|
|
162
|
+
currentView?.markOutdated();
|
|
163
|
+
this._resetIncrementalState();
|
|
164
|
+
if (isRetry)
|
|
165
|
+
throw new Error("The iModel's schemas changed while the schema view was loading.");
|
|
166
|
+
return this._ensureSchemasLoaded(undefined, schemas, true);
|
|
167
|
+
}
|
|
168
|
+
husk.mergeFragment(blob.data);
|
|
169
|
+
// Record the whole closure as loaded, including *excluded* schemas (e.g. CoreCustomAttributes)
|
|
170
|
+
// the writer emits no rows for, so later requests prune them instead of re-fetching.
|
|
171
|
+
for (const name of namesToLoad)
|
|
172
|
+
this._loadedSchemaNames.add(name.toLowerCase());
|
|
173
|
+
}
|
|
174
|
+
// Once every schema is loaded, collapse back to full mode (the size check is just a fast path).
|
|
175
|
+
if (schemas === undefined || (this._loadedSchemaNames.size >= manifest.schemaCount && manifest.entries.every((entry) => this._loadedSchemaNames.has(entry.name.toLowerCase()))))
|
|
176
|
+
this._resetIncrementalState();
|
|
177
|
+
return husk;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=SchemaViewManager.js.map
|