@itwin/core-backend 5.1.0-dev.34 → 5.1.0-dev.36
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/ChangesetECAdaptor.d.ts +54 -8
- package/lib/cjs/ChangesetECAdaptor.d.ts.map +1 -1
- package/lib/cjs/ChangesetECAdaptor.js +235 -33
- package/lib/cjs/ChangesetECAdaptor.js.map +1 -1
- package/lib/cjs/IModelDb.d.ts.map +1 -1
- package/lib/cjs/IModelDb.js +1 -0
- package/lib/cjs/IModelDb.js.map +1 -1
- package/lib/cjs/core-backend.d.ts.map +1 -1
- package/lib/cjs/core-backend.js +20 -0
- package/lib/cjs/core-backend.js.map +1 -1
- package/lib/esm/ChangesetECAdaptor.d.ts +54 -8
- package/lib/esm/ChangesetECAdaptor.d.ts.map +1 -1
- package/lib/esm/ChangesetECAdaptor.js +235 -33
- package/lib/esm/ChangesetECAdaptor.js.map +1 -1
- package/lib/esm/IModelDb.d.ts.map +1 -1
- package/lib/esm/IModelDb.js +1 -0
- package/lib/esm/IModelDb.js.map +1 -1
- package/lib/esm/core-backend.d.ts.map +1 -1
- package/lib/esm/core-backend.js +20 -0
- package/lib/esm/core-backend.js.map +1 -1
- package/lib/esm/test/imodel/IModel.test.js +27 -0
- package/lib/esm/test/imodel/IModel.test.js.map +1 -1
- package/lib/esm/test/standalone/ChangesetReader.test.js +294 -136
- package/lib/esm/test/standalone/ChangesetReader.test.js.map +1 -1
- package/package.json +13 -13
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @module ECDb
|
|
3
3
|
*/
|
|
4
4
|
import { Id64String } from "@itwin/core-bentley";
|
|
5
|
-
import { SqliteChangeOp, SqliteChangesetReader, SqliteValueStage } from "./SqliteChangesetReader";
|
|
5
|
+
import { AnyDb, SqliteChangeOp, SqliteChangesetReader, SqliteValueStage } from "./SqliteChangesetReader";
|
|
6
6
|
/**
|
|
7
7
|
* Record meta data for the change.
|
|
8
8
|
* @beta
|
|
@@ -31,33 +31,83 @@ export interface ChangedECInstance {
|
|
|
31
31
|
$meta?: ChangeMetaData;
|
|
32
32
|
[key: string]: any;
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Represents a cache for unifying EC changes.
|
|
36
|
+
* @beta
|
|
37
|
+
*/
|
|
38
|
+
export interface ECChangeUnifierCache extends Disposable {
|
|
39
|
+
/**
|
|
40
|
+
* Retrieves the value associated with the specified key from the cache.
|
|
41
|
+
* @param key - The key to retrieve the value for.
|
|
42
|
+
* @returns The value associated with the key, or undefined if the key is not found.
|
|
43
|
+
*/
|
|
44
|
+
get(key: string): ChangedECInstance | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Sets the value associated with the specified key in the cache.
|
|
47
|
+
* @param key - The key to set the value for.
|
|
48
|
+
* @param value - The value to be associated with the key.
|
|
49
|
+
*/
|
|
50
|
+
set(key: string, value: ChangedECInstance): void;
|
|
51
|
+
/**
|
|
52
|
+
* Returns an iterator for all the values in the cache.
|
|
53
|
+
* @returns An iterator for all the values in the cache.
|
|
54
|
+
*/
|
|
55
|
+
all(): IterableIterator<ChangedECInstance>;
|
|
56
|
+
/**
|
|
57
|
+
* Returns the number of entries in the cache.
|
|
58
|
+
* @returns The number of entries in the cache.
|
|
59
|
+
*/
|
|
60
|
+
count(): number;
|
|
61
|
+
}
|
|
62
|
+
export declare namespace ECChangeUnifierCache {
|
|
63
|
+
function createInMemory(): ECChangeUnifierCache;
|
|
64
|
+
function createSqliteBacked(db: AnyDb, bufferedReadInstanceSizeInBytes?: number): ECChangeUnifierCache;
|
|
65
|
+
}
|
|
34
66
|
/**
|
|
35
67
|
* Combine partial changed instance into single instance.
|
|
36
68
|
* Partial changes is per table and a single instance can
|
|
37
69
|
* span multiple tables.
|
|
38
70
|
* @beta
|
|
39
71
|
*/
|
|
40
|
-
export declare class PartialECChangeUnifier {
|
|
72
|
+
export declare class PartialECChangeUnifier implements Disposable {
|
|
73
|
+
private _db;
|
|
41
74
|
private _cache;
|
|
42
75
|
private _readonly;
|
|
76
|
+
constructor(_db: AnyDb, _cache?: ECChangeUnifierCache);
|
|
77
|
+
/**
|
|
78
|
+
* Dispose the instance.
|
|
79
|
+
*/
|
|
80
|
+
[Symbol.dispose](): void;
|
|
43
81
|
/**
|
|
44
82
|
* Get root class id for a given class
|
|
45
83
|
* @param classId given class id
|
|
46
84
|
* @param db use to find root class
|
|
47
85
|
* @returns return root class id
|
|
48
86
|
*/
|
|
49
|
-
private
|
|
87
|
+
private getRootClassId;
|
|
88
|
+
/**
|
|
89
|
+
* Checks if the given `rhsClassId` is an instance of the `lhsClassId`.
|
|
90
|
+
* @param rhsClassId The ID of the right-hand side class.
|
|
91
|
+
* @param lhsClassId The ID of the left-hand side class.
|
|
92
|
+
* @returns `true` if `rhsClassId` is an instance of `lhsClassId`, `false` otherwise.
|
|
93
|
+
*/
|
|
94
|
+
private instanceOf;
|
|
50
95
|
/**
|
|
51
96
|
* Combine partial instance with instance with same key if already exists.
|
|
52
97
|
* @param rhs partial instance
|
|
53
98
|
*/
|
|
54
99
|
private combine;
|
|
100
|
+
/**
|
|
101
|
+
* Returns the number of instances in the cache.
|
|
102
|
+
* @returns The number of instances in the cache.
|
|
103
|
+
*/
|
|
104
|
+
getInstanceCount(): number;
|
|
55
105
|
/**
|
|
56
106
|
* Build key from EC change.
|
|
57
107
|
* @param change EC change
|
|
58
108
|
* @returns key created from EC change.
|
|
59
109
|
*/
|
|
60
|
-
private
|
|
110
|
+
private buildKey;
|
|
61
111
|
/**
|
|
62
112
|
* Append partial changes which will be combine using there instance key.
|
|
63
113
|
* @note $meta property must be present on partial change as information
|
|
@@ -66,10 +116,6 @@ export declare class PartialECChangeUnifier {
|
|
|
66
116
|
* @beta
|
|
67
117
|
*/
|
|
68
118
|
appendFrom(adaptor: ChangesetECAdaptor): void;
|
|
69
|
-
/**
|
|
70
|
-
* Delete $meta from all the instances.
|
|
71
|
-
*/
|
|
72
|
-
stripMetaData(): void;
|
|
73
119
|
/**
|
|
74
120
|
* Returns complete EC change instances.
|
|
75
121
|
* @beta
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChangesetECAdaptor.d.ts","sourceRoot":"","sources":["../../src/ChangesetECAdaptor.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"ChangesetECAdaptor.d.ts","sourceRoot":"","sources":["../../src/ChangesetECAdaptor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ChangesetECAdaptor = exports.PartialECChangeUnifier = void 0;
|
|
3
|
+
exports.ChangesetECAdaptor = exports.PartialECChangeUnifier = exports.ECChangeUnifierCache = void 0;
|
|
4
4
|
/*---------------------------------------------------------------------------------------------
|
|
5
5
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
6
6
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
@@ -9,6 +9,9 @@ exports.ChangesetECAdaptor = exports.PartialECChangeUnifier = void 0;
|
|
|
9
9
|
* @module ECDb
|
|
10
10
|
*/
|
|
11
11
|
const core_bentley_1 = require("@itwin/core-bentley");
|
|
12
|
+
const core_common_1 = require("@itwin/core-common");
|
|
13
|
+
const ECDb_1 = require("./ECDb");
|
|
14
|
+
const Symbols_1 = require("./internal/Symbols");
|
|
12
15
|
class ECDbMap {
|
|
13
16
|
db;
|
|
14
17
|
_cachedClassMaps = new Map();
|
|
@@ -321,6 +324,186 @@ var DateTime;
|
|
|
321
324
|
}
|
|
322
325
|
DateTime.fromJulianDay = fromJulianDay;
|
|
323
326
|
})(DateTime || (DateTime = {}));
|
|
327
|
+
var ECChangeUnifierCache;
|
|
328
|
+
(function (ECChangeUnifierCache) {
|
|
329
|
+
function createInMemory() {
|
|
330
|
+
return new InMemoryInstanceCache();
|
|
331
|
+
}
|
|
332
|
+
ECChangeUnifierCache.createInMemory = createInMemory;
|
|
333
|
+
function createSqliteBacked(db, bufferedReadInstanceSizeInBytes = 1024 * 1024 * 10) {
|
|
334
|
+
return new SqliteBackedInstanceCache(db, bufferedReadInstanceSizeInBytes);
|
|
335
|
+
}
|
|
336
|
+
ECChangeUnifierCache.createSqliteBacked = createSqliteBacked;
|
|
337
|
+
})(ECChangeUnifierCache || (exports.ECChangeUnifierCache = ECChangeUnifierCache = {}));
|
|
338
|
+
/**
|
|
339
|
+
* In-memory cache for storing changed EC instances.
|
|
340
|
+
*/
|
|
341
|
+
class InMemoryInstanceCache {
|
|
342
|
+
_cache = new Map();
|
|
343
|
+
/**
|
|
344
|
+
* Retrieves the changed EC instance associated with the specified key.
|
|
345
|
+
* @param key - The key used to retrieve the instance.
|
|
346
|
+
* @returns The changed EC instance, or undefined if not found.
|
|
347
|
+
*/
|
|
348
|
+
get(key) {
|
|
349
|
+
return this._cache.get(key);
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Sets the changed EC instance associated with the specified key.
|
|
353
|
+
* @param key - The key used to store the instance.
|
|
354
|
+
* @param value - The changed EC instance to be stored.
|
|
355
|
+
*/
|
|
356
|
+
set(key, value) {
|
|
357
|
+
const meta = value.$meta;
|
|
358
|
+
// Remove undefined keys
|
|
359
|
+
if (meta) {
|
|
360
|
+
Object.keys(meta).forEach((k) => meta[k] === undefined && delete meta[k]);
|
|
361
|
+
}
|
|
362
|
+
this._cache.set(key, value);
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Returns an iterator over all the changed EC instances in the cache.
|
|
366
|
+
* @returns An iterator over all the changed EC instances.
|
|
367
|
+
*/
|
|
368
|
+
*all() {
|
|
369
|
+
for (const key of Array.from(this._cache.keys()).sort()) {
|
|
370
|
+
const instance = this._cache.get(key);
|
|
371
|
+
if (instance) {
|
|
372
|
+
yield instance;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Returns the number of changed EC instances in the cache.
|
|
378
|
+
* @returns The number of changed EC instances.
|
|
379
|
+
*/
|
|
380
|
+
count() {
|
|
381
|
+
return this._cache.size;
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Disposes the cache.
|
|
385
|
+
*/
|
|
386
|
+
[Symbol.dispose]() {
|
|
387
|
+
// Implementation details
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Represents a cache for unifying EC changes in a SQLite-backed instance cache.
|
|
392
|
+
*/
|
|
393
|
+
class SqliteBackedInstanceCache {
|
|
394
|
+
_db;
|
|
395
|
+
bufferedReadInstanceSizeInBytes;
|
|
396
|
+
_cacheTable = `[temp].[${core_bentley_1.Guid.createValue()}]`;
|
|
397
|
+
static defaultBufferSize = 1024 * 1024 * 10; // 10MB
|
|
398
|
+
/**
|
|
399
|
+
* Creates an instance of SqliteBackedInstanceCache.
|
|
400
|
+
* @param _db The underlying database connection.
|
|
401
|
+
* @param bufferedReadInstanceSizeInBytes The size of read instance buffer defaults to 10Mb.
|
|
402
|
+
* @throws Error if bufferedReadInstanceSizeInBytes is less than or equal to 0.
|
|
403
|
+
*/
|
|
404
|
+
constructor(_db, bufferedReadInstanceSizeInBytes = SqliteBackedInstanceCache.defaultBufferSize) {
|
|
405
|
+
this._db = _db;
|
|
406
|
+
this.bufferedReadInstanceSizeInBytes = bufferedReadInstanceSizeInBytes;
|
|
407
|
+
if (bufferedReadInstanceSizeInBytes <= 0)
|
|
408
|
+
throw new Error("bufferedReadInstanceCount must be greater than 0");
|
|
409
|
+
this.createTempTable();
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Creates a temporary table in the database for caching instances.
|
|
413
|
+
* @throws Error if unable to create the temporary table.
|
|
414
|
+
*/
|
|
415
|
+
createTempTable() {
|
|
416
|
+
this._db.withSqliteStatement(`CREATE TABLE ${this._cacheTable} ([key] text primary key, [value] text)`, (stmt) => {
|
|
417
|
+
if (core_bentley_1.DbResult.BE_SQLITE_DONE !== stmt.step())
|
|
418
|
+
throw new Error("unable to create temp table");
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Drops the temporary table from the database.
|
|
423
|
+
* @throws Error if unable to drop the temporary table.
|
|
424
|
+
*/
|
|
425
|
+
dropTempTable() {
|
|
426
|
+
this._db.saveChanges();
|
|
427
|
+
if (this._db instanceof ECDb_1.ECDb)
|
|
428
|
+
this._db.clearStatementCache();
|
|
429
|
+
else {
|
|
430
|
+
this._db.clearCaches();
|
|
431
|
+
this._db[Symbols_1._nativeDb].clearECDbCache();
|
|
432
|
+
}
|
|
433
|
+
this._db.withSqliteStatement(`DROP TABLE IF EXISTS ${this._cacheTable}`, (stmt) => {
|
|
434
|
+
if (core_bentley_1.DbResult.BE_SQLITE_DONE !== stmt.step())
|
|
435
|
+
throw new Error("unable to drop temp table");
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Retrieves the changed EC instance from the cache based on the specified key.
|
|
440
|
+
* @param key The key of the instance.
|
|
441
|
+
* @returns The changed EC instance if found, otherwise undefined.
|
|
442
|
+
*/
|
|
443
|
+
get(key) {
|
|
444
|
+
return this._db.withPreparedSqliteStatement(`SELECT [value] FROM ${this._cacheTable} WHERE [key]=?`, (stmt) => {
|
|
445
|
+
stmt.bindString(1, key);
|
|
446
|
+
if (stmt.step() === core_bentley_1.DbResult.BE_SQLITE_ROW) {
|
|
447
|
+
const out = JSON.parse(stmt.getValueString(0), core_common_1.Base64EncodedString.reviver);
|
|
448
|
+
return out;
|
|
449
|
+
}
|
|
450
|
+
return undefined;
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Sets the changed EC instance in the cache with the specified key.
|
|
455
|
+
* @param key The key of the instance.
|
|
456
|
+
* @param value The changed EC instance to be set.
|
|
457
|
+
*/
|
|
458
|
+
set(key, value) {
|
|
459
|
+
const shallowCopy = Object.assign({}, value);
|
|
460
|
+
this._db.withPreparedSqliteStatement(`INSERT INTO ${this._cacheTable} ([key], [value]) VALUES (?, ?) ON CONFLICT ([key]) DO UPDATE SET [value] = [excluded].[value]`, (stmt) => {
|
|
461
|
+
stmt.bindString(1, key);
|
|
462
|
+
stmt.bindString(2, JSON.stringify(shallowCopy, core_common_1.Base64EncodedString.replacer));
|
|
463
|
+
stmt.step();
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Returns an iterator for all the changed EC instances in the cache.
|
|
468
|
+
* @returns An iterator for all the changed EC instances.
|
|
469
|
+
*/
|
|
470
|
+
*all() {
|
|
471
|
+
const sql = `
|
|
472
|
+
SELECT JSON_GROUP_ARRAY (JSON([value]))
|
|
473
|
+
FROM (SELECT
|
|
474
|
+
[value],
|
|
475
|
+
SUM (LENGTH ([value])) OVER (ORDER BY [key] ROWS UNBOUNDED PRECEDING) / ${this.bufferedReadInstanceSizeInBytes} AS [bucket]
|
|
476
|
+
FROM ${this._cacheTable})
|
|
477
|
+
GROUP BY [bucket]`;
|
|
478
|
+
const stmt = this._db.prepareSqliteStatement(sql);
|
|
479
|
+
while (stmt.step() === core_bentley_1.DbResult.BE_SQLITE_ROW) {
|
|
480
|
+
const instanceBucket = JSON.parse(stmt.getValueString(0), core_common_1.Base64EncodedString.reviver);
|
|
481
|
+
for (const value of instanceBucket) {
|
|
482
|
+
yield value;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
stmt[Symbol.dispose]();
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Returns the number of instances in the cache.
|
|
489
|
+
* @returns The number of instances in the cache.
|
|
490
|
+
*/
|
|
491
|
+
count() {
|
|
492
|
+
return this._db.withPreparedSqliteStatement(`SELECT COUNT(*) FROM ${this._cacheTable}`, (stmt) => {
|
|
493
|
+
if (stmt.step() === core_bentley_1.DbResult.BE_SQLITE_ROW)
|
|
494
|
+
return stmt.getValue(0).getInteger();
|
|
495
|
+
return 0;
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Disposes the cache by dropping the temporary table.
|
|
500
|
+
*/
|
|
501
|
+
[Symbol.dispose]() {
|
|
502
|
+
if (this._db.isOpen) {
|
|
503
|
+
this.dropTempTable();
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
324
507
|
/**
|
|
325
508
|
* Combine partial changed instance into single instance.
|
|
326
509
|
* Partial changes is per table and a single instance can
|
|
@@ -328,15 +511,26 @@ var DateTime;
|
|
|
328
511
|
* @beta
|
|
329
512
|
*/
|
|
330
513
|
class PartialECChangeUnifier {
|
|
331
|
-
|
|
514
|
+
_db;
|
|
515
|
+
_cache;
|
|
332
516
|
_readonly = false;
|
|
517
|
+
constructor(_db, _cache = new InMemoryInstanceCache()) {
|
|
518
|
+
this._db = _db;
|
|
519
|
+
this._cache = _cache;
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Dispose the instance.
|
|
523
|
+
*/
|
|
524
|
+
[Symbol.dispose]() {
|
|
525
|
+
this._cache[Symbol.dispose]();
|
|
526
|
+
}
|
|
333
527
|
/**
|
|
334
528
|
* Get root class id for a given class
|
|
335
529
|
* @param classId given class id
|
|
336
530
|
* @param db use to find root class
|
|
337
531
|
* @returns return root class id
|
|
338
532
|
*/
|
|
339
|
-
|
|
533
|
+
getRootClassId(classId) {
|
|
340
534
|
const sql = `
|
|
341
535
|
WITH
|
|
342
536
|
[base_class]([classId], [baseClassId], [Level]) AS(
|
|
@@ -359,7 +553,7 @@ class PartialECChangeUnifier {
|
|
|
359
553
|
WHERE [cc].[Name] = 'IsMixIn'
|
|
360
554
|
AND [ss].[Name] = 'CoreCustomAttributes'))
|
|
361
555
|
ORDER BY [Level] DESC`;
|
|
362
|
-
return
|
|
556
|
+
return this._db.withSqliteStatement(sql, (stmt) => {
|
|
363
557
|
stmt.bindId(1, classId);
|
|
364
558
|
if (stmt.step() === core_bentley_1.DbResult.BE_SQLITE_ROW && !stmt.isValueNull(0)) {
|
|
365
559
|
return stmt.getValueString(0);
|
|
@@ -367,15 +561,30 @@ class PartialECChangeUnifier {
|
|
|
367
561
|
return classId;
|
|
368
562
|
});
|
|
369
563
|
}
|
|
564
|
+
/**
|
|
565
|
+
* Checks if the given `rhsClassId` is an instance of the `lhsClassId`.
|
|
566
|
+
* @param rhsClassId The ID of the right-hand side class.
|
|
567
|
+
* @param lhsClassId The ID of the left-hand side class.
|
|
568
|
+
* @returns `true` if `rhsClassId` is an instance of `lhsClassId`, `false` otherwise.
|
|
569
|
+
*/
|
|
570
|
+
instanceOf(rhsClassId, lhsClassId) {
|
|
571
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
572
|
+
return this._db.withPreparedStatement("SELECT ec_instanceof(?,?)", (stmt) => {
|
|
573
|
+
stmt.bindId(1, rhsClassId);
|
|
574
|
+
stmt.bindId(2, lhsClassId);
|
|
575
|
+
stmt.step();
|
|
576
|
+
return stmt.getValue(0).getInteger() === 1;
|
|
577
|
+
});
|
|
578
|
+
}
|
|
370
579
|
/**
|
|
371
580
|
* Combine partial instance with instance with same key if already exists.
|
|
372
581
|
* @param rhs partial instance
|
|
373
582
|
*/
|
|
374
|
-
combine(rhs
|
|
583
|
+
combine(rhs) {
|
|
375
584
|
if (!rhs.$meta) {
|
|
376
585
|
throw new Error("PartialECChange being combine must have '$meta' property");
|
|
377
586
|
}
|
|
378
|
-
const key =
|
|
587
|
+
const key = this.buildKey(rhs);
|
|
379
588
|
const lhs = this._cache.get(key);
|
|
380
589
|
if (lhs) {
|
|
381
590
|
const { $meta: _, ...restOfRhs } = rhs;
|
|
@@ -384,37 +593,39 @@ class PartialECChangeUnifier {
|
|
|
384
593
|
lhs.$meta.tables = [...rhs.$meta?.tables, ...lhs.$meta?.tables];
|
|
385
594
|
lhs.$meta.changeIndexes = [...rhs.$meta?.changeIndexes, ...lhs.$meta?.changeIndexes];
|
|
386
595
|
// we preserve child class name & id when merging instance.
|
|
387
|
-
if (rhs.$meta.fallbackClassId && lhs.$meta.fallbackClassId &&
|
|
596
|
+
if (rhs.$meta.fallbackClassId && lhs.$meta.fallbackClassId && rhs.$meta.fallbackClassId !== lhs.$meta.fallbackClassId) {
|
|
388
597
|
const lhsClassId = lhs.$meta.fallbackClassId;
|
|
389
598
|
const rhsClassId = rhs.$meta.fallbackClassId;
|
|
390
|
-
|
|
391
|
-
const isRhsIsSubClassOfLhs = db.withPreparedStatement("SELECT ec_instanceof(?,?)", (stmt) => {
|
|
392
|
-
stmt.bindId(1, rhsClassId);
|
|
393
|
-
stmt.bindId(2, lhsClassId);
|
|
394
|
-
stmt.step();
|
|
395
|
-
return stmt.getValue(0).getInteger() === 1;
|
|
396
|
-
});
|
|
599
|
+
const isRhsIsSubClassOfLhs = this.instanceOf(rhsClassId, lhsClassId);
|
|
397
600
|
if (isRhsIsSubClassOfLhs) {
|
|
398
601
|
lhs.$meta.fallbackClassId = rhs.$meta.fallbackClassId;
|
|
399
602
|
lhs.$meta.classFullName = rhs.$meta.classFullName;
|
|
400
603
|
}
|
|
401
604
|
}
|
|
402
605
|
}
|
|
606
|
+
this._cache.set(key, lhs);
|
|
403
607
|
}
|
|
404
608
|
else {
|
|
405
609
|
this._cache.set(key, rhs);
|
|
406
610
|
}
|
|
407
611
|
}
|
|
612
|
+
/**
|
|
613
|
+
* Returns the number of instances in the cache.
|
|
614
|
+
* @returns The number of instances in the cache.
|
|
615
|
+
*/
|
|
616
|
+
getInstanceCount() {
|
|
617
|
+
return this._cache.count();
|
|
618
|
+
}
|
|
408
619
|
/**
|
|
409
620
|
* Build key from EC change.
|
|
410
621
|
* @param change EC change
|
|
411
622
|
* @returns key created from EC change.
|
|
412
623
|
*/
|
|
413
|
-
|
|
624
|
+
buildKey(change) {
|
|
414
625
|
let classId = change.ECClassId;
|
|
415
626
|
if (typeof classId === "undefined") {
|
|
416
|
-
if (
|
|
417
|
-
classId = this.getRootClassId(change.$meta.fallbackClassId
|
|
627
|
+
if (change.$meta?.fallbackClassId) {
|
|
628
|
+
classId = this.getRootClassId(change.$meta.fallbackClassId);
|
|
418
629
|
}
|
|
419
630
|
if (typeof classId === "undefined") {
|
|
420
631
|
throw new Error(`unable to resolve ECClassId to root class id.`);
|
|
@@ -437,32 +648,23 @@ class PartialECChangeUnifier {
|
|
|
437
648
|
throw new Error("this instance is marked as readonly.");
|
|
438
649
|
}
|
|
439
650
|
if (adaptor.op === "Updated" && adaptor.inserted && adaptor.deleted) {
|
|
440
|
-
this.combine(adaptor.inserted
|
|
441
|
-
this.combine(adaptor.deleted
|
|
651
|
+
this.combine(adaptor.inserted);
|
|
652
|
+
this.combine(adaptor.deleted);
|
|
442
653
|
}
|
|
443
654
|
else if (adaptor.op === "Inserted" && adaptor.inserted) {
|
|
444
|
-
this.combine(adaptor.inserted
|
|
655
|
+
this.combine(adaptor.inserted);
|
|
445
656
|
}
|
|
446
657
|
else if (adaptor.op === "Deleted" && adaptor.deleted) {
|
|
447
|
-
this.combine(adaptor.deleted
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
/**
|
|
451
|
-
* Delete $meta from all the instances.
|
|
452
|
-
*/
|
|
453
|
-
stripMetaData() {
|
|
454
|
-
for (const inst of this._cache.values()) {
|
|
455
|
-
if ("$meta" in inst) {
|
|
456
|
-
delete inst.$meta;
|
|
457
|
-
}
|
|
658
|
+
this.combine(adaptor.deleted);
|
|
458
659
|
}
|
|
459
|
-
this._readonly = true;
|
|
460
660
|
}
|
|
461
661
|
/**
|
|
462
662
|
* Returns complete EC change instances.
|
|
463
663
|
* @beta
|
|
464
664
|
*/
|
|
465
|
-
get instances() {
|
|
665
|
+
get instances() {
|
|
666
|
+
return this._cache.all();
|
|
667
|
+
}
|
|
466
668
|
}
|
|
467
669
|
exports.PartialECChangeUnifier = PartialECChangeUnifier;
|
|
468
670
|
/**
|