@itwin/core-backend 5.7.0-dev.1 → 5.7.0-dev.11
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 +13 -1
- package/lib/cjs/BriefcaseManager.d.ts.map +1 -1
- package/lib/cjs/BriefcaseManager.js +37 -14
- package/lib/cjs/BriefcaseManager.js.map +1 -1
- package/lib/cjs/IModelDb.d.ts +111 -23
- package/lib/cjs/IModelDb.d.ts.map +1 -1
- package/lib/cjs/IModelDb.js +108 -2
- package/lib/cjs/IModelDb.js.map +1 -1
- package/lib/cjs/StashManager.d.ts +1 -2
- package/lib/cjs/StashManager.d.ts.map +1 -1
- package/lib/cjs/StashManager.js.map +1 -1
- package/lib/cjs/TxnManager.d.ts +76 -55
- package/lib/cjs/TxnManager.d.ts.map +1 -1
- package/lib/cjs/TxnManager.js +116 -29
- package/lib/cjs/TxnManager.js.map +1 -1
- package/lib/cjs/internal/IntegrityCheck.d.ts +240 -0
- package/lib/cjs/internal/IntegrityCheck.d.ts.map +1 -0
- package/lib/cjs/internal/IntegrityCheck.js +193 -0
- package/lib/cjs/internal/IntegrityCheck.js.map +1 -0
- package/lib/esm/BriefcaseManager.d.ts.map +1 -1
- package/lib/esm/BriefcaseManager.js +37 -14
- package/lib/esm/BriefcaseManager.js.map +1 -1
- package/lib/esm/IModelDb.d.ts +111 -23
- package/lib/esm/IModelDb.d.ts.map +1 -1
- package/lib/esm/IModelDb.js +108 -2
- package/lib/esm/IModelDb.js.map +1 -1
- package/lib/esm/StashManager.d.ts +1 -2
- package/lib/esm/StashManager.d.ts.map +1 -1
- package/lib/esm/StashManager.js.map +1 -1
- package/lib/esm/TxnManager.d.ts +76 -55
- package/lib/esm/TxnManager.d.ts.map +1 -1
- package/lib/esm/TxnManager.js +116 -29
- package/lib/esm/TxnManager.js.map +1 -1
- package/lib/esm/internal/IntegrityCheck.d.ts +240 -0
- package/lib/esm/internal/IntegrityCheck.d.ts.map +1 -0
- package/lib/esm/internal/IntegrityCheck.js +187 -0
- package/lib/esm/internal/IntegrityCheck.js.map +1 -0
- package/lib/esm/test/hubaccess/Rebase.test.js +201 -12
- package/lib/esm/test/hubaccess/Rebase.test.js.map +1 -1
- package/lib/esm/test/schema/IModelSchemaContext.test.js +72 -2
- package/lib/esm/test/schema/IModelSchemaContext.test.js.map +1 -1
- package/lib/esm/test/standalone/ChangeMerge.test.js +9 -9
- package/lib/esm/test/standalone/ChangeMerge.test.js.map +1 -1
- package/lib/esm/test/standalone/ChangesetReader.test.js +173 -2
- package/lib/esm/test/standalone/ChangesetReader.test.js.map +1 -1
- package/lib/esm/test/standalone/ExportGraphics.test.js +89 -0
- package/lib/esm/test/standalone/ExportGraphics.test.js.map +1 -1
- package/lib/esm/test/standalone/IntegrityCheck.test.d.ts +2 -0
- package/lib/esm/test/standalone/IntegrityCheck.test.d.ts.map +1 -0
- package/lib/esm/test/standalone/IntegrityCheck.test.js +385 -0
- package/lib/esm/test/standalone/IntegrityCheck.test.js.map +1 -0
- package/package.json +14 -14
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { IModelStatus } from "@itwin/core-bentley";
|
|
6
|
+
import { IModelError } from "@itwin/core-common";
|
|
7
|
+
/**
|
|
8
|
+
* Information about each integrity check type, including the name, expected result type, and SQL query to execute
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
export const integrityCheckTypeMap = {
|
|
12
|
+
checkDataColumns: {
|
|
13
|
+
name: "Check Data Columns",
|
|
14
|
+
resultType: "CheckDataColumnsResultRow",
|
|
15
|
+
sqlCommand: "check_data_columns",
|
|
16
|
+
sqlQuery: `PRAGMA integrity_check(check_data_columns) options enable_experimental_features`,
|
|
17
|
+
},
|
|
18
|
+
checkECProfile: {
|
|
19
|
+
name: "Check EC Profile",
|
|
20
|
+
resultType: "CheckECProfileResultRow",
|
|
21
|
+
sqlCommand: "check_ec_profile",
|
|
22
|
+
sqlQuery: `PRAGMA integrity_check(check_ec_profile) options enable_experimental_features`,
|
|
23
|
+
},
|
|
24
|
+
checkNavigationClassIds: {
|
|
25
|
+
name: "Check Navigation Class Ids",
|
|
26
|
+
resultType: "CheckNavClassIdsResultRow",
|
|
27
|
+
sqlCommand: "check_nav_class_ids",
|
|
28
|
+
sqlQuery: `PRAGMA integrity_check(check_nav_class_ids) options enable_experimental_features`,
|
|
29
|
+
},
|
|
30
|
+
checkNavigationIds: {
|
|
31
|
+
name: "Check Navigation Ids",
|
|
32
|
+
resultType: "CheckNavIdsResultRow",
|
|
33
|
+
sqlCommand: "check_nav_ids",
|
|
34
|
+
sqlQuery: `PRAGMA integrity_check(check_nav_ids) options enable_experimental_features`,
|
|
35
|
+
},
|
|
36
|
+
checkLinktableForeignKeyClassIds: {
|
|
37
|
+
name: "Check Link Table Foreign Key Class Ids",
|
|
38
|
+
resultType: "CheckLinkTableFkClassIdsResultRow",
|
|
39
|
+
sqlCommand: "check_linktable_fk_class_ids",
|
|
40
|
+
sqlQuery: `PRAGMA integrity_check(check_linktable_fk_class_ids) options enable_experimental_features`,
|
|
41
|
+
},
|
|
42
|
+
checkLinktableForeignKeyIds: {
|
|
43
|
+
name: "Check Link Table Foreign Key Ids",
|
|
44
|
+
resultType: "CheckLinkTableFkIdsResultRow",
|
|
45
|
+
sqlCommand: "check_linktable_fk_ids",
|
|
46
|
+
sqlQuery: `PRAGMA integrity_check(check_linktable_fk_ids) options enable_experimental_features`,
|
|
47
|
+
},
|
|
48
|
+
checkClassIds: {
|
|
49
|
+
name: "Check Class Ids",
|
|
50
|
+
resultType: "CheckClassIdsResultRow",
|
|
51
|
+
sqlCommand: "check_class_ids",
|
|
52
|
+
sqlQuery: `PRAGMA integrity_check(check_class_ids) options enable_experimental_features`,
|
|
53
|
+
},
|
|
54
|
+
checkDataSchema: {
|
|
55
|
+
name: "Check Data Schema",
|
|
56
|
+
resultType: "CheckDataSchemaResultRow",
|
|
57
|
+
sqlCommand: "check_data_schema",
|
|
58
|
+
sqlQuery: `PRAGMA integrity_check(check_data_schema) options enable_experimental_features`,
|
|
59
|
+
},
|
|
60
|
+
checkSchemaLoad: {
|
|
61
|
+
name: "Check Schema Load",
|
|
62
|
+
resultType: "CheckSchemaLoadResultRow",
|
|
63
|
+
sqlCommand: "check_schema_load",
|
|
64
|
+
sqlQuery: `PRAGMA integrity_check(check_schema_load) options enable_experimental_features`,
|
|
65
|
+
},
|
|
66
|
+
checkMissingChildRows: {
|
|
67
|
+
name: "Check Missing Child Rows",
|
|
68
|
+
resultType: "CheckMissingChildRowsResultRow",
|
|
69
|
+
sqlCommand: "check_missing_child_rows",
|
|
70
|
+
sqlQuery: `PRAGMA integrity_check(check_missing_child_rows) options enable_experimental_features`,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Gets the user-friendly name of an integrity check based on its key or SQL command.
|
|
75
|
+
* It first attempts to find a direct match for the key in the integrityCheckTypeMap. If not found, it searches for a match based on the SQL command.
|
|
76
|
+
* If still not found, it returns the original check string.
|
|
77
|
+
* @param check - The integrity check key or SQL command to get the name of
|
|
78
|
+
* @returns The user-friendly name of the integrity check, or the original check string if no match is found
|
|
79
|
+
* @internal
|
|
80
|
+
*/
|
|
81
|
+
export function getIntegrityCheckName(check) {
|
|
82
|
+
// First try direct lookup by key
|
|
83
|
+
const directLookup = integrityCheckTypeMap[check];
|
|
84
|
+
if (directLookup) {
|
|
85
|
+
return directLookup.name;
|
|
86
|
+
}
|
|
87
|
+
// If not found, search by sqlCommand
|
|
88
|
+
for (const [, value] of Object.entries(integrityCheckTypeMap)) {
|
|
89
|
+
if (value.sqlCommand === check) {
|
|
90
|
+
return value.name;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Fallback to the original check string
|
|
94
|
+
return check;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Performs a quick integrity check on the given iModel.
|
|
98
|
+
* @param iModel The IModelDb instance to perform the integrity check on
|
|
99
|
+
* @returns An array of results for each check performed, including the check name, whether it passed, and the elapsed time in seconds
|
|
100
|
+
* @internal
|
|
101
|
+
*/
|
|
102
|
+
export async function performQuickIntegrityCheck(iModel) {
|
|
103
|
+
const integrityCheckQuery = "PRAGMA integrity_check options enable_experimental_features";
|
|
104
|
+
const integrityCheckResults = [];
|
|
105
|
+
for await (const row of iModel.createQueryReader(integrityCheckQuery)) {
|
|
106
|
+
integrityCheckResults.push({ check: getIntegrityCheckName(row.check), passed: row.result, elapsedSeconds: row.elapsed_sec });
|
|
107
|
+
}
|
|
108
|
+
;
|
|
109
|
+
return integrityCheckResults;
|
|
110
|
+
}
|
|
111
|
+
export async function performSpecificIntegrityCheck(iModel, check) {
|
|
112
|
+
switch (check) {
|
|
113
|
+
case "checkDataColumns": {
|
|
114
|
+
const results = [];
|
|
115
|
+
for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkDataColumns.sqlQuery)) {
|
|
116
|
+
results.push({ sno: row.sno, table: row.table, column: row.column });
|
|
117
|
+
}
|
|
118
|
+
return results;
|
|
119
|
+
}
|
|
120
|
+
case "checkECProfile": {
|
|
121
|
+
const results = [];
|
|
122
|
+
for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkECProfile.sqlQuery)) {
|
|
123
|
+
results.push({ sno: row.sno, type: row.type, name: row.name, issue: row.issue });
|
|
124
|
+
}
|
|
125
|
+
return results;
|
|
126
|
+
}
|
|
127
|
+
case "checkNavigationClassIds": {
|
|
128
|
+
const results = [];
|
|
129
|
+
for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkNavigationClassIds.sqlQuery)) {
|
|
130
|
+
results.push({ sno: row.sno, id: row.id, class: row.class, property: row.property, navId: row.nav_id, navClassId: row.nav_classId });
|
|
131
|
+
}
|
|
132
|
+
return results;
|
|
133
|
+
}
|
|
134
|
+
case "checkNavigationIds": {
|
|
135
|
+
const results = [];
|
|
136
|
+
for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkNavigationIds.sqlQuery)) {
|
|
137
|
+
results.push({ sno: row.sno, id: row.id, class: row.class, property: row.property, navId: row.nav_id, primaryClass: row.primary_class });
|
|
138
|
+
}
|
|
139
|
+
return results;
|
|
140
|
+
}
|
|
141
|
+
case "checkLinktableForeignKeyClassIds": {
|
|
142
|
+
const results = [];
|
|
143
|
+
for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkLinktableForeignKeyClassIds.sqlQuery)) {
|
|
144
|
+
results.push({ sno: row.sno, id: row.id, relationship: row.relationship, property: row.property, keyId: row.key_id, keyClassId: row.key_classId });
|
|
145
|
+
}
|
|
146
|
+
return results;
|
|
147
|
+
}
|
|
148
|
+
case "checkLinktableForeignKeyIds": {
|
|
149
|
+
const results = [];
|
|
150
|
+
for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkLinktableForeignKeyIds.sqlQuery)) {
|
|
151
|
+
results.push({ sno: row.sno, id: row.id, relationship: row.relationship, property: row.property, keyId: row.key_id, primaryClass: row.primary_class });
|
|
152
|
+
}
|
|
153
|
+
return results;
|
|
154
|
+
}
|
|
155
|
+
case "checkClassIds": {
|
|
156
|
+
const results = [];
|
|
157
|
+
for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkClassIds.sqlQuery)) {
|
|
158
|
+
results.push({ sno: row.sno, class: row.class, id: row.id, classId: row.class_id, type: row.type });
|
|
159
|
+
}
|
|
160
|
+
return results;
|
|
161
|
+
}
|
|
162
|
+
case "checkDataSchema": {
|
|
163
|
+
const results = [];
|
|
164
|
+
for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkDataSchema.sqlQuery)) {
|
|
165
|
+
results.push({ sno: row.sno, type: row.type, name: row.name });
|
|
166
|
+
}
|
|
167
|
+
return results;
|
|
168
|
+
}
|
|
169
|
+
case "checkSchemaLoad": {
|
|
170
|
+
const results = [];
|
|
171
|
+
for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkSchemaLoad.sqlQuery)) {
|
|
172
|
+
results.push({ sno: row.sno, schema: row.schema });
|
|
173
|
+
}
|
|
174
|
+
return results;
|
|
175
|
+
}
|
|
176
|
+
case "checkMissingChildRows": {
|
|
177
|
+
const results = [];
|
|
178
|
+
for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkMissingChildRows.sqlQuery)) {
|
|
179
|
+
results.push({ sno: row.sno, class: row.class, id: row.id, classId: row.class_id, missingRowInTables: row.MissingRowInTables });
|
|
180
|
+
}
|
|
181
|
+
return results;
|
|
182
|
+
}
|
|
183
|
+
default:
|
|
184
|
+
throw new IModelError(IModelStatus.BadRequest, `Unknown integrity check type: ${check}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=IntegrityCheck.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IntegrityCheck.js","sourceRoot":"","sources":["../../../src/internal/IntegrityCheck.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 { IModelStatus } from \"@itwin/core-bentley\";\r\nimport { IModelError } from \"@itwin/core-common\";\r\nimport { IModelDb } from \"../IModelDb\";\r\n\r\n/**\r\n * Information about each integrity check type, including the name, expected result type, and SQL query to execute\r\n * @internal\r\n */\r\nexport const integrityCheckTypeMap = {\r\n checkDataColumns: {\r\n name: \"Check Data Columns\",\r\n resultType: \"CheckDataColumnsResultRow\",\r\n sqlCommand: \"check_data_columns\",\r\n sqlQuery: `PRAGMA integrity_check(check_data_columns) options enable_experimental_features`,\r\n },\r\n checkECProfile: {\r\n name: \"Check EC Profile\",\r\n resultType: \"CheckECProfileResultRow\",\r\n sqlCommand: \"check_ec_profile\",\r\n sqlQuery: `PRAGMA integrity_check(check_ec_profile) options enable_experimental_features`,\r\n },\r\n checkNavigationClassIds: {\r\n name: \"Check Navigation Class Ids\",\r\n resultType: \"CheckNavClassIdsResultRow\",\r\n sqlCommand: \"check_nav_class_ids\",\r\n sqlQuery: `PRAGMA integrity_check(check_nav_class_ids) options enable_experimental_features`,\r\n },\r\n checkNavigationIds: {\r\n name: \"Check Navigation Ids\",\r\n resultType: \"CheckNavIdsResultRow\",\r\n sqlCommand: \"check_nav_ids\",\r\n sqlQuery: `PRAGMA integrity_check(check_nav_ids) options enable_experimental_features`,\r\n },\r\n checkLinktableForeignKeyClassIds: {\r\n name: \"Check Link Table Foreign Key Class Ids\",\r\n resultType: \"CheckLinkTableFkClassIdsResultRow\",\r\n sqlCommand: \"check_linktable_fk_class_ids\",\r\n sqlQuery: `PRAGMA integrity_check(check_linktable_fk_class_ids) options enable_experimental_features`,\r\n },\r\n checkLinktableForeignKeyIds: {\r\n name: \"Check Link Table Foreign Key Ids\",\r\n resultType: \"CheckLinkTableFkIdsResultRow\",\r\n sqlCommand: \"check_linktable_fk_ids\",\r\n sqlQuery: `PRAGMA integrity_check(check_linktable_fk_ids) options enable_experimental_features`,\r\n },\r\n checkClassIds: {\r\n name: \"Check Class Ids\",\r\n resultType: \"CheckClassIdsResultRow\",\r\n sqlCommand: \"check_class_ids\",\r\n sqlQuery: `PRAGMA integrity_check(check_class_ids) options enable_experimental_features`,\r\n },\r\n checkDataSchema: {\r\n name: \"Check Data Schema\",\r\n resultType: \"CheckDataSchemaResultRow\",\r\n sqlCommand: \"check_data_schema\",\r\n sqlQuery: `PRAGMA integrity_check(check_data_schema) options enable_experimental_features`,\r\n },\r\n checkSchemaLoad: {\r\n name: \"Check Schema Load\",\r\n resultType: \"CheckSchemaLoadResultRow\",\r\n sqlCommand: \"check_schema_load\",\r\n sqlQuery: `PRAGMA integrity_check(check_schema_load) options enable_experimental_features`,\r\n },\r\n checkMissingChildRows: {\r\n name: \"Check Missing Child Rows\",\r\n resultType: \"CheckMissingChildRowsResultRow\",\r\n sqlCommand: \"check_missing_child_rows\",\r\n sqlQuery: `PRAGMA integrity_check(check_missing_child_rows) options enable_experimental_features`,\r\n },\r\n} as const;\r\n\r\n/**\r\n * Type representing the keys of the integrityCheckType map, which correspond to the different types of integrity checks that can be performed.\r\n */\r\nexport type IntegrityCheckKey = keyof typeof integrityCheckTypeMap;\r\n\r\n/** Map of integrity check keys to their result row types */\r\ninterface IntegrityCheckResultTypeMap {\r\n checkDataColumns: CheckDataColumnsResultRow;\r\n checkECProfile: CheckECProfileResultRow;\r\n checkNavigationClassIds: CheckNavClassIdsResultRow;\r\n checkNavigationIds: CheckNavIdsResultRow;\r\n checkLinktableForeignKeyClassIds: CheckLinkTableFkClassIdsResultRow;\r\n checkLinktableForeignKeyIds: CheckLinkTableFkIdsResultRow;\r\n checkClassIds: CheckClassIdsResultRow;\r\n checkDataSchema: CheckDataSchemaResultRow;\r\n checkSchemaLoad: CheckSchemaLoadResultRow;\r\n checkMissingChildRows: CheckMissingChildRowsResultRow;\r\n}\r\n\r\n/** Checks the Map to give the return type of a specific integrity check */\r\ntype IntegrityCheckResultRow<K extends IntegrityCheckKey> = IntegrityCheckResultTypeMap[K];\r\n\r\n/**\r\n * Return type for quick integrity check\r\n */\r\nexport interface QuickIntegrityCheckResultRow {\r\n check: string;\r\n passed: boolean;\r\n elapsedSeconds: string;\r\n}\r\n\r\n/**\r\n * Return type for Check Data Columns integrity check\r\n */\r\nexport interface CheckDataColumnsResultRow {\r\n sno: number;\r\n table: string;\r\n column: string;\r\n}\r\n\r\n/**\r\n * Return type for Check EC Profile integrity check\r\n */\r\nexport interface CheckECProfileResultRow {\r\n sno: number;\r\n type: string;\r\n name: string;\r\n issue: string;\r\n}\r\n\r\n/**\r\n * Return type for Check Navigation Class Ids integrity check\r\n */\r\nexport interface CheckNavClassIdsResultRow {\r\n sno: number;\r\n id: string;\r\n class: string;\r\n property: string;\r\n navId: string;\r\n navClassId: string;\r\n}\r\n\r\n/**\r\n * Return type for Check Navigation Ids integrity check\r\n */\r\nexport interface CheckNavIdsResultRow {\r\n sno: number;\r\n id: string;\r\n class: string;\r\n property: string;\r\n navId: string;\r\n primaryClass: string;\r\n}\r\n\r\n/**\r\n * Return type for Check Link Table Foreign Key Class Ids integrity check\r\n */\r\nexport interface CheckLinkTableFkClassIdsResultRow {\r\n sno: number;\r\n id: string;\r\n relationship: string;\r\n property: string;\r\n keyId: string;\r\n keyClassId: string;\r\n}\r\n\r\n/**\r\n * Return type for Check Link Table Foreign Key Ids integrity check\r\n */\r\nexport interface CheckLinkTableFkIdsResultRow {\r\n sno: number;\r\n id: string;\r\n relationship: string;\r\n property: string;\r\n keyId: string;\r\n primaryClass: string;\r\n}\r\n\r\n/**\r\n * Return type for Check Class Ids integrity check\r\n */\r\nexport interface CheckClassIdsResultRow {\r\n sno: number;\r\n class: string;\r\n id: string;\r\n classId: string;\r\n type: string;\r\n}\r\n\r\n/**\r\n * Return type for Check Data Schema integrity check\r\n */\r\nexport interface CheckDataSchemaResultRow {\r\n sno: number;\r\n type: string;\r\n name: string;\r\n}\r\n\r\n/**\r\n * Return type for Check Schema Load integrity check\r\n */\r\nexport interface CheckSchemaLoadResultRow {\r\n sno: number;\r\n schema: string;\r\n}\r\n\r\n/**\r\n * Return type for Check Missing Child Rows integrity check\r\n */\r\nexport interface CheckMissingChildRowsResultRow {\r\n sno: number;\r\n class: string;\r\n id: string;\r\n classId: string;\r\n missingRowInTables: string;\r\n}\r\n\r\n/**\r\n * Return type for integrity check results, including the check name, whether it passed, and the specific results (if any)\r\n */\r\nexport interface IntegrityCheckResult {\r\n /** The name of the integrity check that was performed */\r\n check: string;\r\n /** Whether the integrity check passed (i.e. no issues were found = true) */\r\n passed: boolean;\r\n /** The specific results returned by the integrity check, which may include details about any issues that were found.\r\n * In the case where issues are found, this will be an array of result rows specific to the type of check that was performed,\r\n * or an array of quick integrity check results if it was a quick check. */\r\n results: IntegrityCheckResultRow<IntegrityCheckKey>[] | QuickIntegrityCheckResultRow[];\r\n}\r\n\r\n/**\r\n * Gets the user-friendly name of an integrity check based on its key or SQL command.\r\n * It first attempts to find a direct match for the key in the integrityCheckTypeMap. If not found, it searches for a match based on the SQL command.\r\n * If still not found, it returns the original check string.\r\n * @param check - The integrity check key or SQL command to get the name of\r\n * @returns The user-friendly name of the integrity check, or the original check string if no match is found\r\n * @internal\r\n */\r\nexport function getIntegrityCheckName(check: string): string {\r\n // First try direct lookup by key\r\n const directLookup = integrityCheckTypeMap[check as IntegrityCheckKey];\r\n if (directLookup) {\r\n return directLookup.name;\r\n }\r\n // If not found, search by sqlCommand\r\n for (const [, value] of Object.entries(integrityCheckTypeMap)) {\r\n if (value.sqlCommand === check) {\r\n return value.name;\r\n }\r\n }\r\n // Fallback to the original check string\r\n return check;\r\n}\r\n\r\n/**\r\n * Performs a quick integrity check on the given iModel.\r\n * @param iModel The IModelDb instance to perform the integrity check on\r\n * @returns An array of results for each check performed, including the check name, whether it passed, and the elapsed time in seconds\r\n * @internal\r\n */\r\nexport async function performQuickIntegrityCheck(iModel: IModelDb): Promise<QuickIntegrityCheckResultRow[]> {\r\n const integrityCheckQuery = \"PRAGMA integrity_check options enable_experimental_features\";\r\n const integrityCheckResults: QuickIntegrityCheckResultRow[] = [];\r\n for await (const row of iModel.createQueryReader(integrityCheckQuery)) {\r\n integrityCheckResults.push({ check: getIntegrityCheckName(row.check), passed: row.result, elapsedSeconds: row.elapsed_sec});\r\n };\r\n return integrityCheckResults;\r\n}\r\n\r\n/**\r\n * Performs a specific integrity check on the given iModel based on the provided check key, and returns the results specific to that check type.\r\n * @param iModel The IModelDb instance to perform the integrity check on\r\n * @param check The key of the specific integrity check to perform\r\n * @return An array of results specific to the integrity check that was performed. The type of the result rows will depend on the check that was executed.\r\n * @throws IModelError with status BadRequest if an unknown integrity check key is provided\r\n * @internal\r\n */\r\nexport async function performSpecificIntegrityCheck(iModel: IModelDb, check: \"checkDataColumns\"): Promise<IntegrityCheckResultRow<\"checkDataColumns\">[]>;\r\nexport async function performSpecificIntegrityCheck(iModel: IModelDb, check: \"checkECProfile\"): Promise<IntegrityCheckResultRow<\"checkECProfile\">[]>;\r\nexport async function performSpecificIntegrityCheck(iModel: IModelDb, check: \"checkNavigationClassIds\"): Promise<IntegrityCheckResultRow<\"checkNavigationClassIds\">[]>;\r\nexport async function performSpecificIntegrityCheck(iModel: IModelDb, check: \"checkNavigationIds\"): Promise<IntegrityCheckResultRow<\"checkNavigationIds\">[]>;\r\nexport async function performSpecificIntegrityCheck(iModel: IModelDb, check: \"checkLinktableForeignKeyClassIds\"): Promise<IntegrityCheckResultRow<\"checkLinktableForeignKeyClassIds\">[]>;\r\nexport async function performSpecificIntegrityCheck(iModel: IModelDb, check: \"checkLinktableForeignKeyIds\"): Promise<IntegrityCheckResultRow<\"checkLinktableForeignKeyIds\">[]>;\r\nexport async function performSpecificIntegrityCheck(iModel: IModelDb, check: \"checkClassIds\"): Promise<IntegrityCheckResultRow<\"checkClassIds\">[]>;\r\nexport async function performSpecificIntegrityCheck(iModel: IModelDb, check: \"checkDataSchema\"): Promise<IntegrityCheckResultRow<\"checkDataSchema\">[]>;\r\nexport async function performSpecificIntegrityCheck(iModel: IModelDb, check: \"checkSchemaLoad\"): Promise<IntegrityCheckResultRow<\"checkSchemaLoad\">[]>;\r\nexport async function performSpecificIntegrityCheck(iModel: IModelDb, check: \"checkMissingChildRows\"): Promise<IntegrityCheckResultRow<\"checkMissingChildRows\">[]>;\r\nexport async function performSpecificIntegrityCheck<K extends IntegrityCheckKey>(iModel: IModelDb, check: K): Promise<IntegrityCheckResultRow<K>[]>;\r\nexport async function performSpecificIntegrityCheck(iModel: IModelDb, check: IntegrityCheckKey): Promise<IntegrityCheckResultRow<IntegrityCheckKey>[]> {\r\n switch (check) {\r\n case \"checkDataColumns\": {\r\n const results: CheckDataColumnsResultRow[] = [];\r\n for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkDataColumns.sqlQuery)) {\r\n results.push({ sno: row.sno, table: row.table, column: row.column });\r\n }\r\n return results;\r\n }\r\n case \"checkECProfile\": {\r\n const results: CheckECProfileResultRow[] = [];\r\n for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkECProfile.sqlQuery)) {\r\n results.push({ sno: row.sno, type: row.type, name: row.name, issue: row.issue });\r\n }\r\n return results;\r\n }\r\n case \"checkNavigationClassIds\": {\r\n const results: CheckNavClassIdsResultRow[] = [];\r\n for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkNavigationClassIds.sqlQuery)) {\r\n results.push({ sno: row.sno, id: row.id, class: row.class, property: row.property, navId: row.nav_id, navClassId: row.nav_classId });\r\n }\r\n return results;\r\n }\r\n case \"checkNavigationIds\": {\r\n const results: CheckNavIdsResultRow[] = [];\r\n for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkNavigationIds.sqlQuery)) {\r\n results.push({ sno: row.sno, id: row.id, class: row.class, property: row.property, navId: row.nav_id, primaryClass: row.primary_class });\r\n }\r\n return results;\r\n }\r\n case \"checkLinktableForeignKeyClassIds\": {\r\n const results: CheckLinkTableFkClassIdsResultRow[] = [];\r\n for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkLinktableForeignKeyClassIds.sqlQuery)) {\r\n results.push({ sno: row.sno, id: row.id, relationship: row.relationship, property: row.property, keyId: row.key_id, keyClassId: row.key_classId });\r\n }\r\n return results;\r\n }\r\n case \"checkLinktableForeignKeyIds\": {\r\n const results: CheckLinkTableFkIdsResultRow[] = [];\r\n for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkLinktableForeignKeyIds.sqlQuery)) {\r\n results.push({ sno: row.sno, id: row.id, relationship: row.relationship, property: row.property, keyId: row.key_id, primaryClass: row.primary_class });\r\n }\r\n return results;\r\n }\r\n case \"checkClassIds\": {\r\n const results: CheckClassIdsResultRow[] = [];\r\n for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkClassIds.sqlQuery)) {\r\n results.push({ sno: row.sno, class: row.class, id: row.id, classId: row.class_id, type: row.type });\r\n }\r\n return results;\r\n }\r\n case \"checkDataSchema\": {\r\n const results: CheckDataSchemaResultRow[] = [];\r\n for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkDataSchema.sqlQuery)) {\r\n results.push({ sno: row.sno, type: row.type, name: row.name });\r\n }\r\n return results;\r\n }\r\n case \"checkSchemaLoad\": {\r\n const results: CheckSchemaLoadResultRow[] = [];\r\n for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkSchemaLoad.sqlQuery)) {\r\n results.push({ sno: row.sno, schema: row.schema });\r\n }\r\n return results;\r\n }\r\n case \"checkMissingChildRows\": {\r\n const results: CheckMissingChildRowsResultRow[] = [];\r\n for await (const row of iModel.createQueryReader(integrityCheckTypeMap.checkMissingChildRows.sqlQuery)) {\r\n results.push({ sno: row.sno, class: row.class, id: row.id, classId: row.class_id, missingRowInTables: row.MissingRowInTables });\r\n }\r\n return results;\r\n }\r\n default:\r\n throw new IModelError(IModelStatus.BadRequest, `Unknown integrity check type: ${check}`);\r\n }\r\n}"]}
|
|
@@ -184,6 +184,18 @@ class TestIModel {
|
|
|
184
184
|
HubMock.shutdown();
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
|
+
const removePropertyRecursive = (obj, prop) => {
|
|
188
|
+
if (obj && typeof obj === "object") {
|
|
189
|
+
Object.keys(obj).forEach((key) => {
|
|
190
|
+
if (key === prop) {
|
|
191
|
+
delete obj[key];
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
removePropertyRecursive(obj[key], prop);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
};
|
|
187
199
|
describe("rebase changes & stashing api", function () {
|
|
188
200
|
let testIModel;
|
|
189
201
|
before(async () => {
|
|
@@ -483,7 +495,7 @@ describe("rebase changes & stashing api", function () {
|
|
|
483
495
|
b1.saveChanges();
|
|
484
496
|
await chai.expect(b1.txns.withIndirectTxnModeAsync(async () => {
|
|
485
497
|
await b1.pushChanges({ description: "test" });
|
|
486
|
-
})).to.be.rejectedWith("Cannot
|
|
498
|
+
})).to.be.rejectedWith("Cannot pull and apply changeset while in an indirect change scope");
|
|
487
499
|
await b1.pushChanges({ description: "test" });
|
|
488
500
|
});
|
|
489
501
|
it("should fail to saveFileProperty/deleteFileProperty in indirect scope", async () => {
|
|
@@ -978,7 +990,7 @@ describe("rebase changes & stashing api", function () {
|
|
|
978
990
|
onRebase: {
|
|
979
991
|
beginCount: 0,
|
|
980
992
|
endCount: 0,
|
|
981
|
-
|
|
993
|
+
beginTxns: [],
|
|
982
994
|
},
|
|
983
995
|
onRebaseTxn: {
|
|
984
996
|
beginTxns: [],
|
|
@@ -987,44 +999,174 @@ describe("rebase changes & stashing api", function () {
|
|
|
987
999
|
rebaseHandler: {
|
|
988
1000
|
shouldReinstate: [],
|
|
989
1001
|
recompute: [],
|
|
990
|
-
}
|
|
1002
|
+
},
|
|
1003
|
+
pullMerge: {
|
|
1004
|
+
beginCount: 0,
|
|
1005
|
+
endCount: 0,
|
|
1006
|
+
beginChangeset: [],
|
|
1007
|
+
endChangeset: [],
|
|
1008
|
+
},
|
|
1009
|
+
applyIncomingChanges: {
|
|
1010
|
+
beginCount: 0,
|
|
1011
|
+
endCount: 0,
|
|
1012
|
+
beginChangesets: [],
|
|
1013
|
+
endChangesets: [],
|
|
1014
|
+
},
|
|
1015
|
+
reverseLocalChanges: {
|
|
1016
|
+
beginCount: 0,
|
|
1017
|
+
endCount: 0,
|
|
1018
|
+
txns: [],
|
|
1019
|
+
},
|
|
1020
|
+
downloadChangesets: {
|
|
1021
|
+
beginCount: 0,
|
|
1022
|
+
endCount: 0,
|
|
1023
|
+
},
|
|
991
1024
|
};
|
|
992
1025
|
const resetEvent = () => {
|
|
993
1026
|
events.onRebase.beginCount = 0;
|
|
994
1027
|
events.onRebase.endCount = 0;
|
|
995
|
-
events.onRebase.
|
|
1028
|
+
events.onRebase.beginTxns = [];
|
|
996
1029
|
events.onRebaseTxn.beginTxns = [];
|
|
997
1030
|
events.onRebaseTxn.endTxns = [];
|
|
998
1031
|
events.rebaseHandler.shouldReinstate = [];
|
|
999
1032
|
events.rebaseHandler.recompute = [];
|
|
1033
|
+
events.pullMerge.beginCount = 0;
|
|
1034
|
+
events.pullMerge.endCount = 0;
|
|
1035
|
+
events.pullMerge.beginChangeset = [];
|
|
1036
|
+
events.pullMerge.endChangeset = [];
|
|
1037
|
+
events.applyIncomingChanges.beginCount = 0;
|
|
1038
|
+
events.applyIncomingChanges.endCount = 0;
|
|
1039
|
+
events.applyIncomingChanges.beginChangesets = [];
|
|
1040
|
+
events.applyIncomingChanges.endChangesets = [];
|
|
1041
|
+
events.reverseLocalChanges.beginCount = 0;
|
|
1042
|
+
events.reverseLocalChanges.endCount = 0;
|
|
1043
|
+
events.reverseLocalChanges.txns = [];
|
|
1044
|
+
events.downloadChangesets.beginCount = 0;
|
|
1045
|
+
events.downloadChangesets.endCount = 0;
|
|
1000
1046
|
};
|
|
1001
|
-
|
|
1047
|
+
// onPullMergeXXXX
|
|
1048
|
+
b2.txns.rebaser.onPullMergeBegin.addListener((changeset) => {
|
|
1049
|
+
events.pullMerge.beginCount++;
|
|
1050
|
+
events.pullMerge.beginChangeset.push(changeset);
|
|
1051
|
+
});
|
|
1052
|
+
b2.txns.rebaser.onPullMergeEnd.addListener((changeset) => {
|
|
1053
|
+
events.pullMerge.endCount++;
|
|
1054
|
+
events.pullMerge.endChangeset.push(changeset);
|
|
1055
|
+
});
|
|
1056
|
+
// onApplyIncomingChangesXXXX
|
|
1057
|
+
b2.txns.rebaser.onApplyIncomingChangesBegin.addListener((changesets) => {
|
|
1058
|
+
events.applyIncomingChanges.beginCount++;
|
|
1059
|
+
events.applyIncomingChanges.beginChangesets.push(...changesets);
|
|
1060
|
+
});
|
|
1061
|
+
b2.txns.rebaser.onApplyIncomingChangesEnd.addListener((changesets) => {
|
|
1062
|
+
events.applyIncomingChanges.endCount++;
|
|
1063
|
+
events.applyIncomingChanges.endChangesets.push(...changesets);
|
|
1064
|
+
});
|
|
1065
|
+
// onReverseLocalChangesXXXX
|
|
1066
|
+
b2.txns.rebaser.onReverseLocalChangesBegin.addListener(() => {
|
|
1067
|
+
events.reverseLocalChanges.beginCount++;
|
|
1068
|
+
});
|
|
1069
|
+
b2.txns.rebaser.onReverseLocalChangesEnd.addListener((txns) => {
|
|
1070
|
+
events.reverseLocalChanges.endCount++;
|
|
1071
|
+
removePropertyRecursive(txns, "timestamp"); // it changes on each run, so remove it for comparison
|
|
1072
|
+
events.reverseLocalChanges.txns.push(...txns);
|
|
1073
|
+
});
|
|
1074
|
+
// onDownloadChangesetsXXXX
|
|
1075
|
+
b2.txns.rebaser.onDownloadChangesetsBegin.addListener(() => {
|
|
1076
|
+
events.downloadChangesets.beginCount++;
|
|
1077
|
+
});
|
|
1078
|
+
b2.txns.rebaser.onDownloadChangesetsEnd.addListener(() => {
|
|
1079
|
+
events.downloadChangesets.endCount++;
|
|
1080
|
+
});
|
|
1081
|
+
// onRebaseXXXX
|
|
1082
|
+
b2.txns.rebaser.onRebaseBegin.addListener((txns) => {
|
|
1002
1083
|
events.onRebase.beginCount++;
|
|
1003
|
-
|
|
1084
|
+
removePropertyRecursive(txns, "timestamp"); // it changes on each run, so remove it for comparison
|
|
1085
|
+
events.onRebase.beginTxns.push(...txns);
|
|
1004
1086
|
});
|
|
1005
|
-
b2.txns.onRebaseEnd.addListener(() => {
|
|
1087
|
+
b2.txns.rebaser.onRebaseEnd.addListener(() => {
|
|
1006
1088
|
events.onRebase.endCount++;
|
|
1007
1089
|
});
|
|
1008
|
-
|
|
1090
|
+
// onRebaseTxnXXXX
|
|
1091
|
+
b2.txns.rebaser.onRebaseTxnBegin.addListener((txn) => {
|
|
1092
|
+
removePropertyRecursive(txn, "timestamp"); // it changes on each run, so remove it for comparison
|
|
1009
1093
|
events.onRebaseTxn.beginTxns.push(txn);
|
|
1010
1094
|
});
|
|
1011
|
-
b2.txns.onRebaseTxnEnd.addListener((txn) => {
|
|
1095
|
+
b2.txns.rebaser.onRebaseTxnEnd.addListener((txn) => {
|
|
1096
|
+
removePropertyRecursive(txn, "timestamp"); // it changes on each run, so remove it for comparison
|
|
1012
1097
|
events.onRebaseTxn.endTxns.push(txn);
|
|
1013
1098
|
});
|
|
1014
1099
|
b2.txns.rebaser.setCustomHandler({
|
|
1015
1100
|
shouldReinstate: (_txn) => {
|
|
1101
|
+
// shouldReinstate
|
|
1102
|
+
removePropertyRecursive(_txn, "timestamp"); // it changes on each run, so remove it for comparison
|
|
1016
1103
|
events.rebaseHandler.shouldReinstate.push(_txn);
|
|
1017
1104
|
return true;
|
|
1018
1105
|
},
|
|
1019
1106
|
recompute: async (_txn) => {
|
|
1107
|
+
// recompute
|
|
1108
|
+
removePropertyRecursive(_txn, "timestamp"); // it changes on each run, so remove it for comparison
|
|
1020
1109
|
events.rebaseHandler.recompute.push(_txn);
|
|
1021
1110
|
},
|
|
1022
1111
|
});
|
|
1023
1112
|
resetEvent();
|
|
1024
1113
|
await b2.pullChanges();
|
|
1114
|
+
// pullMerge events
|
|
1115
|
+
chai.expect(events.pullMerge.beginCount).to.equal(1);
|
|
1116
|
+
chai.expect(events.pullMerge.endCount).to.equal(1);
|
|
1117
|
+
chai.expect((events.pullMerge.beginChangeset[0].index)).to.equal(3);
|
|
1118
|
+
chai.expect((events.pullMerge.endChangeset[0].index)).to.equal(4);
|
|
1119
|
+
// applyIncomingChanges events
|
|
1120
|
+
chai.expect(events.applyIncomingChanges.beginCount).to.equal(1);
|
|
1121
|
+
chai.expect(events.applyIncomingChanges.endCount).to.equal(1);
|
|
1122
|
+
chai.expect(events.applyIncomingChanges.beginChangesets.map((cs) => cs.index)).to.deep.equal([4]);
|
|
1123
|
+
chai.expect(events.applyIncomingChanges.endChangesets.map((cs) => cs.index)).to.deep.equal([4]);
|
|
1124
|
+
// downloadChangesets events
|
|
1125
|
+
chai.expect(events.downloadChangesets.beginCount).to.equal(1);
|
|
1126
|
+
chai.expect(events.downloadChangesets.endCount).to.equal(1);
|
|
1127
|
+
// reverseLocalChanges events
|
|
1128
|
+
chai.expect(events.reverseLocalChanges.beginCount).to.equal(1);
|
|
1129
|
+
chai.expect(events.reverseLocalChanges.endCount).to.equal(1);
|
|
1130
|
+
chai.expect(events.reverseLocalChanges.txns.map((txn) => txn.id)).to.deep.equal(["0x100000000", "0x100000001", "0x100000002"]);
|
|
1131
|
+
// rebase events
|
|
1025
1132
|
chai.expect(events.onRebase.beginCount).to.equal(1);
|
|
1026
1133
|
chai.expect(events.onRebase.endCount).to.equal(1);
|
|
1027
|
-
chai.expect(events.onRebase.
|
|
1134
|
+
chai.expect(events.onRebase.beginTxns).to.deep.equal([
|
|
1135
|
+
{
|
|
1136
|
+
grouped: false,
|
|
1137
|
+
id: "0x100000000",
|
|
1138
|
+
nextId: "0x100000001",
|
|
1139
|
+
props: {
|
|
1140
|
+
description: "first change"
|
|
1141
|
+
},
|
|
1142
|
+
reversed: true,
|
|
1143
|
+
sessionId: 1,
|
|
1144
|
+
type: "Data"
|
|
1145
|
+
},
|
|
1146
|
+
{
|
|
1147
|
+
grouped: false,
|
|
1148
|
+
id: "0x100000001",
|
|
1149
|
+
nextId: "0x100000002",
|
|
1150
|
+
prevId: "0x100000000",
|
|
1151
|
+
props: {
|
|
1152
|
+
description: "second change",
|
|
1153
|
+
},
|
|
1154
|
+
reversed: true,
|
|
1155
|
+
sessionId: 1,
|
|
1156
|
+
type: "Data"
|
|
1157
|
+
},
|
|
1158
|
+
{
|
|
1159
|
+
grouped: false,
|
|
1160
|
+
id: "0x100000002",
|
|
1161
|
+
prevId: "0x100000001",
|
|
1162
|
+
props: {
|
|
1163
|
+
description: "third change"
|
|
1164
|
+
},
|
|
1165
|
+
reversed: true,
|
|
1166
|
+
sessionId: 1,
|
|
1167
|
+
type: "Data"
|
|
1168
|
+
}
|
|
1169
|
+
]);
|
|
1028
1170
|
chai.expect(events.onRebaseTxn.beginTxns.map((txn) => txn.id)).to.deep.equal(["0x100000000", "0x100000001", "0x100000002"]);
|
|
1029
1171
|
chai.expect(events.onRebaseTxn.endTxns.map((txn) => txn.id)).to.deep.equal(["0x100000000", "0x100000001", "0x100000002"]);
|
|
1030
1172
|
chai.expect(events.rebaseHandler.shouldReinstate.map((txn) => txn.id)).to.deep.equal(["0x100000000", "0x100000001", "0x100000002"]);
|
|
@@ -1035,12 +1177,59 @@ describe("rebase changes & stashing api", function () {
|
|
|
1035
1177
|
await b1.pushChanges({ description: "update element 1 direct and 1 indirect" });
|
|
1036
1178
|
await testIModel.insertElement(b2);
|
|
1037
1179
|
await testIModel.insertElement(b2, true);
|
|
1038
|
-
b2.saveChanges("
|
|
1180
|
+
b2.saveChanges("fourth change");
|
|
1039
1181
|
resetEvent();
|
|
1040
1182
|
await b2.pullChanges();
|
|
1041
1183
|
chai.expect(events.onRebase.beginCount).to.equal(1);
|
|
1042
1184
|
chai.expect(events.onRebase.endCount).to.equal(1);
|
|
1043
|
-
chai.expect(events.onRebase.
|
|
1185
|
+
chai.expect(events.onRebase.beginTxns).to.deep.equal([
|
|
1186
|
+
{
|
|
1187
|
+
grouped: false,
|
|
1188
|
+
id: "0x100000000",
|
|
1189
|
+
nextId: "0x100000001",
|
|
1190
|
+
props: {
|
|
1191
|
+
description: "first change"
|
|
1192
|
+
},
|
|
1193
|
+
reversed: true,
|
|
1194
|
+
sessionId: 1,
|
|
1195
|
+
type: "Data"
|
|
1196
|
+
},
|
|
1197
|
+
{
|
|
1198
|
+
grouped: false,
|
|
1199
|
+
id: "0x100000001",
|
|
1200
|
+
nextId: "0x100000002",
|
|
1201
|
+
prevId: "0x100000000",
|
|
1202
|
+
props: {
|
|
1203
|
+
description: "second change"
|
|
1204
|
+
},
|
|
1205
|
+
reversed: true,
|
|
1206
|
+
sessionId: 1,
|
|
1207
|
+
type: "Data"
|
|
1208
|
+
},
|
|
1209
|
+
{
|
|
1210
|
+
grouped: false,
|
|
1211
|
+
id: "0x100000002",
|
|
1212
|
+
nextId: "0x100000003",
|
|
1213
|
+
prevId: "0x100000001",
|
|
1214
|
+
props: {
|
|
1215
|
+
description: "third change"
|
|
1216
|
+
},
|
|
1217
|
+
reversed: true,
|
|
1218
|
+
sessionId: 1,
|
|
1219
|
+
type: "Data"
|
|
1220
|
+
},
|
|
1221
|
+
{
|
|
1222
|
+
grouped: false,
|
|
1223
|
+
id: "0x100000003",
|
|
1224
|
+
prevId: "0x100000002",
|
|
1225
|
+
props: {
|
|
1226
|
+
description: "fourth change"
|
|
1227
|
+
},
|
|
1228
|
+
reversed: true,
|
|
1229
|
+
sessionId: 1,
|
|
1230
|
+
type: "Data"
|
|
1231
|
+
}
|
|
1232
|
+
]);
|
|
1044
1233
|
chai.expect(events.onRebaseTxn.beginTxns.map((txn) => txn.id)).to.deep.equal(["0x100000000", "0x100000001", "0x100000002", "0x100000003"]);
|
|
1045
1234
|
chai.expect(events.onRebaseTxn.endTxns.map((txn) => txn.id)).to.deep.equal(["0x100000000", "0x100000001", "0x100000002", "0x100000003"]);
|
|
1046
1235
|
chai.expect(events.rebaseHandler.shouldReinstate.map((txn) => txn.id)).to.deep.equal(["0x100000000", "0x100000001", "0x100000002", "0x100000003"]);
|