@itwin/core-backend 5.8.0-dev.11 → 5.8.0-dev.13
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/IModelDb.d.ts.map +1 -1
- package/lib/cjs/IModelDb.js +0 -3
- package/lib/cjs/IModelDb.js.map +1 -1
- package/lib/cjs/LocalHub.d.ts +17 -10
- package/lib/cjs/LocalHub.d.ts.map +1 -1
- package/lib/cjs/LocalHub.js +126 -28
- package/lib/cjs/LocalHub.js.map +1 -1
- package/lib/cjs/internal/workspace/SettingsDbImpl.d.ts.map +1 -1
- package/lib/cjs/internal/workspace/SettingsDbImpl.js +2 -0
- package/lib/cjs/internal/workspace/SettingsDbImpl.js.map +1 -1
- package/lib/cjs/internal/workspace/SettingsEditorImpl.d.ts +7 -0
- package/lib/cjs/internal/workspace/SettingsEditorImpl.d.ts.map +1 -0
- package/lib/cjs/internal/workspace/SettingsEditorImpl.js +266 -0
- package/lib/cjs/internal/workspace/SettingsEditorImpl.js.map +1 -0
- package/lib/cjs/internal/workspace/SettingsImpl.d.ts +1 -3
- package/lib/cjs/internal/workspace/SettingsImpl.d.ts.map +1 -1
- package/lib/cjs/internal/workspace/SettingsImpl.js +4 -250
- package/lib/cjs/internal/workspace/SettingsImpl.js.map +1 -1
- package/lib/cjs/internal/workspace/WorkspaceImpl.d.ts.map +1 -1
- package/lib/cjs/internal/workspace/WorkspaceImpl.js +13 -11
- package/lib/cjs/internal/workspace/WorkspaceImpl.js.map +1 -1
- package/lib/cjs/workspace/SettingsEditor.d.ts +4 -0
- package/lib/cjs/workspace/SettingsEditor.d.ts.map +1 -1
- package/lib/cjs/workspace/SettingsEditor.js +7 -5
- package/lib/cjs/workspace/SettingsEditor.js.map +1 -1
- package/lib/cjs/workspace/Workspace.d.ts +3 -1
- package/lib/cjs/workspace/Workspace.d.ts.map +1 -1
- package/lib/cjs/workspace/Workspace.js.map +1 -1
- package/lib/cjs/workspace/WorkspaceEditor.d.ts +4 -1
- package/lib/cjs/workspace/WorkspaceEditor.d.ts.map +1 -1
- package/lib/cjs/workspace/WorkspaceEditor.js +2 -0
- package/lib/cjs/workspace/WorkspaceEditor.js.map +1 -1
- package/lib/esm/IModelDb.d.ts.map +1 -1
- package/lib/esm/IModelDb.js +0 -3
- package/lib/esm/IModelDb.js.map +1 -1
- package/lib/esm/LocalHub.d.ts +17 -10
- package/lib/esm/LocalHub.d.ts.map +1 -1
- package/lib/esm/LocalHub.js +127 -29
- package/lib/esm/LocalHub.js.map +1 -1
- package/lib/esm/internal/workspace/SettingsDbImpl.d.ts.map +1 -1
- package/lib/esm/internal/workspace/SettingsDbImpl.js +2 -0
- package/lib/esm/internal/workspace/SettingsDbImpl.js.map +1 -1
- package/lib/esm/internal/workspace/SettingsEditorImpl.d.ts +7 -0
- package/lib/esm/internal/workspace/SettingsEditorImpl.d.ts.map +1 -0
- package/lib/esm/internal/workspace/SettingsEditorImpl.js +263 -0
- package/lib/esm/internal/workspace/SettingsEditorImpl.js.map +1 -0
- package/lib/esm/internal/workspace/SettingsImpl.d.ts +1 -3
- package/lib/esm/internal/workspace/SettingsImpl.d.ts.map +1 -1
- package/lib/esm/internal/workspace/SettingsImpl.js +5 -251
- package/lib/esm/internal/workspace/SettingsImpl.js.map +1 -1
- package/lib/esm/internal/workspace/WorkspaceImpl.d.ts.map +1 -1
- package/lib/esm/internal/workspace/WorkspaceImpl.js +13 -11
- package/lib/esm/internal/workspace/WorkspaceImpl.js.map +1 -1
- package/lib/esm/test/standalone/HubMock.test.js +177 -7
- package/lib/esm/test/standalone/HubMock.test.js.map +1 -1
- package/lib/esm/test/standalone/Workspace.test.js +100 -0
- package/lib/esm/test/standalone/Workspace.test.js.map +1 -1
- package/lib/esm/test/workspace/SettingsDb.test.js +95 -2
- package/lib/esm/test/workspace/SettingsDb.test.js.map +1 -1
- package/lib/esm/workspace/SettingsEditor.d.ts +4 -0
- package/lib/esm/workspace/SettingsEditor.d.ts.map +1 -1
- package/lib/esm/workspace/SettingsEditor.js +6 -4
- package/lib/esm/workspace/SettingsEditor.js.map +1 -1
- package/lib/esm/workspace/Workspace.d.ts +3 -1
- package/lib/esm/workspace/Workspace.d.ts.map +1 -1
- package/lib/esm/workspace/Workspace.js.map +1 -1
- package/lib/esm/workspace/WorkspaceEditor.d.ts +4 -1
- package/lib/esm/workspace/WorkspaceEditor.d.ts.map +1 -1
- package/lib/esm/workspace/WorkspaceEditor.js +2 -0
- package/lib/esm/workspace/WorkspaceEditor.js.map +1 -1
- package/package.json +13 -13
package/lib/esm/LocalHub.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GuidString, Id64String } from "@itwin/core-bentley";
|
|
2
2
|
import { BriefcaseId, ChangesetFileProps, ChangesetId, ChangesetIdWithIndex, ChangesetIndex, ChangesetIndexOrId, ChangesetProps, ChangesetRange, LocalDirName, LocalFileName, LockState } from "@itwin/core-common";
|
|
3
|
-
import { LockMap, LockProps } from "./BackendHubAccess";
|
|
3
|
+
import { BriefcaseIdArg, LockMap, LockProps } from "./BackendHubAccess";
|
|
4
4
|
/** @internal */
|
|
5
5
|
interface MockBriefcaseIdProps {
|
|
6
6
|
id: BriefcaseId;
|
|
@@ -17,27 +17,27 @@ interface LocalHubProps {
|
|
|
17
17
|
readonly version0?: string;
|
|
18
18
|
readonly noLocks?: true;
|
|
19
19
|
}
|
|
20
|
-
interface
|
|
20
|
+
interface LockLastReleaseChangesetIndices {
|
|
21
|
+
lastExclusiveReleaseChangesetIndex?: ChangesetIndex;
|
|
22
|
+
lastSharedReleaseChangesetIndex?: ChangesetIndex;
|
|
23
|
+
}
|
|
24
|
+
interface LocksEntry extends LockLastReleaseChangesetIndices {
|
|
21
25
|
id: Id64String;
|
|
22
26
|
level: LockState;
|
|
23
|
-
lastCsIndex?: ChangesetIndex;
|
|
24
27
|
briefcaseId?: BriefcaseId;
|
|
25
28
|
}
|
|
26
|
-
interface LockStatusNone {
|
|
29
|
+
interface LockStatusNone extends LockLastReleaseChangesetIndices {
|
|
27
30
|
state: LockState.None;
|
|
28
|
-
lastCsIndex?: ChangesetIndex;
|
|
29
31
|
}
|
|
30
32
|
/** @internal exported for tests. */
|
|
31
|
-
export interface LockStatusExclusive {
|
|
33
|
+
export interface LockStatusExclusive extends LockLastReleaseChangesetIndices {
|
|
32
34
|
state: LockState.Exclusive;
|
|
33
35
|
briefcaseId: BriefcaseId;
|
|
34
|
-
lastCsIndex?: ChangesetIndex;
|
|
35
36
|
}
|
|
36
37
|
/** @internal exported for tests. */
|
|
37
|
-
export interface LockStatusShared {
|
|
38
|
+
export interface LockStatusShared extends LockLastReleaseChangesetIndices {
|
|
38
39
|
state: LockState.Shared;
|
|
39
40
|
sharedBy: Set<BriefcaseId>;
|
|
40
|
-
lastCsIndex?: ChangesetIndex;
|
|
41
41
|
}
|
|
42
42
|
interface BriefcaseIdAndChangeset {
|
|
43
43
|
changeset: ChangesetIdWithIndex;
|
|
@@ -131,11 +131,16 @@ export declare class LocalHub {
|
|
|
131
131
|
private querySharedLockHolders;
|
|
132
132
|
queryAllLocks(briefcaseId: BriefcaseId): LockProps[];
|
|
133
133
|
queryLockStatus(elementId: Id64String): LockStatus;
|
|
134
|
+
private doesBriefcaseRequirePullBeforeLock;
|
|
135
|
+
private addSharedLockRecord;
|
|
134
136
|
private reserveLock;
|
|
137
|
+
private downgradeExclusiveLockToShared;
|
|
135
138
|
private clearLock;
|
|
136
|
-
private
|
|
139
|
+
private updateLockExclusiveChangeset;
|
|
140
|
+
private updateLockSharedChangeset;
|
|
137
141
|
private requestLock;
|
|
138
142
|
private removeSharedLock;
|
|
143
|
+
private abandonLock;
|
|
139
144
|
private releaseLock;
|
|
140
145
|
/** Acquire a set of locks. If any lock cannot be acquired, no locks are acquired */
|
|
141
146
|
acquireLocks(locks: LockMap, briefcase: BriefcaseIdAndChangeset): void;
|
|
@@ -144,10 +149,12 @@ export declare class LocalHub {
|
|
|
144
149
|
briefcaseId: BriefcaseId;
|
|
145
150
|
changesetIndex: ChangesetIndex;
|
|
146
151
|
}): void;
|
|
152
|
+
abandonLocks(locks: LockMap, arg: BriefcaseIdArg): void;
|
|
147
153
|
releaseAllLocks(arg: {
|
|
148
154
|
briefcaseId: BriefcaseId;
|
|
149
155
|
changesetIndex: ChangesetIndex;
|
|
150
156
|
}): void;
|
|
157
|
+
abandonAllLocks(arg: BriefcaseIdArg): void;
|
|
151
158
|
private countTable;
|
|
152
159
|
countSharedLocks(): number;
|
|
153
160
|
countLocks(): number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocalHub.d.ts","sourceRoot":"","sources":["../../src/LocalHub.ts"],"names":[],"mappings":"AAMA,OAAO,
|
|
1
|
+
{"version":3,"file":"LocalHub.d.ts","sourceRoot":"","sources":["../../src/LocalHub.ts"],"names":[],"mappings":"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"}
|
package/lib/esm/LocalHub.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import { join } from "path";
|
|
6
|
-
import { DbResult, IModelHubStatus, IModelStatus, OpenMode } from "@itwin/core-bentley";
|
|
6
|
+
import { assert, DbResult, IModelHubStatus, IModelStatus, OpenMode } from "@itwin/core-bentley";
|
|
7
7
|
import { BriefcaseIdValue, IModelError, LockState, } from "@itwin/core-common";
|
|
8
8
|
import { LockConflict } from "./BackendHubAccess";
|
|
9
9
|
import { BriefcaseManager } from "./BriefcaseManager";
|
|
@@ -41,7 +41,7 @@ export class LocalHub {
|
|
|
41
41
|
FOREIGN KEY(briefcaseId) REFERENCES briefcases(id))");
|
|
42
42
|
db.executeSQL("CREATE TABLE checkpoints(csIndex INTEGER PRIMARY KEY NOT NULL)");
|
|
43
43
|
db.executeSQL("CREATE TABLE versions(name TEXT PRIMARY KEY NOT NULL,csIndex TEXT,FOREIGN KEY(csIndex) REFERENCES timeline(csIndex))");
|
|
44
|
-
db.executeSQL("CREATE TABLE locks(id INTEGER PRIMARY KEY NOT NULL,level INTEGER NOT NULL,
|
|
44
|
+
db.executeSQL("CREATE TABLE locks(id INTEGER PRIMARY KEY NOT NULL,level INTEGER NOT NULL,lastExclusiveReleaseChangesetIndex INTEGER,lastSharedReleaseChangesetIndex INTEGER,briefcaseId INTEGER)");
|
|
45
45
|
db.executeSQL("CREATE TABLE sharedLocks(lockId INTEGER NOT NULL,briefcaseId INTEGER NOT NULL,PRIMARY KEY(lockId,briefcaseId))");
|
|
46
46
|
db.executeSQL("CREATE INDEX LockIdx ON locks(briefcaseId)");
|
|
47
47
|
db.executeSQL("CREATE INDEX SharedLockIdx ON sharedLocks(briefcaseId)");
|
|
@@ -380,21 +380,23 @@ export class LocalHub {
|
|
|
380
380
|
return locks;
|
|
381
381
|
}
|
|
382
382
|
queryLockStatus(elementId) {
|
|
383
|
-
return this.db.withPreparedSqliteStatement("SELECT
|
|
383
|
+
return this.db.withPreparedSqliteStatement("SELECT lastSharedReleaseChangesetIndex,lastExclusiveReleaseChangesetIndex,level,briefcaseId FROM locks WHERE id=?", (stmt) => {
|
|
384
384
|
stmt.bindId(1, elementId);
|
|
385
385
|
const rc = stmt.step();
|
|
386
386
|
if (DbResult.BE_SQLITE_ROW !== rc)
|
|
387
387
|
return { state: LockState.None };
|
|
388
|
-
const
|
|
388
|
+
const lastSharedCsVal = stmt.getValue(0);
|
|
389
|
+
const lastExclusiveCsVal = stmt.getValue(1);
|
|
389
390
|
const lock = {
|
|
390
|
-
|
|
391
|
-
|
|
391
|
+
lastSharedReleaseChangesetIndex: lastSharedCsVal.isNull ? undefined : lastSharedCsVal.getInteger(),
|
|
392
|
+
lastExclusiveReleaseChangesetIndex: lastExclusiveCsVal.isNull ? undefined : lastExclusiveCsVal.getInteger(),
|
|
393
|
+
state: stmt.getValueInteger(2),
|
|
392
394
|
};
|
|
393
395
|
switch (lock.state) {
|
|
394
396
|
case LockState.None:
|
|
395
397
|
return lock;
|
|
396
398
|
case LockState.Exclusive:
|
|
397
|
-
return { ...lock, briefcaseId: stmt.getValueInteger(
|
|
399
|
+
return { ...lock, briefcaseId: stmt.getValueInteger(3) };
|
|
398
400
|
case LockState.Shared:
|
|
399
401
|
return { ...lock, sharedBy: this.querySharedLockHolders(elementId) };
|
|
400
402
|
default:
|
|
@@ -402,9 +404,37 @@ export class LocalHub {
|
|
|
402
404
|
}
|
|
403
405
|
});
|
|
404
406
|
}
|
|
407
|
+
doesBriefcaseRequirePullBeforeLock(currStatus, props, briefcase) {
|
|
408
|
+
if (props.state === LockState.None)
|
|
409
|
+
return false;
|
|
410
|
+
const briefcaseChangesetIndex = this.getIndexFromChangeset(briefcase.changeset);
|
|
411
|
+
const exclusiveIndexIsNewer = currStatus.lastExclusiveReleaseChangesetIndex !== undefined &&
|
|
412
|
+
currStatus.lastExclusiveReleaseChangesetIndex > briefcaseChangesetIndex;
|
|
413
|
+
if (props.state === LockState.Shared) {
|
|
414
|
+
// To acquire a shared lock, the briefcase must at least at the latest exclusive changeset index
|
|
415
|
+
return exclusiveIndexIsNewer;
|
|
416
|
+
}
|
|
417
|
+
else {
|
|
418
|
+
assert(props.state === LockState.Exclusive);
|
|
419
|
+
const sharedIndexIsNewer = currStatus.lastSharedReleaseChangesetIndex !== undefined &&
|
|
420
|
+
currStatus.lastSharedReleaseChangesetIndex > briefcaseChangesetIndex;
|
|
421
|
+
// To acquire the exclusive lock the briefcase must be at least at the greater of the two last-indexes
|
|
422
|
+
return exclusiveIndexIsNewer || sharedIndexIsNewer;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
addSharedLockRecord(lockId, briefcaseId) {
|
|
426
|
+
this.db.withPreparedSqliteStatement("INSERT INTO sharedLocks(lockId,briefcaseId) VALUES(?,?) ON CONFLICT(lockId,briefcaseId) DO NOTHING", (stmt) => {
|
|
427
|
+
stmt.bindId(1, lockId);
|
|
428
|
+
stmt.bindInteger(2, briefcaseId);
|
|
429
|
+
const rc = stmt.step();
|
|
430
|
+
if (rc !== DbResult.BE_SQLITE_DONE)
|
|
431
|
+
throw new IModelError(rc, "cannot insert shared lock");
|
|
432
|
+
});
|
|
433
|
+
}
|
|
405
434
|
reserveLock(currStatus, props, briefcase) {
|
|
406
|
-
if (
|
|
435
|
+
if (this.doesBriefcaseRequirePullBeforeLock(currStatus, props, briefcase)) {
|
|
407
436
|
throw new IModelError(IModelHubStatus.PullIsRequired, "pull is required to obtain lock");
|
|
437
|
+
}
|
|
408
438
|
const wantShared = props.state === LockState.Shared;
|
|
409
439
|
if (wantShared && (currStatus.state === LockState.Exclusive))
|
|
410
440
|
throw new Error("cannot acquire shared lock because an exclusive lock is already held");
|
|
@@ -417,15 +447,26 @@ export class LocalHub {
|
|
|
417
447
|
throw new IModelError(rc, "cannot insert lock");
|
|
418
448
|
});
|
|
419
449
|
if (wantShared) {
|
|
420
|
-
this.
|
|
421
|
-
stmt.bindId(1, props.id);
|
|
422
|
-
stmt.bindInteger(2, briefcase.briefcaseId);
|
|
423
|
-
const rc = stmt.step();
|
|
424
|
-
if (rc !== DbResult.BE_SQLITE_DONE)
|
|
425
|
-
throw new IModelError(rc, "cannot insert shared lock");
|
|
426
|
-
});
|
|
450
|
+
this.addSharedLockRecord(props.id, briefcase.briefcaseId);
|
|
427
451
|
}
|
|
428
452
|
}
|
|
453
|
+
downgradeExclusiveLockToShared(lockId, briefcaseId) {
|
|
454
|
+
this.db.withPreparedSqliteStatement("UPDATE locks SET level=1,briefcaseId=NULL WHERE id=? AND briefcaseId=? AND level=2", (stmt) => {
|
|
455
|
+
stmt.bindId(1, lockId);
|
|
456
|
+
stmt.bindInteger(2, briefcaseId);
|
|
457
|
+
const rc = stmt.step();
|
|
458
|
+
if (rc !== DbResult.BE_SQLITE_DONE)
|
|
459
|
+
throw new IModelError(rc, "can't downgrade lock");
|
|
460
|
+
});
|
|
461
|
+
// Verify that the above actually updated a row. If it didn't, something has gone wrong with the downgrade.
|
|
462
|
+
// This shouldn't happen.
|
|
463
|
+
this.db.withPreparedSqliteStatement("SELECT CHANGES()", (stmt) => {
|
|
464
|
+
stmt.step();
|
|
465
|
+
if (stmt.getValueInteger(0) !== 1)
|
|
466
|
+
throw new IModelError(IModelHubStatus.LockOwnedByAnotherBriefcase, "lock not held by this briefcase or lock is not exclusive");
|
|
467
|
+
});
|
|
468
|
+
this.addSharedLockRecord(lockId, briefcaseId);
|
|
469
|
+
}
|
|
429
470
|
clearLock(id) {
|
|
430
471
|
this.db.withPreparedSqliteStatement("UPDATE locks SET level=0,briefcaseId=NULL WHERE id=?", (stmt) => {
|
|
431
472
|
stmt.bindId(1, id);
|
|
@@ -434,15 +475,26 @@ export class LocalHub {
|
|
|
434
475
|
throw new IModelError(rc, "can't release lock");
|
|
435
476
|
});
|
|
436
477
|
}
|
|
437
|
-
|
|
478
|
+
updateLockExclusiveChangeset(id, index) {
|
|
438
479
|
if (index <= 0)
|
|
439
480
|
return;
|
|
440
|
-
this.db.withPreparedSqliteStatement("UPDATE locks SET
|
|
481
|
+
this.db.withPreparedSqliteStatement("UPDATE locks SET lastExclusiveReleaseChangesetIndex=? WHERE id=?", (stmt) => {
|
|
441
482
|
stmt.bindInteger(1, index);
|
|
442
483
|
stmt.bindId(2, id);
|
|
443
484
|
const rc = stmt.step();
|
|
444
485
|
if (rc !== DbResult.BE_SQLITE_DONE)
|
|
445
|
-
throw new IModelError(rc, "can't update lock changeSetId");
|
|
486
|
+
throw new IModelError(rc, "can't update lock exclusive changeSetId");
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
updateLockSharedChangeset(id, index) {
|
|
490
|
+
if (index <= 0)
|
|
491
|
+
return;
|
|
492
|
+
this.db.withPreparedSqliteStatement("UPDATE locks SET lastSharedReleaseChangesetIndex=? WHERE id=?", (stmt) => {
|
|
493
|
+
stmt.bindInteger(1, index);
|
|
494
|
+
stmt.bindId(2, id);
|
|
495
|
+
const rc = stmt.step();
|
|
496
|
+
if (rc !== DbResult.BE_SQLITE_DONE)
|
|
497
|
+
throw new IModelError(rc, "can't update lock shared changeSetId");
|
|
446
498
|
});
|
|
447
499
|
}
|
|
448
500
|
requestLock(props, briefcase) {
|
|
@@ -482,23 +534,58 @@ export class LocalHub {
|
|
|
482
534
|
throw new IModelError(rc, "can't remove shared lock");
|
|
483
535
|
});
|
|
484
536
|
}
|
|
485
|
-
|
|
537
|
+
abandonLock(props, briefcase) {
|
|
538
|
+
// When abandoning (but not when releasing), props.state indicates which
|
|
539
|
+
// state we're abandoning _to_. Specifically, an Exclusive lock can be
|
|
540
|
+
// abandoned to either Shared or None.
|
|
541
|
+
// It makes no sense to abandon a lock _to_ the Exclusive state.
|
|
542
|
+
if (props.state === LockState.Exclusive)
|
|
543
|
+
throw new IModelError(IModelHubStatus.InvalidArgumentError, "must specify Shared or None when abandoning a lock");
|
|
486
544
|
const lockId = props.id;
|
|
487
|
-
const
|
|
488
|
-
switch (
|
|
545
|
+
const previousLockStatus = this.queryLockStatus(lockId);
|
|
546
|
+
switch (previousLockStatus.state) {
|
|
547
|
+
case LockState.None:
|
|
548
|
+
throw new IModelError(IModelHubStatus.LockDoesNotExist, "lock not held");
|
|
549
|
+
case LockState.Exclusive:
|
|
550
|
+
if (previousLockStatus.briefcaseId !== briefcase.briefcaseId)
|
|
551
|
+
throw new IModelError(IModelHubStatus.LockOwnedByAnotherBriefcase, "lock not held by this briefcase");
|
|
552
|
+
if (props.state === LockState.Shared) {
|
|
553
|
+
// Exclusive -> Shared
|
|
554
|
+
this.downgradeExclusiveLockToShared(lockId, briefcase.briefcaseId);
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
// Exclusive -> None
|
|
558
|
+
this.clearLock(lockId);
|
|
559
|
+
}
|
|
560
|
+
break;
|
|
561
|
+
case LockState.Shared:
|
|
562
|
+
if (!previousLockStatus.sharedBy.has(briefcase.briefcaseId))
|
|
563
|
+
throw new IModelError(IModelHubStatus.LockDoesNotExist, "shared lock not held by this briefcase");
|
|
564
|
+
this.removeSharedLock(lockId, briefcase.briefcaseId);
|
|
565
|
+
if (previousLockStatus.sharedBy.size === 1)
|
|
566
|
+
this.clearLock(lockId);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
releaseLock(props, briefcase) {
|
|
570
|
+
// Unlike abandonLock above, release always releases the lock all the way back to the None state.
|
|
571
|
+
// So we ignore props.state. There's no such thing as a "downgrade" here.
|
|
572
|
+
const lockId = props.id;
|
|
573
|
+
const previousLockStatus = this.queryLockStatus(lockId);
|
|
574
|
+
switch (previousLockStatus.state) {
|
|
489
575
|
case LockState.None:
|
|
490
576
|
throw new IModelError(IModelHubStatus.LockDoesNotExist, "lock not held");
|
|
491
577
|
case LockState.Exclusive:
|
|
492
|
-
if (
|
|
578
|
+
if (previousLockStatus.briefcaseId !== briefcase.briefcaseId)
|
|
493
579
|
throw new IModelError(IModelHubStatus.LockOwnedByAnotherBriefcase, "lock not held by this briefcase");
|
|
494
|
-
this.
|
|
580
|
+
this.updateLockExclusiveChangeset(lockId, briefcase.changesetIndex);
|
|
495
581
|
this.clearLock(lockId);
|
|
496
582
|
break;
|
|
497
583
|
case LockState.Shared:
|
|
498
|
-
if (!
|
|
584
|
+
if (!previousLockStatus.sharedBy.has(briefcase.briefcaseId))
|
|
499
585
|
throw new IModelError(IModelHubStatus.LockDoesNotExist, "shared lock not held by this briefcase");
|
|
500
|
-
this.
|
|
501
|
-
|
|
586
|
+
this.updateLockSharedChangeset(lockId, briefcase.changesetIndex);
|
|
587
|
+
this.removeSharedLock(lockId, briefcase.briefcaseId);
|
|
588
|
+
if (previousLockStatus.sharedBy.size === 1)
|
|
502
589
|
this.clearLock(lockId);
|
|
503
590
|
}
|
|
504
591
|
}
|
|
@@ -524,10 +611,20 @@ export class LocalHub {
|
|
|
524
611
|
this.releaseLock(props, arg);
|
|
525
612
|
this.db.saveChanges();
|
|
526
613
|
}
|
|
614
|
+
abandonLocks(locks, arg) {
|
|
615
|
+
for (const props of locks)
|
|
616
|
+
this.abandonLock({ id: props[0], state: props[1] }, arg);
|
|
617
|
+
this.db.saveChanges();
|
|
618
|
+
}
|
|
527
619
|
releaseAllLocks(arg) {
|
|
528
620
|
const locks = this.queryAllLocks(arg.briefcaseId);
|
|
529
621
|
this.releaseLocks(locks, arg);
|
|
530
622
|
}
|
|
623
|
+
abandonAllLocks(arg) {
|
|
624
|
+
const locks = new Map();
|
|
625
|
+
this.queryAllLocks(arg.briefcaseId).forEach(lock => locks.set(lock.id, LockState.None));
|
|
626
|
+
this.abandonLocks(locks, arg);
|
|
627
|
+
}
|
|
531
628
|
countTable(tableName) {
|
|
532
629
|
return this.db.withSqliteStatement(`SELECT count(*) from ${tableName}`, (stmt) => {
|
|
533
630
|
stmt.step();
|
|
@@ -550,13 +647,14 @@ export class LocalHub {
|
|
|
550
647
|
// for debugging
|
|
551
648
|
queryLocks() {
|
|
552
649
|
const locks = [];
|
|
553
|
-
this.db.withPreparedSqliteStatement("SELECT id,level,
|
|
650
|
+
this.db.withPreparedSqliteStatement("SELECT id,level,lastExclusiveReleaseChangesetIndex,lastSharedReleaseChangesetIndex,briefcaseId FROM locks", (stmt) => {
|
|
554
651
|
while (DbResult.BE_SQLITE_ROW === stmt.step())
|
|
555
652
|
locks.push({
|
|
556
653
|
id: stmt.getValueId(0),
|
|
557
654
|
level: stmt.getValueInteger(1),
|
|
558
|
-
|
|
559
|
-
|
|
655
|
+
lastExclusiveReleaseChangesetIndex: stmt.getValue(2).isNull ? undefined : stmt.getValueInteger(2),
|
|
656
|
+
lastSharedReleaseChangesetIndex: stmt.getValue(3).isNull ? undefined : stmt.getValueInteger(3),
|
|
657
|
+
briefcaseId: stmt.getValue(4).isNull ? undefined : stmt.getValueInteger(4),
|
|
560
658
|
});
|
|
561
659
|
});
|
|
562
660
|
return locks;
|