@proteinjs/db 1.33.0 → 1.34.0
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 -0
- package/dist/generated/index.js +1 -1
- package/dist/generated/index.js.map +1 -1
- package/dist/generated/test/index.d.ts.map +1 -1
- package/dist/generated/test/index.js +15 -1
- package/dist/generated/test/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/src/Db.d.ts +2 -0
- package/dist/src/Db.d.ts.map +1 -1
- package/dist/src/Db.js +33 -62
- package/dist/src/Db.js.map +1 -1
- package/dist/src/ReverseCascadeEdgeIndex.d.ts +51 -0
- package/dist/src/ReverseCascadeEdgeIndex.d.ts.map +1 -0
- package/dist/src/ReverseCascadeEdgeIndex.js +108 -0
- package/dist/src/ReverseCascadeEdgeIndex.js.map +1 -0
- package/dist/src/Table.d.ts +34 -7
- package/dist/src/Table.d.ts.map +1 -1
- package/dist/src/Table.js +2 -7
- package/dist/src/Table.js.map +1 -1
- package/dist/src/schema/TableManager.d.ts +26 -0
- package/dist/src/schema/TableManager.d.ts.map +1 -1
- package/dist/src/schema/TableManager.js +154 -13
- package/dist/src/schema/TableManager.js.map +1 -1
- package/dist/src/source/SourceRecordLoader.d.ts +18 -1
- package/dist/src/source/SourceRecordLoader.d.ts.map +1 -1
- package/dist/src/source/SourceRecordLoader.js +187 -68
- package/dist/src/source/SourceRecordLoader.js.map +1 -1
- package/dist/src/tables/MigrationTable.d.ts +1 -6
- package/dist/src/tables/MigrationTable.d.ts.map +1 -1
- package/dist/src/tables/MigrationTable.js +2 -1
- package/dist/src/tables/MigrationTable.js.map +1 -1
- package/dist/test/index.d.ts +2 -0
- package/dist/test/index.d.ts.map +1 -1
- package/dist/test/index.js +2 -0
- package/dist/test/index.js.map +1 -1
- package/dist/test/reusable/CascadeDeleteTests.d.ts.map +1 -1
- package/dist/test/reusable/CascadeDeleteTests.js +59 -0
- package/dist/test/reusable/CascadeDeleteTests.js.map +1 -1
- package/dist/test/reusable/SourceRecordSyncTests.d.ts +11 -0
- package/dist/test/reusable/SourceRecordSyncTests.d.ts.map +1 -0
- package/dist/test/reusable/SourceRecordSyncTests.js +483 -0
- package/dist/test/reusable/SourceRecordSyncTests.js.map +1 -0
- package/dist/test/util/DbTestEnvironment.d.ts.map +1 -1
- package/dist/test/util/DbTestEnvironment.js +2 -1
- package/dist/test/util/DbTestEnvironment.js.map +1 -1
- package/dist/test/util/tables/cascadeDeleteTestTables.d.ts +46 -0
- package/dist/test/util/tables/cascadeDeleteTestTables.d.ts.map +1 -1
- package/dist/test/util/tables/cascadeDeleteTestTables.js +51 -1
- package/dist/test/util/tables/cascadeDeleteTestTables.js.map +1 -1
- package/dist/test/util/tables/crudTestTables.d.ts +1 -1
- package/dist/test/util/tables/sourceRecordSyncTestTables.d.ts +82 -0
- package/dist/test/util/tables/sourceRecordSyncTestTables.d.ts.map +1 -0
- package/dist/test/util/tables/sourceRecordSyncTestTables.js +90 -0
- package/dist/test/util/tables/sourceRecordSyncTestTables.js.map +1 -0
- package/dist/test/util/tables/transactionTestTables.d.ts +1 -1
- package/generated/index.ts +1 -1
- package/generated/test/index.ts +15 -1
- package/index.ts +4 -0
- package/package.json +2 -2
- package/src/Db.ts +32 -57
- package/src/ReverseCascadeEdgeIndex.ts +126 -0
- package/src/Table.ts +32 -9
- package/src/schema/TableManager.ts +98 -1
- package/src/source/SourceRecordLoader.ts +133 -23
- package/src/tables/MigrationTable.ts +3 -2
- package/test/index.ts +2 -0
- package/test/reusable/CascadeDeleteTests.ts +46 -0
- package/test/reusable/SourceRecordSyncTests.ts +288 -0
- package/test/util/DbTestEnvironment.ts +2 -0
- package/test/util/tables/cascadeDeleteTestTables.ts +48 -0
- package/test/util/tables/sourceRecordSyncTestTables.ts +84 -0
|
@@ -67,6 +67,19 @@ export interface Task extends Record {
|
|
|
67
67
|
assigneeRef?: Reference<Worker> | null;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
// --- Reverse: DynamicReferenceColumn across multiple target tables (Mission -> Pilot | Robot)
|
|
71
|
+
export interface Pilot extends Record {
|
|
72
|
+
name: string;
|
|
73
|
+
}
|
|
74
|
+
export interface Robot extends Record {
|
|
75
|
+
name: string;
|
|
76
|
+
}
|
|
77
|
+
export interface Mission extends Record {
|
|
78
|
+
title: string;
|
|
79
|
+
assigneeTableName?: string | null;
|
|
80
|
+
assigneeRef?: Reference<Pilot | Robot> | null;
|
|
81
|
+
}
|
|
82
|
+
|
|
70
83
|
/**
|
|
71
84
|
* ---------- Table Names ----------
|
|
72
85
|
*/
|
|
@@ -94,6 +107,11 @@ const GROUP_ARR_REV_TABLE = 'db_test_cd_groups_arr_rev';
|
|
|
94
107
|
const WORKER_TABLE = 'db_test_cd_workers';
|
|
95
108
|
const TASK_TABLE = 'db_test_cd_tasks';
|
|
96
109
|
|
|
110
|
+
// Reverse (DynamicReferenceColumn, multiple targets)
|
|
111
|
+
const PILOT_TABLE = 'db_test_cd_pilots';
|
|
112
|
+
const ROBOT_TABLE = 'db_test_cd_robots';
|
|
113
|
+
const MISSION_TABLE = 'db_test_cd_missions';
|
|
114
|
+
|
|
97
115
|
/**
|
|
98
116
|
* ---------- Table Classes ----------
|
|
99
117
|
*/
|
|
@@ -216,6 +234,33 @@ export class TaskTable extends Table<Task> {
|
|
|
216
234
|
});
|
|
217
235
|
}
|
|
218
236
|
|
|
237
|
+
// Reverse: DynamicReferenceColumn across multiple target tables
|
|
238
|
+
export class PilotTable extends Table<Pilot> {
|
|
239
|
+
name = PILOT_TABLE;
|
|
240
|
+
columns = withRecordColumns<Pilot>({
|
|
241
|
+
name: new StringColumn('name'),
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
export class RobotTable extends Table<Robot> {
|
|
245
|
+
name = ROBOT_TABLE;
|
|
246
|
+
columns = withRecordColumns<Robot>({
|
|
247
|
+
name: new StringColumn('name'),
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
export class MissionTable extends Table<Mission> {
|
|
251
|
+
name = MISSION_TABLE;
|
|
252
|
+
columns = withRecordColumns<Mission>({
|
|
253
|
+
title: new StringColumn('title'),
|
|
254
|
+
assigneeTableName: new DynamicReferenceTableNameColumn('assignee_table_name', 'assignee_ref'),
|
|
255
|
+
assigneeRef: new DynamicReferenceColumn<Pilot | Robot>(
|
|
256
|
+
'assignee_ref',
|
|
257
|
+
'assignee_table_name',
|
|
258
|
+
false,
|
|
259
|
+
{ reverseCascadeDelete: true } // reverse: deleting a Pilot OR a Robot deletes its Missions
|
|
260
|
+
),
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
219
264
|
export const cascadeDeleteTestTables = {
|
|
220
265
|
MemberRef: new MemberRefTable() as Table<MemberRef>,
|
|
221
266
|
GroupRef: new GroupRefTable() as Table<GroupRef>,
|
|
@@ -229,4 +274,7 @@ export const cascadeDeleteTestTables = {
|
|
|
229
274
|
GroupArrRev: new GroupArrRevTable() as Table<GroupArrRev>,
|
|
230
275
|
Worker: new WorkerTable() as Table<Worker>,
|
|
231
276
|
Task: new TaskTable() as Table<Task>,
|
|
277
|
+
Pilot: new PilotTable() as Table<Pilot>,
|
|
278
|
+
Robot: new RobotTable() as Table<Robot>,
|
|
279
|
+
Mission: new MissionTable() as Table<Mission>,
|
|
232
280
|
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Record as DbRecord,
|
|
3
|
+
SourceRecord,
|
|
4
|
+
StringColumn,
|
|
5
|
+
Table,
|
|
6
|
+
withRecordColumns,
|
|
7
|
+
withSourceRecordColumns,
|
|
8
|
+
} from '@proteinjs/db';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Fixtures for the source-record sync suites ({@link sourceRecordSyncTests}): a machine-account-
|
|
12
|
+
* shaped mixed table (natural-key adoption + flag-on-removed), a default-policy table (removed =
|
|
13
|
+
* deleted), a misdeclared natural-key table (non-unique column), and the two-generation table
|
|
14
|
+
* pair driving the unique-index duplicate preflight.
|
|
15
|
+
*
|
|
16
|
+
* The `sourceRecordOptions` literals are `as`-cast to the table's options type (not inferred):
|
|
17
|
+
* the cast also compiles against PRE-change `@proteinjs/db`, so the suites can run red-before-
|
|
18
|
+
* green against the old loader (which ignores these options) instead of failing at compile time.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
export interface SyncMachineAccount extends SourceRecord {
|
|
22
|
+
email: string;
|
|
23
|
+
displayName?: string | null;
|
|
24
|
+
/** Declared by the loaders ('active') and patched by onSourceRemoved ('deactivated'). */
|
|
25
|
+
status?: string | null;
|
|
26
|
+
/** Runtime-owned: never declared, must survive every boot sync (the credential stand-in). */
|
|
27
|
+
runtimeNote?: string | null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** The machine-account shape: natural-key adoption by email, removed rows flagged not deleted. */
|
|
31
|
+
export class SyncMachineAccountTable extends Table<SyncMachineAccount> {
|
|
32
|
+
name = 'db_test_sync_machine_account';
|
|
33
|
+
columns = withSourceRecordColumns<SyncMachineAccount>({
|
|
34
|
+
email: new StringColumn('email', {
|
|
35
|
+
unique: { unique: true, indexName: 'db_test_sync_machine_account_email_unique' },
|
|
36
|
+
}),
|
|
37
|
+
displayName: new StringColumn('display_name'),
|
|
38
|
+
status: new StringColumn('status'),
|
|
39
|
+
runtimeNote: new StringColumn('runtime_note'),
|
|
40
|
+
});
|
|
41
|
+
sourceRecordOptions = {
|
|
42
|
+
naturalKey: 'email',
|
|
43
|
+
onSourceRemoved: { update: { status: 'deactivated' } },
|
|
44
|
+
} as Table<SyncMachineAccount>['sourceRecordOptions'];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface SyncDefaultPolicyRecord extends SourceRecord {
|
|
48
|
+
email: string;
|
|
49
|
+
displayName?: string | null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Default options: id-keyed, removed source rows are deleted (today's behavior). */
|
|
53
|
+
export class SyncDefaultPolicyTable extends Table<SyncDefaultPolicyRecord> {
|
|
54
|
+
name = 'db_test_sync_default_policy';
|
|
55
|
+
columns = withSourceRecordColumns<SyncDefaultPolicyRecord>({
|
|
56
|
+
email: new StringColumn('email'),
|
|
57
|
+
displayName: new StringColumn('display_name'),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface DupePreflightRecord extends DbRecord {
|
|
62
|
+
email: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Generation 1: no uniqueness — the table under which duplicate rows accumulate. */
|
|
66
|
+
export class DupePreflightTable extends Table<DupePreflightRecord> {
|
|
67
|
+
name = 'db_test_dupe_preflight';
|
|
68
|
+
columns = withRecordColumns<DupePreflightRecord>({
|
|
69
|
+
email: new StringColumn('email'),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Generation 2: same table, email now unique — loading it runs the alter-path preflight. */
|
|
74
|
+
export class DupePreflightUniqueEmailTable extends Table<DupePreflightRecord> {
|
|
75
|
+
name = 'db_test_dupe_preflight';
|
|
76
|
+
columns = withRecordColumns<DupePreflightRecord>({
|
|
77
|
+
email: new StringColumn('email', { unique: { unique: true, indexName: 'db_test_dupe_preflight_email_unique' } }),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export const sourceRecordSyncTestTables = {
|
|
82
|
+
SyncMachineAccount: new SyncMachineAccountTable() as Table<SyncMachineAccount>,
|
|
83
|
+
SyncDefaultPolicy: new SyncDefaultPolicyTable() as Table<SyncDefaultPolicyRecord>,
|
|
84
|
+
};
|