@itwin/core-backend 5.2.0-dev.8 → 5.3.0-dev.2
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 +36 -1
- package/lib/cjs/BackendHubAccess.d.ts +2 -0
- package/lib/cjs/BackendHubAccess.d.ts.map +1 -1
- package/lib/cjs/BackendHubAccess.js.map +1 -1
- package/lib/cjs/BackendLoggerCategory.d.ts +6 -0
- package/lib/cjs/BackendLoggerCategory.d.ts.map +1 -1
- package/lib/cjs/BackendLoggerCategory.js +6 -0
- package/lib/cjs/BackendLoggerCategory.js.map +1 -1
- package/lib/cjs/BriefcaseManager.d.ts +57 -3
- package/lib/cjs/BriefcaseManager.d.ts.map +1 -1
- package/lib/cjs/BriefcaseManager.js +151 -42
- package/lib/cjs/BriefcaseManager.js.map +1 -1
- package/lib/cjs/CloudSqlite.d.ts +4 -0
- package/lib/cjs/CloudSqlite.d.ts.map +1 -1
- package/lib/cjs/CloudSqlite.js.map +1 -1
- package/lib/cjs/ECDb.d.ts +8 -0
- package/lib/cjs/ECDb.d.ts.map +1 -1
- package/lib/cjs/ECDb.js +22 -0
- package/lib/cjs/ECDb.js.map +1 -1
- package/lib/cjs/GeographicCRSServices.d.ts.map +1 -1
- package/lib/cjs/GeographicCRSServices.js +2 -0
- package/lib/cjs/GeographicCRSServices.js.map +1 -1
- package/lib/cjs/IModelDb.d.ts +54 -3
- package/lib/cjs/IModelDb.d.ts.map +1 -1
- package/lib/cjs/IModelDb.js +87 -9
- package/lib/cjs/IModelDb.js.map +1 -1
- package/lib/cjs/IModelHost.d.ts +11 -1
- package/lib/cjs/IModelHost.d.ts.map +1 -1
- package/lib/cjs/IModelHost.js +5 -0
- package/lib/cjs/IModelHost.js.map +1 -1
- package/lib/cjs/IModelIncrementalSchemaLocater.d.ts +1 -5
- package/lib/cjs/IModelIncrementalSchemaLocater.d.ts.map +1 -1
- package/lib/cjs/IModelIncrementalSchemaLocater.js +0 -6
- package/lib/cjs/IModelIncrementalSchemaLocater.js.map +1 -1
- package/lib/cjs/SqliteChangesetReader.d.ts +8 -0
- package/lib/cjs/SqliteChangesetReader.d.ts.map +1 -1
- package/lib/cjs/SqliteChangesetReader.js +11 -0
- package/lib/cjs/SqliteChangesetReader.js.map +1 -1
- package/lib/cjs/StashManager.d.ts +175 -0
- package/lib/cjs/StashManager.d.ts.map +1 -0
- package/lib/cjs/StashManager.js +306 -0
- package/lib/cjs/StashManager.js.map +1 -0
- package/lib/cjs/TxnManager.d.ts +226 -15
- package/lib/cjs/TxnManager.d.ts.map +1 -1
- package/lib/cjs/TxnManager.js +249 -23
- package/lib/cjs/TxnManager.js.map +1 -1
- package/lib/cjs/annotations/ElementDrivesTextAnnotation.d.ts +10 -1
- package/lib/cjs/annotations/ElementDrivesTextAnnotation.d.ts.map +1 -1
- package/lib/cjs/annotations/ElementDrivesTextAnnotation.js +15 -6
- package/lib/cjs/annotations/ElementDrivesTextAnnotation.js.map +1 -1
- package/lib/cjs/annotations/LeaderGeometry.d.ts +3 -2
- package/lib/cjs/annotations/LeaderGeometry.d.ts.map +1 -1
- package/lib/cjs/annotations/LeaderGeometry.js +5 -4
- package/lib/cjs/annotations/LeaderGeometry.js.map +1 -1
- package/lib/cjs/annotations/TextAnnotationElement.d.ts +52 -24
- package/lib/cjs/annotations/TextAnnotationElement.d.ts.map +1 -1
- package/lib/cjs/annotations/TextAnnotationElement.js +49 -59
- package/lib/cjs/annotations/TextAnnotationElement.js.map +1 -1
- package/lib/cjs/annotations/TextAnnotationGeometry.d.ts +2 -0
- package/lib/cjs/annotations/TextAnnotationGeometry.d.ts.map +1 -1
- package/lib/cjs/annotations/TextAnnotationGeometry.js +26 -19
- package/lib/cjs/annotations/TextAnnotationGeometry.js.map +1 -1
- package/lib/cjs/annotations/TextBlockGeometry.d.ts.map +1 -1
- package/lib/cjs/annotations/TextBlockGeometry.js +8 -0
- package/lib/cjs/annotations/TextBlockGeometry.js.map +1 -1
- package/lib/cjs/annotations/TextBlockLayout.d.ts +49 -36
- package/lib/cjs/annotations/TextBlockLayout.d.ts.map +1 -1
- package/lib/cjs/annotations/TextBlockLayout.js +204 -135
- package/lib/cjs/annotations/TextBlockLayout.js.map +1 -1
- package/lib/cjs/internal/ChannelAdmin.js +1 -1
- package/lib/cjs/internal/ChannelAdmin.js.map +1 -1
- package/lib/cjs/internal/Symbols.d.ts +1 -0
- package/lib/cjs/internal/Symbols.d.ts.map +1 -1
- package/lib/cjs/internal/Symbols.js +2 -1
- package/lib/cjs/internal/Symbols.js.map +1 -1
- package/lib/cjs/internal/annotations/fields.d.ts +2 -12
- package/lib/cjs/internal/annotations/fields.d.ts.map +1 -1
- package/lib/cjs/internal/annotations/fields.js +49 -45
- package/lib/cjs/internal/annotations/fields.js.map +1 -1
- package/lib/cjs/workspace/Workspace.d.ts +1 -1
- package/lib/cjs/workspace/Workspace.js.map +1 -1
- package/lib/esm/BackendHubAccess.d.ts +2 -0
- package/lib/esm/BackendHubAccess.d.ts.map +1 -1
- package/lib/esm/BackendHubAccess.js.map +1 -1
- package/lib/esm/BackendLoggerCategory.d.ts +6 -0
- package/lib/esm/BackendLoggerCategory.d.ts.map +1 -1
- package/lib/esm/BackendLoggerCategory.js +6 -0
- package/lib/esm/BackendLoggerCategory.js.map +1 -1
- package/lib/esm/BriefcaseManager.d.ts +57 -3
- package/lib/esm/BriefcaseManager.d.ts.map +1 -1
- package/lib/esm/BriefcaseManager.js +152 -43
- package/lib/esm/BriefcaseManager.js.map +1 -1
- package/lib/esm/CloudSqlite.d.ts +4 -0
- package/lib/esm/CloudSqlite.d.ts.map +1 -1
- package/lib/esm/CloudSqlite.js.map +1 -1
- package/lib/esm/ECDb.d.ts +8 -0
- package/lib/esm/ECDb.d.ts.map +1 -1
- package/lib/esm/ECDb.js +22 -0
- package/lib/esm/ECDb.js.map +1 -1
- package/lib/esm/GeographicCRSServices.d.ts.map +1 -1
- package/lib/esm/GeographicCRSServices.js +2 -0
- package/lib/esm/GeographicCRSServices.js.map +1 -1
- package/lib/esm/IModelDb.d.ts +54 -3
- package/lib/esm/IModelDb.d.ts.map +1 -1
- package/lib/esm/IModelDb.js +88 -10
- package/lib/esm/IModelDb.js.map +1 -1
- package/lib/esm/IModelHost.d.ts +11 -1
- package/lib/esm/IModelHost.d.ts.map +1 -1
- package/lib/esm/IModelHost.js +5 -0
- package/lib/esm/IModelHost.js.map +1 -1
- package/lib/esm/IModelIncrementalSchemaLocater.d.ts +1 -5
- package/lib/esm/IModelIncrementalSchemaLocater.d.ts.map +1 -1
- package/lib/esm/IModelIncrementalSchemaLocater.js +0 -6
- package/lib/esm/IModelIncrementalSchemaLocater.js.map +1 -1
- package/lib/esm/SqliteChangesetReader.d.ts +8 -0
- package/lib/esm/SqliteChangesetReader.d.ts.map +1 -1
- package/lib/esm/SqliteChangesetReader.js +11 -0
- package/lib/esm/SqliteChangesetReader.js.map +1 -1
- package/lib/esm/StashManager.d.ts +175 -0
- package/lib/esm/StashManager.d.ts.map +1 -0
- package/lib/esm/StashManager.js +301 -0
- package/lib/esm/StashManager.js.map +1 -0
- package/lib/esm/TxnManager.d.ts +226 -15
- package/lib/esm/TxnManager.d.ts.map +1 -1
- package/lib/esm/TxnManager.js +247 -21
- package/lib/esm/TxnManager.js.map +1 -1
- package/lib/esm/annotations/ElementDrivesTextAnnotation.d.ts +10 -1
- package/lib/esm/annotations/ElementDrivesTextAnnotation.d.ts.map +1 -1
- package/lib/esm/annotations/ElementDrivesTextAnnotation.js +13 -5
- package/lib/esm/annotations/ElementDrivesTextAnnotation.js.map +1 -1
- package/lib/esm/annotations/LeaderGeometry.d.ts +3 -2
- package/lib/esm/annotations/LeaderGeometry.d.ts.map +1 -1
- package/lib/esm/annotations/LeaderGeometry.js +5 -4
- package/lib/esm/annotations/LeaderGeometry.js.map +1 -1
- package/lib/esm/annotations/TextAnnotationElement.d.ts +52 -24
- package/lib/esm/annotations/TextAnnotationElement.d.ts.map +1 -1
- package/lib/esm/annotations/TextAnnotationElement.js +51 -61
- package/lib/esm/annotations/TextAnnotationElement.js.map +1 -1
- package/lib/esm/annotations/TextAnnotationGeometry.d.ts +2 -0
- package/lib/esm/annotations/TextAnnotationGeometry.d.ts.map +1 -1
- package/lib/esm/annotations/TextAnnotationGeometry.js +26 -19
- package/lib/esm/annotations/TextAnnotationGeometry.js.map +1 -1
- package/lib/esm/annotations/TextBlockGeometry.d.ts.map +1 -1
- package/lib/esm/annotations/TextBlockGeometry.js +8 -0
- package/lib/esm/annotations/TextBlockGeometry.js.map +1 -1
- package/lib/esm/annotations/TextBlockLayout.d.ts +49 -36
- package/lib/esm/annotations/TextBlockLayout.d.ts.map +1 -1
- package/lib/esm/annotations/TextBlockLayout.js +205 -136
- package/lib/esm/annotations/TextBlockLayout.js.map +1 -1
- package/lib/esm/internal/ChannelAdmin.js +1 -1
- package/lib/esm/internal/ChannelAdmin.js.map +1 -1
- package/lib/esm/internal/Symbols.d.ts +1 -0
- package/lib/esm/internal/Symbols.d.ts.map +1 -1
- package/lib/esm/internal/Symbols.js +1 -0
- package/lib/esm/internal/Symbols.js.map +1 -1
- package/lib/esm/internal/annotations/fields.d.ts +2 -12
- package/lib/esm/internal/annotations/fields.d.ts.map +1 -1
- package/lib/esm/internal/annotations/fields.js +51 -47
- package/lib/esm/internal/annotations/fields.js.map +1 -1
- package/lib/esm/test/AnnotationTestUtils.d.ts +5 -1
- package/lib/esm/test/AnnotationTestUtils.d.ts.map +1 -1
- package/lib/esm/test/AnnotationTestUtils.js +6 -1
- package/lib/esm/test/AnnotationTestUtils.js.map +1 -1
- package/lib/esm/test/annotations/Fields.test.js +163 -46
- package/lib/esm/test/annotations/Fields.test.js.map +1 -1
- package/lib/esm/test/annotations/LeaderGeometry.test.js +12 -10
- package/lib/esm/test/annotations/LeaderGeometry.test.js.map +1 -1
- package/lib/esm/test/annotations/TextAnnotation.test.js +299 -43
- package/lib/esm/test/annotations/TextAnnotation.test.js.map +1 -1
- package/lib/esm/test/annotations/TextBlock.test.js +453 -86
- package/lib/esm/test/annotations/TextBlock.test.js.map +1 -1
- package/lib/esm/test/assets/IncrementalSchemaLocater/configs/simple.config.d.ts +46 -0
- package/lib/esm/test/assets/IncrementalSchemaLocater/configs/simple.config.d.ts.map +1 -1
- package/lib/esm/test/assets/IncrementalSchemaLocater/configs/simple.config.js +20 -2
- package/lib/esm/test/assets/IncrementalSchemaLocater/configs/simple.config.js.map +1 -1
- package/lib/esm/test/ecdb/ECDb.test.js +71 -1
- package/lib/esm/test/ecdb/ECDb.test.js.map +1 -1
- package/lib/esm/test/hubaccess/Rebase.test.d.ts +2 -0
- package/lib/esm/test/hubaccess/Rebase.test.d.ts.map +1 -0
- package/lib/esm/test/hubaccess/Rebase.test.js +640 -0
- package/lib/esm/test/hubaccess/Rebase.test.js.map +1 -0
- package/lib/esm/test/incrementalSchemaLocater/ECSqlQueries.test.js +20 -20
- package/lib/esm/test/incrementalSchemaLocater/ECSqlQueries.test.js.map +1 -1
- package/lib/esm/test/incrementalSchemaLocater/IncrementalLoading.test.js +3 -3
- package/lib/esm/test/incrementalSchemaLocater/IncrementalLoading.test.js.map +1 -1
- package/lib/esm/test/incrementalSchemaLocater/utils/TestSqlSchemaLocater.d.ts +16 -1
- package/lib/esm/test/incrementalSchemaLocater/utils/TestSqlSchemaLocater.d.ts.map +1 -1
- package/lib/esm/test/incrementalSchemaLocater/utils/TestSqlSchemaLocater.js +47 -0
- package/lib/esm/test/incrementalSchemaLocater/utils/TestSqlSchemaLocater.js.map +1 -1
- package/lib/esm/test/standalone/ChangeMerge.test.js +15 -19
- package/lib/esm/test/standalone/ChangeMerge.test.js.map +1 -1
- package/lib/esm/test/standalone/ChangesetReader.test.js +131 -1
- package/lib/esm/test/standalone/ChangesetReader.test.js.map +1 -1
- package/lib/esm/test/standalone/MergeConflict.test.js +3 -3
- package/lib/esm/test/standalone/MergeConflict.test.js.map +1 -1
- package/lib/esm/workspace/Workspace.d.ts +1 -1
- package/lib/esm/workspace/Workspace.js.map +1 -1
- package/package.json +13 -13
package/lib/esm/TxnManager.js
CHANGED
|
@@ -12,6 +12,7 @@ import { BackendLoggerCategory } from "./BackendLoggerCategory";
|
|
|
12
12
|
import { IpcHost } from "./IpcHost";
|
|
13
13
|
import { _nativeDb } from "./internal/Symbols";
|
|
14
14
|
import { RebaseChangesetConflictArgs } from "./internal/ChangesetConflictArgs";
|
|
15
|
+
import { BriefcaseManager } from "./BriefcaseManager";
|
|
15
16
|
/** Strictly for tests. @internal */
|
|
16
17
|
export function setMaxEntitiesPerEvent(max) {
|
|
17
18
|
const prevMax = ChangedEntitiesProc.maxPerEvent;
|
|
@@ -193,21 +194,162 @@ class ChangedEntitiesProc {
|
|
|
193
194
|
}
|
|
194
195
|
}
|
|
195
196
|
/**
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
|
|
199
|
-
|
|
197
|
+
* Manages the process of merging and rebasing local changes (transactions) in a [[BriefcaseDb]] or [[StandaloneDb]].
|
|
198
|
+
*
|
|
199
|
+
* The `RebaseManager` coordinates the rebase of local transactions when pulling and merging changes from other sources,
|
|
200
|
+
* such as remote repositories or other users. It provides mechanisms to handle transaction conflicts, register custom conflict
|
|
201
|
+
* handlers, and manage the rebase workflow. This includes resuming rebases, invoking user-defined handlers for conflict resolution,
|
|
202
|
+
* and tracking the current merge/rebase state.
|
|
203
|
+
*
|
|
204
|
+
* Key responsibilities:
|
|
205
|
+
* - Orchestrates the rebase of local transactions after a pull/merge operation.
|
|
206
|
+
* - Allows registration and removal of custom conflict handlers to resolve changeset conflicts during rebase.
|
|
207
|
+
* - Provides methods to check the current merge/rebase state.
|
|
208
|
+
* - Raises events before and after each transaction is rebased.
|
|
209
|
+
* - Ensures changes are saved or aborted appropriately based on the outcome of the rebase process.
|
|
210
|
+
*
|
|
211
|
+
* @alpha
|
|
212
|
+
*/
|
|
213
|
+
export class RebaseManager {
|
|
200
214
|
_iModel;
|
|
201
215
|
_conflictHandlers;
|
|
216
|
+
_customHandler;
|
|
202
217
|
constructor(_iModel) {
|
|
203
218
|
this._iModel = _iModel;
|
|
204
219
|
}
|
|
205
|
-
|
|
206
|
-
|
|
220
|
+
/**
|
|
221
|
+
* Resumes the rebase process for the current iModel, applying any pending local changes
|
|
222
|
+
* on top of the latest pulled changes from the remote source.
|
|
223
|
+
*
|
|
224
|
+
* This method performs the following steps:
|
|
225
|
+
* 1. Begins the rebase process using the native database.
|
|
226
|
+
* 2. Iterates through each transaction that needs to be rebased:
|
|
227
|
+
* - Retrieves transaction properties.
|
|
228
|
+
* - Raises events before and after rebasing each transaction.
|
|
229
|
+
* - Optionally reinstates local changes based on the rebase handler.
|
|
230
|
+
* - Optionally recomputes transaction data using the rebase handler.
|
|
231
|
+
* - Updates the transaction in the native database.
|
|
232
|
+
* 3. Ends the rebase process and saves changes if the database is not read-only.
|
|
233
|
+
* 4. Drops any restore point associated with the pull-merge operation.
|
|
234
|
+
*
|
|
235
|
+
* If an error occurs during the process, the rebase is aborted and the error is rethrown.
|
|
236
|
+
*
|
|
237
|
+
* @throws {Error} If a transaction cannot be found or if any step in the rebase process fails.
|
|
238
|
+
*/
|
|
239
|
+
async resume() {
|
|
240
|
+
const nativeDb = this._iModel[_nativeDb];
|
|
241
|
+
const txns = this._iModel.txns;
|
|
242
|
+
try {
|
|
243
|
+
nativeDb.pullMergeRebaseBegin();
|
|
244
|
+
let txnId = nativeDb.pullMergeRebaseNext();
|
|
245
|
+
while (txnId) {
|
|
246
|
+
const txnProps = txns.getTxnProps(txnId);
|
|
247
|
+
if (!txnProps) {
|
|
248
|
+
throw new Error(`Transaction ${txnId} not found`);
|
|
249
|
+
}
|
|
250
|
+
txns.onRebaseTxnBegin.raiseEvent(txnProps);
|
|
251
|
+
Logger.logInfo(BackendLoggerCategory.IModelDb, `Rebasing local changes for transaction ${txnId}`);
|
|
252
|
+
const shouldReinstate = this._customHandler?.shouldReinstate(txnProps) ?? true;
|
|
253
|
+
if (shouldReinstate) {
|
|
254
|
+
nativeDb.pullMergeRebaseReinstateTxn();
|
|
255
|
+
Logger.logInfo(BackendLoggerCategory.IModelDb, `Reinstated local changes for transaction ${txnId}`);
|
|
256
|
+
}
|
|
257
|
+
if (this._customHandler) {
|
|
258
|
+
await this._customHandler.recompute(txnProps);
|
|
259
|
+
}
|
|
260
|
+
nativeDb.pullMergeRebaseUpdateTxn();
|
|
261
|
+
txns.onRebaseTxnEnd.raiseEvent(txnProps);
|
|
262
|
+
txnId = nativeDb.pullMergeRebaseNext();
|
|
263
|
+
}
|
|
264
|
+
nativeDb.pullMergeRebaseEnd();
|
|
265
|
+
if (!nativeDb.isReadonly) {
|
|
266
|
+
nativeDb.saveChanges("Merge.");
|
|
267
|
+
}
|
|
268
|
+
if (BriefcaseManager.containsRestorePoint(this._iModel, BriefcaseManager.PULL_MERGE_RESTORE_POINT_NAME)) {
|
|
269
|
+
BriefcaseManager.dropRestorePoint(this._iModel, BriefcaseManager.PULL_MERGE_RESTORE_POINT_NAME);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
catch (err) {
|
|
273
|
+
nativeDb.pullMergeRebaseAbortTxn();
|
|
274
|
+
throw err;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Determines whether the current transaction can be aborted.
|
|
279
|
+
*
|
|
280
|
+
* This method checks if a transaction is currently in progress and if a specific restore point,
|
|
281
|
+
* identified by `BriefcaseManager.PULL_MERGE_RESTORE_POINT_NAME`, exists in the briefcase manager.
|
|
282
|
+
*
|
|
283
|
+
* @returns {boolean} Returns `true` if a transaction is in progress and the required restore point exists; otherwise, returns `false`.
|
|
284
|
+
*/
|
|
285
|
+
canAbort() {
|
|
286
|
+
return this.inProgress() && BriefcaseManager.containsRestorePoint(this._iModel, BriefcaseManager.PULL_MERGE_RESTORE_POINT_NAME);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Aborts the current transaction by restoring the iModel to a predefined restore point.
|
|
290
|
+
*
|
|
291
|
+
* If a restore point is available (as determined by `canAbort()`), this method restores the iModel
|
|
292
|
+
* to the state saved at the restore point named by `BriefcaseManager.PULL_MERGE_RESTORE_POINT_NAME`.
|
|
293
|
+
* If no restore point is available, an error is thrown.
|
|
294
|
+
*
|
|
295
|
+
* @returns A promise that resolves when the restore operation is complete.
|
|
296
|
+
* @throws {Error} If there is no restore point to abort to.
|
|
297
|
+
*/
|
|
298
|
+
async abort() {
|
|
299
|
+
if (this.canAbort()) {
|
|
300
|
+
return BriefcaseManager.restorePoint(this._iModel, BriefcaseManager.PULL_MERGE_RESTORE_POINT_NAME);
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
throw new Error("No restore point to abort to");
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Sets the handler to be invoked for rebase operations.
|
|
308
|
+
*
|
|
309
|
+
* @param handler - The {@link RebaseHandler} to handle rebase events.
|
|
310
|
+
*/
|
|
311
|
+
setCustomHandler(handler) {
|
|
312
|
+
if (this._customHandler) {
|
|
313
|
+
Logger.logWarning(BackendLoggerCategory.IModelDb, "Rebase handler already set");
|
|
314
|
+
}
|
|
315
|
+
this._customHandler = handler;
|
|
207
316
|
}
|
|
317
|
+
/**
|
|
318
|
+
* Determines whether a transaction is currently in progress.
|
|
319
|
+
*
|
|
320
|
+
* @returns {boolean} Returns `true` if there is an active transaction stage, otherwise `false`.
|
|
321
|
+
*/
|
|
208
322
|
inProgress() {
|
|
209
|
-
return this._iModel[_nativeDb].
|
|
323
|
+
return this._iModel[_nativeDb].pullMergeGetStage() !== "None";
|
|
210
324
|
}
|
|
325
|
+
/**
|
|
326
|
+
* Indicates whether the current transaction manager is in the "Rebasing" stage.
|
|
327
|
+
*
|
|
328
|
+
* This property checks the internal native database's merge stage to determine if a rebase operation is in progress.
|
|
329
|
+
*
|
|
330
|
+
* @returns `true` if the transaction manager is currently rebasing; otherwise, `false`.
|
|
331
|
+
*/
|
|
332
|
+
get isRebasing() {
|
|
333
|
+
return this._iModel[_nativeDb].pullMergeGetStage() === "Rebasing";
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Indicates whether the current iModel is in the process of merging changes from a pull operation.
|
|
337
|
+
*
|
|
338
|
+
* @returns `true` if the iModel is currently merging changes; otherwise, `false`.
|
|
339
|
+
*/
|
|
340
|
+
get isMerging() {
|
|
341
|
+
return this._iModel[_nativeDb].pullMergeGetStage() === "Merging";
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Attempts to resolve a changeset conflict by invoking registered conflict handlers in sequence.
|
|
345
|
+
*
|
|
346
|
+
* Iterates through the linked list of conflict handlers, passing the provided conflict arguments to each handler.
|
|
347
|
+
* If a handler returns a defined resolution, logs the resolution and returns it immediately.
|
|
348
|
+
* If no handler resolves the conflict, returns `undefined`.
|
|
349
|
+
*
|
|
350
|
+
* @param args - The arguments describing the changeset conflict to resolve.
|
|
351
|
+
* @returns The conflict resolution provided by a handler, or `undefined` if no handler resolves the conflict.
|
|
352
|
+
*/
|
|
211
353
|
onConflict(args) {
|
|
212
354
|
let curr = this._conflictHandlers;
|
|
213
355
|
while (curr) {
|
|
@@ -220,6 +362,18 @@ export class ChangeMergeManager {
|
|
|
220
362
|
}
|
|
221
363
|
return undefined;
|
|
222
364
|
}
|
|
365
|
+
/**
|
|
366
|
+
* Registers a new conflict handler for rebase changeset conflicts.
|
|
367
|
+
*
|
|
368
|
+
* @param args - An object containing:
|
|
369
|
+
* - `id`: A unique identifier for the conflict handler.
|
|
370
|
+
* - `handler`: A function that handles rebase changeset conflicts and returns a `DbConflictResolution` or `undefined`.
|
|
371
|
+
* @throws IModelError if a conflict handler with the same `id` already exists.
|
|
372
|
+
*
|
|
373
|
+
* @remarks
|
|
374
|
+
* Conflict handlers are used during changeset rebase operations to resolve conflicts.
|
|
375
|
+
* Each handler must have a unique `id`. Attempting to register a handler with a duplicate `id` will result in an error.
|
|
376
|
+
*/
|
|
223
377
|
addConflictHandler(args) {
|
|
224
378
|
const idExists = (id) => {
|
|
225
379
|
let curr = this._conflictHandlers;
|
|
@@ -234,6 +388,14 @@ export class ChangeMergeManager {
|
|
|
234
388
|
throw new IModelError(DbResult.BE_SQLITE_ERROR, `Conflict handler with id ${args.id} already exists`);
|
|
235
389
|
this._conflictHandlers = { ...args, next: this._conflictHandlers };
|
|
236
390
|
}
|
|
391
|
+
/**
|
|
392
|
+
* Removes a conflict handler from the internal linked list by its identifier.
|
|
393
|
+
*
|
|
394
|
+
* @param id - The unique identifier of the conflict handler to remove.
|
|
395
|
+
*
|
|
396
|
+
* If the handler with the specified `id` exists in the list, it will be removed.
|
|
397
|
+
* If no handler with the given `id` is found, the method does nothing.
|
|
398
|
+
*/
|
|
237
399
|
removeConflictHandler(id) {
|
|
238
400
|
if (!this._conflictHandlers)
|
|
239
401
|
return;
|
|
@@ -265,11 +427,11 @@ export class TxnManager {
|
|
|
265
427
|
return this._isDisposed;
|
|
266
428
|
}
|
|
267
429
|
/** @internal */
|
|
268
|
-
|
|
430
|
+
rebaser;
|
|
269
431
|
/** @internal */
|
|
270
432
|
constructor(_iModel) {
|
|
271
433
|
this._iModel = _iModel;
|
|
272
|
-
this.
|
|
434
|
+
this.rebaser = new RebaseManager(_iModel);
|
|
273
435
|
_iModel.onBeforeClose.addOnce(() => {
|
|
274
436
|
this._isDisposed = true;
|
|
275
437
|
});
|
|
@@ -367,12 +529,6 @@ export class TxnManager {
|
|
|
367
529
|
this.onAfterUndoRedo.raiseEvent(isUndo);
|
|
368
530
|
IpcHost.notifyTxns(this._iModel, "notifyAfterUndoRedo", isUndo);
|
|
369
531
|
}
|
|
370
|
-
_onRebaseTxnBegin(txn) {
|
|
371
|
-
this.onRebaseTxnBegin.raiseEvent(txn);
|
|
372
|
-
}
|
|
373
|
-
_onRebaseTxnEnd(txn) {
|
|
374
|
-
this.onRebaseTxnEnd.raiseEvent(txn);
|
|
375
|
-
}
|
|
376
532
|
_onRebaseLocalTxnConflict(internalArg) {
|
|
377
533
|
const args = new RebaseChangesetConflictArgs(internalArg, this._iModel);
|
|
378
534
|
const getChangeMetaData = () => {
|
|
@@ -404,7 +560,7 @@ export class TxnManager {
|
|
|
404
560
|
}
|
|
405
561
|
}
|
|
406
562
|
try {
|
|
407
|
-
const resolution = this.
|
|
563
|
+
const resolution = this.rebaser.onConflict(args);
|
|
408
564
|
if (resolution !== undefined)
|
|
409
565
|
return resolution;
|
|
410
566
|
}
|
|
@@ -435,11 +591,43 @@ export class TxnManager {
|
|
|
435
591
|
return DbConflictResolution.Skip;
|
|
436
592
|
}
|
|
437
593
|
if (args.cause === "Constraint") {
|
|
438
|
-
Logger.logInfo(BackendLoggerCategory.IModelDb, "Constraint
|
|
594
|
+
Logger.logInfo(BackendLoggerCategory.IModelDb, "Constraint violation detected. Generally caused by db constraints like UNIQUE index. Skipping local change.", getChangeMetaData());
|
|
439
595
|
return DbConflictResolution.Skip;
|
|
440
596
|
}
|
|
441
597
|
return DbConflictResolution.Replace;
|
|
442
598
|
}
|
|
599
|
+
/**
|
|
600
|
+
* @alpha
|
|
601
|
+
* Retrieves the txn properties for a given txn ID.
|
|
602
|
+
*
|
|
603
|
+
* @param id - The unique identifier of the transaction.
|
|
604
|
+
* @returns The properties of the transaction if found; otherwise, `undefined`.
|
|
605
|
+
*/
|
|
606
|
+
getTxnProps(id) {
|
|
607
|
+
return this._iModel[_nativeDb].getTxnProps(id);
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* @alpha
|
|
611
|
+
* Iterates over all transactions in the sequence, yielding each transaction's properties.
|
|
612
|
+
*
|
|
613
|
+
* @yields {TxnProps} The properties of each transaction in the sequence.
|
|
614
|
+
*/
|
|
615
|
+
*queryTxns() {
|
|
616
|
+
let txn = this.getTxnProps(this.queryFirstTxnId());
|
|
617
|
+
while (txn) {
|
|
618
|
+
yield txn;
|
|
619
|
+
txn = txn.nextId ? this.getTxnProps(txn.nextId) : undefined;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* @alpha
|
|
624
|
+
* Retrieves the properties of the last saved txn via `IModelDb.saveChanges()`, if available.
|
|
625
|
+
*
|
|
626
|
+
* @returns The properties of the last saved txn, or `undefined` if none exist.
|
|
627
|
+
*/
|
|
628
|
+
getLastSavedTxnProps() {
|
|
629
|
+
return this.getTxnProps(this.queryPreviousTxnId(this.getCurrentTxnId()));
|
|
630
|
+
}
|
|
443
631
|
/** Dependency handlers may call method this to report a validation error.
|
|
444
632
|
* @param error The error. If error.fatal === true, the transaction will cancel rather than commit.
|
|
445
633
|
*/
|
|
@@ -489,12 +677,18 @@ export class TxnManager {
|
|
|
489
677
|
* @see [[onReplayExternalTxns]] for the event raised before the changes are applied.
|
|
490
678
|
*/
|
|
491
679
|
onReplayedExternalTxns = new BeEvent();
|
|
492
|
-
/**
|
|
680
|
+
/**
|
|
681
|
+
* @alpha
|
|
682
|
+
* Event raised when a rebase transaction begins.
|
|
683
|
+
*/
|
|
493
684
|
onRebaseTxnBegin = new BeEvent();
|
|
494
|
-
/**
|
|
685
|
+
/**
|
|
686
|
+
* @alpha
|
|
687
|
+
* Event raised when a rebase transaction ends.
|
|
688
|
+
*/
|
|
495
689
|
onRebaseTxnEnd = new BeEvent();
|
|
496
690
|
/**
|
|
497
|
-
* if handler is set and it does not return
|
|
691
|
+
* if handler is set and it does not return undefined then default handler will not be called
|
|
498
692
|
* @internal
|
|
499
693
|
* */
|
|
500
694
|
appCustomConflictHandler;
|
|
@@ -509,7 +703,7 @@ export class TxnManager {
|
|
|
509
703
|
this._nativeDb.restartTxnSession();
|
|
510
704
|
}
|
|
511
705
|
/** Determine whether current txn is propagating indirect changes or not. */
|
|
512
|
-
get isIndirectChanges() { return this.
|
|
706
|
+
get isIndirectChanges() { return this.getMode() === "indirect"; }
|
|
513
707
|
/** Determine if there are currently any reversible (undoable) changes from this editing session. */
|
|
514
708
|
get isUndoPossible() { return this._nativeDb.isUndoPossible(); }
|
|
515
709
|
/** Determine if there are currently any reinstatable (redoable) changes */
|
|
@@ -574,6 +768,11 @@ export class TxnManager {
|
|
|
574
768
|
queryPreviousTxnId(txnId) { return this._nativeDb.queryPreviousTxnId(txnId); }
|
|
575
769
|
/** Get the Id of the current (tip) transaction. */
|
|
576
770
|
getCurrentTxnId() { return this._nativeDb.getCurrentTxnId(); }
|
|
771
|
+
/**
|
|
772
|
+
* @alpha
|
|
773
|
+
* Get the Id of the current session.
|
|
774
|
+
*/
|
|
775
|
+
getCurrentSessionId() { return this._nativeDb.currentTxnSessionId(); }
|
|
577
776
|
/** Get the description that was supplied when the specified transaction was saved. */
|
|
578
777
|
getTxnDescription(txnId) { return this._nativeDb.getTxnDescription(txnId); }
|
|
579
778
|
/** Test if a TxnId is valid */
|
|
@@ -587,6 +786,11 @@ export class TxnManager {
|
|
|
587
786
|
* @see [[IModelDb.saveChanges]]
|
|
588
787
|
*/
|
|
589
788
|
get hasUnsavedChanges() { return this._nativeDb.hasUnsavedChanges(); }
|
|
789
|
+
/**
|
|
790
|
+
* @alpha
|
|
791
|
+
* Query if there are any pending schema changes in this IModelDb.
|
|
792
|
+
*/
|
|
793
|
+
get hasPendingSchemaChanges() { return this._nativeDb.hasPendingSchemaChanges(); }
|
|
590
794
|
/**
|
|
591
795
|
* Query if there are changes in memory that have not been saved to the iModelDb or if there are Txns that are waiting to be pushed.
|
|
592
796
|
* @see [[IModelDb.saveChanges]]
|
|
@@ -616,5 +820,27 @@ export class TxnManager {
|
|
|
616
820
|
getChangeTrackingMemoryUsed() {
|
|
617
821
|
return this._iModel[_nativeDb].getChangeTrackingMemoryUsed();
|
|
618
822
|
}
|
|
823
|
+
/**
|
|
824
|
+
* @alpha
|
|
825
|
+
* Get the current transaction mode.
|
|
826
|
+
* @returns The current transaction mode, either "direct" or "indirect".
|
|
827
|
+
*/
|
|
828
|
+
getMode() {
|
|
829
|
+
return this._nativeDb.getTxnMode();
|
|
830
|
+
}
|
|
831
|
+
/**
|
|
832
|
+
* @alpha
|
|
833
|
+
* Execute a series of changes in an indirect transaction.
|
|
834
|
+
* @param callback The function containing the changes to make.
|
|
835
|
+
*/
|
|
836
|
+
withIndirectTxnMode(callback) {
|
|
837
|
+
this._nativeDb.setTxnMode("indirect");
|
|
838
|
+
try {
|
|
839
|
+
callback();
|
|
840
|
+
}
|
|
841
|
+
finally {
|
|
842
|
+
this._nativeDb.setTxnMode("direct");
|
|
843
|
+
}
|
|
844
|
+
}
|
|
619
845
|
}
|
|
620
846
|
//# sourceMappingURL=TxnManager.js.map
|