@proteinjs/db 1.19.0 → 1.20.1

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.
Files changed (105) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/generated/index.js +1 -1
  3. package/dist/generated/index.js.map +1 -1
  4. package/dist/generated/test/index.d.ts +1 -1
  5. package/dist/generated/test/index.d.ts.map +1 -1
  6. package/dist/generated/test/index.js +52 -34
  7. package/dist/generated/test/index.js.map +1 -1
  8. package/dist/index.d.ts +0 -6
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +0 -6
  11. package/dist/index.js.map +1 -1
  12. package/dist/src/Db.d.ts +2 -2
  13. package/dist/src/Db.d.ts.map +1 -1
  14. package/dist/src/Db.js +6 -3
  15. package/dist/src/Db.js.map +1 -1
  16. package/dist/src/TableWatcherRunner.d.ts.map +1 -1
  17. package/dist/src/TableWatcherRunner.js +4 -1
  18. package/dist/src/TableWatcherRunner.js.map +1 -1
  19. package/dist/src/schema/TableManager.d.ts.map +1 -1
  20. package/dist/src/schema/TableManager.js +4 -1
  21. package/dist/src/schema/TableManager.js.map +1 -1
  22. package/dist/test/index.d.ts +13 -0
  23. package/dist/test/index.d.ts.map +1 -0
  24. package/dist/test/index.js +29 -0
  25. package/dist/test/index.js.map +1 -0
  26. package/dist/test/reusable/CascadeDeleteTests.d.ts +1 -189
  27. package/dist/test/reusable/CascadeDeleteTests.d.ts.map +1 -1
  28. package/dist/test/reusable/CascadeDeleteTests.js +36 -393
  29. package/dist/test/reusable/CascadeDeleteTests.js.map +1 -1
  30. package/dist/test/reusable/ColumnTypesTests.d.ts +1 -52
  31. package/dist/test/reusable/ColumnTypesTests.d.ts.map +1 -1
  32. package/dist/test/reusable/ColumnTypesTests.js +20 -86
  33. package/dist/test/reusable/ColumnTypesTests.js.map +1 -1
  34. package/dist/test/reusable/CrudTests.d.ts +1 -50
  35. package/dist/test/reusable/CrudTests.d.ts.map +1 -1
  36. package/dist/test/reusable/CrudTests.js +37 -126
  37. package/dist/test/reusable/CrudTests.js.map +1 -1
  38. package/dist/test/reusable/DynamicReferenceColumnTests.d.ts +3 -0
  39. package/dist/test/reusable/DynamicReferenceColumnTests.d.ts.map +1 -0
  40. package/dist/test/reusable/DynamicReferenceColumnTests.js +429 -0
  41. package/dist/test/reusable/DynamicReferenceColumnTests.js.map +1 -0
  42. package/dist/test/reusable/TableManagerTests.d.ts +1 -2
  43. package/dist/test/reusable/TableManagerTests.d.ts.map +1 -1
  44. package/dist/test/reusable/TableManagerTests.js +57 -152
  45. package/dist/test/reusable/TableManagerTests.js.map +1 -1
  46. package/dist/test/reusable/TransactionTests.d.ts +1 -51
  47. package/dist/test/reusable/TransactionTests.d.ts.map +1 -1
  48. package/dist/test/reusable/TransactionTests.js +24 -111
  49. package/dist/test/reusable/TransactionTests.js.map +1 -1
  50. package/dist/test/util/DbTestEnvironment.d.ts +12 -0
  51. package/dist/test/util/DbTestEnvironment.d.ts.map +1 -0
  52. package/dist/test/util/DbTestEnvironment.js +125 -0
  53. package/dist/test/util/DbTestEnvironment.js.map +1 -0
  54. package/dist/test/util/tables/cascadeDeleteTestTables.d.ts +191 -0
  55. package/dist/test/util/tables/cascadeDeleteTestTables.d.ts.map +1 -0
  56. package/dist/test/util/tables/cascadeDeleteTestTables.js +234 -0
  57. package/dist/test/util/tables/cascadeDeleteTestTables.js.map +1 -0
  58. package/dist/test/util/tables/columnTypesTestTables.d.ts +47 -0
  59. package/dist/test/util/tables/columnTypesTestTables.d.ts.map +1 -0
  60. package/dist/test/util/tables/columnTypesTestTables.js +49 -0
  61. package/dist/test/util/tables/columnTypesTestTables.js.map +1 -0
  62. package/dist/test/util/tables/crudTestTables.d.ts +48 -0
  63. package/dist/test/util/tables/crudTestTables.d.ts.map +1 -0
  64. package/dist/test/util/tables/crudTestTables.js +58 -0
  65. package/dist/test/util/tables/crudTestTables.js.map +1 -0
  66. package/dist/test/util/tables/dynamicReferenceColumnTestTables.d.ts +76 -0
  67. package/dist/test/util/tables/dynamicReferenceColumnTestTables.d.ts.map +1 -0
  68. package/dist/test/util/tables/dynamicReferenceColumnTestTables.js +131 -0
  69. package/dist/test/util/tables/dynamicReferenceColumnTestTables.js.map +1 -0
  70. package/dist/test/util/tables/tableManagerTestTables.d.ts +86 -0
  71. package/dist/test/util/tables/tableManagerTestTables.d.ts.map +1 -0
  72. package/dist/test/util/tables/tableManagerTestTables.js +131 -0
  73. package/dist/test/util/tables/tableManagerTestTables.js.map +1 -0
  74. package/dist/test/util/tables/transactionTestTables.d.ts +48 -0
  75. package/dist/test/util/tables/transactionTestTables.d.ts.map +1 -0
  76. package/dist/test/util/tables/transactionTestTables.js +58 -0
  77. package/dist/test/util/tables/transactionTestTables.js.map +1 -0
  78. package/generated/index.ts +18 -15
  79. package/generated/test/index.ts +67 -46
  80. package/index.ts +0 -7
  81. package/package.json +29 -17
  82. package/src/Db.ts +8 -3
  83. package/src/TableWatcherRunner.ts +4 -1
  84. package/src/schema/TableManager.ts +4 -1
  85. package/test/index.ts +13 -0
  86. package/test/reusable/CascadeDeleteTests.ts +38 -320
  87. package/test/reusable/ColumnTypesTests.ts +9 -85
  88. package/test/reusable/CrudTests.ts +26 -97
  89. package/test/reusable/DynamicReferenceColumnTests.ts +342 -0
  90. package/test/reusable/TableManagerTests.ts +18 -97
  91. package/test/reusable/TransactionTests.ts +26 -93
  92. package/test/util/DbTestEnvironment.ts +46 -0
  93. package/test/util/tables/cascadeDeleteTestTables.ts +232 -0
  94. package/test/util/tables/columnTypesTestTables.ts +63 -0
  95. package/test/util/tables/crudTestTables.ts +44 -0
  96. package/test/util/tables/dynamicReferenceColumnTestTables.ts +87 -0
  97. package/test/util/tables/tableManagerTestTables.ts +98 -0
  98. package/test/util/tables/transactionTestTables.ts +44 -0
  99. package/tsconfig.json +7 -1
  100. package/LICENSE +0 -21
  101. package/dist/test/reusable/DynamicReferenceColumn.d.ts +0 -77
  102. package/dist/test/reusable/DynamicReferenceColumn.d.ts.map +0 -1
  103. package/dist/test/reusable/DynamicReferenceColumn.js +0 -656
  104. package/dist/test/reusable/DynamicReferenceColumn.js.map +0 -1
  105. package/test/reusable/DynamicReferenceColumn.ts +0 -487
package/index.ts CHANGED
@@ -25,11 +25,4 @@ export * from './src/services/DbService';
25
25
  export * from './src/services/MigrationRunnerService';
26
26
  export * from './src/services/TransactionRunnerService';
27
27
 
28
- export * from './test/reusable/TableManagerTests';
29
- export * from './test/reusable/CrudTests';
30
- export * from './test/reusable/ColumnTypesTests';
31
- export * from './test/reusable/DynamicReferenceColumn';
32
- export * from './test/reusable/TransactionTests';
33
- export * from './test/reusable/CascadeDeleteTests';
34
-
35
28
  export * from '@proteinjs/db-query';
package/package.json CHANGED
@@ -1,6 +1,25 @@
1
1
  {
2
2
  "name": "@proteinjs/db",
3
- "version": "1.19.0",
3
+ "version": "1.20.1",
4
+ "main": "./dist/generated/index.js",
5
+ "types": "./dist/generated/index.d.ts",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/generated/index.d.ts",
9
+ "default": "./dist/generated/index.js"
10
+ },
11
+ "./test": {
12
+ "types": "./dist/generated/test/index.d.ts",
13
+ "default": "./dist/generated/test/index.js"
14
+ }
15
+ },
16
+ "typesVersions": {
17
+ "*": {
18
+ "test": [
19
+ "dist/generated/test/index.d.ts"
20
+ ]
21
+ }
22
+ },
4
23
  "description": "Db",
5
24
  "publishConfig": {
6
25
  "access": "public"
@@ -17,24 +36,24 @@
17
36
  "license": "MIT",
18
37
  "scripts": {
19
38
  "clean": "rm -rf dist/ node_modules/ generated/",
20
- "build": "reflection-build && REFLECTION_SOURCE_DIRS=test,src reflection-build && tsc",
39
+ "build": "reflection-build && REFLECTION_SOURCE_DIRS=test,src REFLECTION_EXPORT_FROM=test/index.ts reflection-build && tsc",
21
40
  "watch": "reflection-watch",
22
41
  "test": "jest"
23
42
  },
24
43
  "dependencies": {
25
- "@proteinjs/db-query": "^1.4.0",
26
- "@proteinjs/logger": "1.0.11",
44
+ "@proteinjs/db-query": "^1.4.1",
45
+ "@proteinjs/logger": "1.0.12",
27
46
  "@proteinjs/reflection": "1.1.10",
28
- "@proteinjs/serializer": "1.1.1",
29
- "@proteinjs/server-api": "2.0.1",
30
- "@proteinjs/service": "1.2.7",
31
- "@proteinjs/user-auth": "1.1.6",
47
+ "@proteinjs/serializer": "1.1.2",
48
+ "@proteinjs/server-api": "2.0.2",
49
+ "@proteinjs/service": "1.2.8",
50
+ "@proteinjs/user-auth": "1.1.7",
32
51
  "@proteinjs/util": "1.5.0",
33
52
  "moment": "2.29.4",
34
53
  "uuid": "8.3.0"
35
54
  },
36
55
  "devDependencies": {
37
- "@proteinjs/reflection-build": "1.3.0",
56
+ "@proteinjs/reflection-build": "1.4.1",
38
57
  "@types/jest": "29.5.5",
39
58
  "@types/node": "14.0.27",
40
59
  "@types/uuid": "8.3.0",
@@ -46,12 +65,5 @@
46
65
  "jest": "29.7.0",
47
66
  "ts-jest": "29.1.1",
48
67
  "typescript": "5.2.2"
49
- },
50
- "main": "./dist/generated/index.js",
51
- "types": "./dist/generated/index.d.ts",
52
- "exports": {
53
- ".": "./dist/generated/index.js",
54
- "./test": "./dist/generated/test/index.js"
55
- },
56
- "gitHead": "5f31f973e8ce8d8810b344b15c22ec0b99018a06"
68
+ }
57
69
  }
package/src/Db.ts CHANGED
@@ -33,6 +33,9 @@ export const getDb = <R extends Record = Record>() =>
33
33
  typeof self === 'undefined' ? new Db<R>() : (getDbService() as Db<R>);
34
34
  export const getDbAsSystem = <R extends Record = Record>() => new Db<R>(undefined, undefined, undefined, true);
35
35
 
36
+ const getEnvVar = (key: string): string | undefined =>
37
+ typeof process !== 'undefined' && process.env ? process.env[key] : undefined;
38
+
36
39
  export type DbDriverQueryStatementConfig = ParameterizationConfig & {
37
40
  prefixTablesWithDb?: boolean;
38
41
  getDriverColumnType?: (tableName: string, columnName: string) => string;
@@ -65,7 +68,8 @@ export interface DbDriver {
65
68
  export class Db<R extends Record = Record> implements DbService<R> {
66
69
  private static defaultDbDriver: DbDriver;
67
70
  private dbDriver: DbDriver;
68
- private logger = new Logger({ name: this.constructor.name });
71
+ private getTable: (tableName: string) => Table<any>;
72
+ private logger = new Logger({ name: this.constructor.name, logLevel: getEnvVar('DB_LOG_LEVEL') as any });
69
73
  private statementConfigFactory: StatementConfigFactory;
70
74
  private auth = new TableAuth();
71
75
  private tableWatcherRunner = new TableWatcherRunner<R>();
@@ -79,11 +83,12 @@ export class Db<R extends Record = Record> implements DbService<R> {
79
83
 
80
84
  constructor(
81
85
  dbDriver?: DbDriver,
82
- private getTable?: (tableName: string) => Table<any>,
86
+ getTable?: (tableName: string) => Table<any>,
83
87
  transactionContextFactory?: DefaultTransactionContextFactory,
84
88
  private runAsSystem: boolean = false
85
89
  ) {
86
90
  this.dbDriver = dbDriver ? dbDriver : Db.getDefaultDbDriver();
91
+ this.getTable = getTable ?? tableByName;
87
92
  this.statementConfigFactory = new StatementConfigFactory(this.dbDriver.getDbName(), getTable);
88
93
  this.transactionContextFactory = transactionContextFactory
89
94
  ? transactionContextFactory
@@ -241,7 +246,7 @@ export class Db<R extends Record = Record> implements DbService<R> {
241
246
  }
242
247
 
243
248
  for (const cascadeDeleteReference of table.cascadeDeleteReferences()) {
244
- const referenceTable = tableByName(cascadeDeleteReference.table);
249
+ const referenceTable = this.getTable(cascadeDeleteReference.table);
245
250
  const referenceColumnPropertyName = getColumnPropertyName(referenceTable, cascadeDeleteReference.referenceColumn);
246
251
  this.logger.info({
247
252
  message: `Executing cascade delete for table: ${table.name}`,
@@ -4,9 +4,12 @@ import { Record } from './Record';
4
4
  import { Table } from './Table';
5
5
  import { QueryBuilder } from '@proteinjs/db-query';
6
6
 
7
+ const getEnvVar = (key: string): string | undefined =>
8
+ typeof process !== 'undefined' && process.env ? process.env[key] : undefined;
9
+
7
10
  export class TableWatcherRunner<R extends Record = Record> {
8
11
  private static tableWatcherMap: TableWatcherMap;
9
- private logger = new Logger({ name: this.constructor.name });
12
+ private logger = new Logger({ name: this.constructor.name, logLevel: getEnvVar('DB_LOG_LEVEL') as any });
10
13
 
11
14
  constructor() {
12
15
  if (!TableWatcherRunner.tableWatcherMap) {
@@ -5,12 +5,15 @@ import { SchemaMetadata } from './SchemaMetadata';
5
5
  import { DbDriver } from '../Db';
6
6
  import { DynamicReferenceColumn, DynamicReferenceTableNameColumn } from '../Columns';
7
7
 
8
+ const getEnvVar = (key: string): string | undefined =>
9
+ typeof process !== 'undefined' && process.env ? process.env[key] : undefined;
10
+
8
11
  export interface ColumnTypeFactory {
9
12
  getType(column: Column<any, any>): string;
10
13
  }
11
14
 
12
15
  export class TableManager {
13
- private logger = new Logger({ name: this.constructor.name });
16
+ private logger = new Logger({ name: this.constructor.name, logLevel: getEnvVar('DB_LOG_LEVEL') as any });
14
17
  public columnTypeFactory: ColumnTypeFactory;
15
18
  public schemaOperations: SchemaOperations;
16
19
  public schemaMetadata: SchemaMetadata;
package/test/index.ts ADDED
@@ -0,0 +1,13 @@
1
+ export * from './reusable/TableManagerTests';
2
+ export * from './reusable/CrudTests';
3
+ export * from './reusable/ColumnTypesTests';
4
+ export * from './reusable/DynamicReferenceColumnTests';
5
+ export * from './reusable/TransactionTests';
6
+ export * from './reusable/CascadeDeleteTests';
7
+
8
+ export * from './util/tables/cascadeDeleteTestTables';
9
+ export * from './util/tables/columnTypesTestTables';
10
+ export * from './util/tables/crudTestTables';
11
+ export * from './util/tables/dynamicReferenceColumnTestTables';
12
+ export * from './util/tables/tableManagerTestTables';
13
+ export * from './util/tables/transactionTestTables';
@@ -4,261 +4,29 @@ import {
4
4
  ReferenceArrayColumn,
5
5
  DynamicReferenceColumn,
6
6
  DynamicReferenceTableNameColumn,
7
- } from '../../src/Columns';
8
- import { Db, DbDriver } from '../../src/Db';
9
- import { Table } from '../../src/Table';
10
- import { withRecordColumns, Record } from '../../src/Record';
11
- import { Reference } from '../../src/reference/Reference';
12
- import { ReferenceArray } from '../../src/reference/ReferenceArray';
7
+ Db,
8
+ DbDriver,
9
+ Table,
10
+ withRecordColumns,
11
+ Record,
12
+ Reference,
13
+ ReferenceArray,
14
+ DefaultTransactionContextFactory,
15
+ } from '@proteinjs/db';
13
16
  import { QueryBuilder } from '@proteinjs/db-query';
14
- import { DefaultTransactionContextFactory } from '../../src/transaction/TransactionContextFactory';
15
-
16
- /**
17
- * ---------- Test Entities ----------
18
- * (Isolated per scenario so we never mount multiple cascade columns
19
- * to the same target on a single table.)
20
- */
21
-
22
- // --- Cascade: ReferenceColumn (GroupRef -> MemberRef)
23
- interface MemberRef extends Record {
24
- name: string;
25
- }
26
- interface GroupRef extends Record {
27
- groupName: string;
28
- memberRef?: Reference<MemberRef> | null;
29
- }
30
-
31
- // --- Cascade: ReferenceArrayColumn (GroupArr -> MemberArr[])
32
- interface MemberArr extends Record {
33
- name: string;
34
- }
35
- interface GroupArr extends Record {
36
- groupName: string;
37
- memberRefs?: ReferenceArray<MemberArr> | null;
38
- }
39
-
40
- // --- Cascade: DynamicReferenceColumn (GroupDyn -> MemberDyn)
41
- interface MemberDyn extends Record {
42
- name: string;
43
- }
44
- interface GroupDyn extends Record {
45
- groupName: string;
46
- memberDynTableName?: string | null;
47
- memberDynRef?: Reference<MemberDyn> | null;
48
- }
49
-
50
- // --- Reverse: ReferenceColumn (Comment -> Post)
51
- interface Post extends Record {
52
- title: string;
53
- }
54
- interface Comment extends Record {
55
- text: string;
56
- postRef?: Reference<Post> | null;
57
- }
58
-
59
- // --- Reverse: ReferenceArrayColumn (GroupArrRev -> MemberArrRev[])
60
- interface MemberArrRev extends Record {
61
- name: string;
62
- }
63
- interface GroupArrRev extends Record {
64
- groupName: string;
65
- memberRefs?: ReferenceArray<MemberArrRev> | null;
66
- }
67
-
68
- // --- Reverse: DynamicReferenceColumn (Task -> Worker)
69
- interface Worker extends Record {
70
- name: string;
71
- }
72
- interface Task extends Record {
73
- title: string;
74
- assigneeTableName?: string | null;
75
- assigneeRef?: Reference<Worker> | null;
76
- }
77
-
78
- /**
79
- * ---------- Table Names ----------
80
- */
81
- // Cascade (ReferenceColumn)
82
- const MEMBER_REF_TABLE = 'db_test_cd_members_ref';
83
- const GROUP_REF_TABLE = 'db_test_cd_groups_ref';
84
-
85
- // Cascade (ReferenceArrayColumn)
86
- const MEMBER_ARR_TABLE = 'db_test_cd_members_arr';
87
- const GROUP_ARR_TABLE = 'db_test_cd_groups_arr';
88
-
89
- // Cascade (DynamicReferenceColumn)
90
- const MEMBER_DYN_TABLE = 'db_test_cd_members_dyn';
91
- const GROUP_DYN_TABLE = 'db_test_cd_groups_dyn';
92
-
93
- // Reverse (ReferenceColumn)
94
- const POST_TABLE = 'db_test_cd_posts';
95
- const COMMENT_TABLE = 'db_test_cd_comments';
96
-
97
- // Reverse (ReferenceArrayColumn)
98
- const MEMBER_ARR_REV_TABLE = 'db_test_cd_members_arr_rev';
99
- const GROUP_ARR_REV_TABLE = 'db_test_cd_groups_arr_rev';
100
-
101
- // Reverse (DynamicReferenceColumn)
102
- const WORKER_TABLE = 'db_test_cd_workers';
103
- const TASK_TABLE = 'db_test_cd_tasks';
104
-
105
- /**
106
- * ---------- Table Classes ----------
107
- */
108
- // Cascade: ReferenceColumn
109
- export class MemberRefTable extends Table<MemberRef> {
110
- name = MEMBER_REF_TABLE;
111
- columns = withRecordColumns<MemberRef>({
112
- name: new StringColumn('name'),
113
- });
114
- }
115
- export class GroupRefTable extends Table<GroupRef> {
116
- name = GROUP_REF_TABLE;
117
- columns = withRecordColumns<GroupRef>({
118
- groupName: new StringColumn('group_name'),
119
- memberRef: new ReferenceColumn<MemberRef>(
120
- 'member_id',
121
- MEMBER_REF_TABLE,
122
- true // cascade: deleting GroupRef deletes the referenced MemberRef
123
- ),
124
- });
125
- }
126
-
127
- // Cascade: ReferenceArrayColumn
128
- export class MemberArrTable extends Table<MemberArr> {
129
- name = MEMBER_ARR_TABLE;
130
- columns = withRecordColumns<MemberArr>({
131
- name: new StringColumn('name'),
132
- });
133
- }
134
- export class GroupArrTable extends Table<GroupArr> {
135
- name = GROUP_ARR_TABLE;
136
- columns = withRecordColumns<GroupArr>({
137
- groupName: new StringColumn('group_name'),
138
- memberRefs: new ReferenceArrayColumn<MemberArr>(
139
- 'member_ids',
140
- MEMBER_ARR_TABLE,
141
- true // cascade: deleting GroupArr deletes all referenced MemberArr
142
- ),
143
- });
144
- }
145
-
146
- // Cascade: DynamicReferenceColumn
147
- export class MemberDynTable extends Table<MemberDyn> {
148
- name = MEMBER_DYN_TABLE;
149
- columns = withRecordColumns<MemberDyn>({
150
- name: new StringColumn('name'),
151
- });
152
- }
153
- export class GroupDynTable extends Table<GroupDyn> {
154
- name = GROUP_DYN_TABLE;
155
- columns = withRecordColumns<GroupDyn>({
156
- groupName: new StringColumn('group_name'),
157
- memberDynTableName: new DynamicReferenceTableNameColumn('member_dyn_table_name', 'member_dyn_ref'),
158
- memberDynRef: new DynamicReferenceColumn<MemberDyn>(
159
- 'member_dyn_ref',
160
- 'member_dyn_table_name',
161
- true // cascade: deleting GroupDyn deletes dynamically referenced MemberDyn
162
- ),
163
- });
164
- }
165
-
166
- // Reverse: ReferenceColumn
167
- export class PostTable extends Table<Post> {
168
- name = POST_TABLE;
169
- columns = withRecordColumns<Post>({
170
- title: new StringColumn('title'),
171
- });
172
- }
173
- export class CommentTable extends Table<Comment> {
174
- name = COMMENT_TABLE;
175
- columns = withRecordColumns<Comment>({
176
- text: new StringColumn('text'),
177
- postRef: new ReferenceColumn<Post>(
178
- 'post_id',
179
- POST_TABLE,
180
- false,
181
- { reverseCascadeDelete: true } // reverse: deleting Post deletes Comment
182
- ),
183
- });
184
- }
185
-
186
- // Reverse: ReferenceArrayColumn
187
- export class MemberArrRevTable extends Table<MemberArrRev> {
188
- name = MEMBER_ARR_REV_TABLE;
189
- columns = withRecordColumns<MemberArrRev>({
190
- name: new StringColumn('name'),
191
- });
192
- }
193
- export class GroupArrRevTable extends Table<GroupArrRev> {
194
- name = GROUP_ARR_REV_TABLE;
195
- columns = withRecordColumns<GroupArrRev>({
196
- groupName: new StringColumn('group_name'),
197
- memberRefs: new ReferenceArrayColumn<MemberArrRev>(
198
- 'member_ids',
199
- MEMBER_ARR_REV_TABLE,
200
- false,
201
- { reverseCascadeDelete: true } // reverse: deleting any MemberArrRev deletes the GroupArrRev
202
- ),
203
- });
204
- }
205
-
206
- // Reverse: DynamicReferenceColumn
207
- export class WorkerTable extends Table<Worker> {
208
- name = WORKER_TABLE;
209
- columns = withRecordColumns<Worker>({
210
- name: new StringColumn('name'),
211
- });
212
- }
213
- export class TaskTable extends Table<Task> {
214
- name = TASK_TABLE;
215
- columns = withRecordColumns<Task>({
216
- title: new StringColumn('title'),
217
- assigneeTableName: new DynamicReferenceTableNameColumn('assignee_table_name', 'assignee_ref'),
218
- assigneeRef: new DynamicReferenceColumn<Worker>(
219
- 'assignee_ref',
220
- 'assignee_table_name',
221
- false,
222
- { reverseCascadeDelete: true } // reverse: deleting Worker deletes Task
223
- ),
224
- });
225
- }
226
-
227
- /** getTable resolver for Db */
228
- export const getCascadeDeleteTestTable = (tableName: string) => {
229
- switch (tableName) {
230
- // Cascade
231
- case MEMBER_REF_TABLE:
232
- return new MemberRefTable();
233
- case GROUP_REF_TABLE:
234
- return new GroupRefTable();
235
- case MEMBER_ARR_TABLE:
236
- return new MemberArrTable();
237
- case GROUP_ARR_TABLE:
238
- return new GroupArrTable();
239
- case MEMBER_DYN_TABLE:
240
- return new MemberDynTable();
241
- case GROUP_DYN_TABLE:
242
- return new GroupDynTable();
243
-
244
- // Reverse
245
- case POST_TABLE:
246
- return new PostTable();
247
- case COMMENT_TABLE:
248
- return new CommentTable();
249
- case MEMBER_ARR_REV_TABLE:
250
- return new MemberArrRevTable();
251
- case GROUP_ARR_REV_TABLE:
252
- return new GroupArrRevTable();
253
- case WORKER_TABLE:
254
- return new WorkerTable();
255
- case TASK_TABLE:
256
- return new TaskTable();
257
-
258
- default:
259
- throw new Error(`Cannot find test table: ${tableName}`);
260
- }
261
- };
17
+ import { DbTestEnvironment } from '../util/DbTestEnvironment';
18
+ import {
19
+ cascadeDeleteTestTables,
20
+ GroupArr,
21
+ GroupDyn,
22
+ GroupRef,
23
+ MemberArr,
24
+ MemberArrRev,
25
+ MemberDyn,
26
+ MemberRef,
27
+ Post,
28
+ Worker,
29
+ } from '../util/tables/cascadeDeleteTestTables';
262
30
 
263
31
  /**
264
32
  * Public test suite factory.
@@ -269,69 +37,19 @@ export const cascadeDeleteTests = (
269
37
  dropTable: (table: Table<any>) => Promise<void>
270
38
  ) => {
271
39
  return () => {
272
- const db = new Db(driver, getCascadeDeleteTestTable, transactionContextFactory);
273
-
274
- beforeAll(async () => {
275
- if (driver.start) {
276
- await driver.start();
277
- }
278
- });
279
-
280
- beforeEach(async () => {
281
- // Ensure tables exist and are in a known state for each test
282
- await driver.getTableManager().loadTable(new MemberRefTable());
283
- await driver.getTableManager().loadTable(new GroupRefTable());
284
-
285
- await driver.getTableManager().loadTable(new MemberArrTable());
286
- await driver.getTableManager().loadTable(new GroupArrTable());
287
-
288
- await driver.getTableManager().loadTable(new MemberDynTable());
289
- await driver.getTableManager().loadTable(new GroupDynTable());
290
-
291
- await driver.getTableManager().loadTable(new PostTable());
292
- await driver.getTableManager().loadTable(new CommentTable());
40
+ const db = new Db(driver, undefined, transactionContextFactory);
41
+ const testEnv = new DbTestEnvironment(driver, dropTable);
293
42
 
294
- await driver.getTableManager().loadTable(new MemberArrRevTable());
295
- await driver.getTableManager().loadTable(new GroupArrRevTable());
296
-
297
- await driver.getTableManager().loadTable(new WorkerTable());
298
- await driver.getTableManager().loadTable(new TaskTable());
299
- });
300
-
301
- afterEach(async () => {
302
- // Drop referencing tables first, then referenced
303
- await dropTable(new GroupRefTable());
304
- await dropTable(new MemberRefTable());
305
-
306
- await dropTable(new GroupArrTable());
307
- await dropTable(new MemberArrTable());
308
-
309
- await dropTable(new GroupDynTable());
310
- await dropTable(new MemberDynTable());
311
-
312
- await dropTable(new CommentTable());
313
- await dropTable(new PostTable());
314
-
315
- await dropTable(new GroupArrRevTable());
316
- await dropTable(new MemberArrRevTable());
317
-
318
- await dropTable(new TaskTable());
319
- await dropTable(new WorkerTable());
320
- });
321
-
322
- afterAll(async () => {
323
- if (driver.stop) {
324
- await driver.stop();
325
- }
326
- });
43
+ beforeAll(async () => await testEnv.beforeAll(), 10000);
44
+ afterAll(async () => await testEnv.afterAll(), 10000);
327
45
 
328
46
  /**
329
47
  * -------------------- Cascade Delete (holder → referenced) --------------------
330
48
  */
331
49
  describe('Cascade Delete', () => {
332
50
  test('ReferenceColumn: deleting holder deletes referenced record', async () => {
333
- const memberTable = new MemberRefTable();
334
- const groupTable = new GroupRefTable();
51
+ const memberTable = cascadeDeleteTestTables.MemberRef;
52
+ const groupTable = cascadeDeleteTestTables.GroupRef;
335
53
 
336
54
  const m = await db.insert(memberTable, { name: 'Alice' });
337
55
  const g = await db.insert(groupTable, {
@@ -352,8 +70,8 @@ export const cascadeDeleteTests = (
352
70
  });
353
71
 
354
72
  test('ReferenceArrayColumn: deleting holder deletes all referenced records', async () => {
355
- const memberTable = new MemberArrTable();
356
- const groupTable = new GroupArrTable();
73
+ const memberTable = cascadeDeleteTestTables.MemberArr;
74
+ const groupTable = cascadeDeleteTestTables.GroupArr;
357
75
 
358
76
  const m1 = await db.insert(memberTable, { name: 'Bob' });
359
77
  const m2 = await db.insert(memberTable, { name: 'Charlie' });
@@ -378,8 +96,8 @@ export const cascadeDeleteTests = (
378
96
  });
379
97
 
380
98
  test('DynamicReferenceColumn: deleting holder deletes dynamically referenced record', async () => {
381
- const memberTable = new MemberDynTable();
382
- const groupTable = new GroupDynTable();
99
+ const memberTable = cascadeDeleteTestTables.MemberDyn;
100
+ const groupTable = cascadeDeleteTestTables.GroupDyn;
383
101
 
384
102
  const m = await db.insert(memberTable, { name: 'Dina' });
385
103
  const g = await db.insert(groupTable, {
@@ -406,8 +124,8 @@ export const cascadeDeleteTests = (
406
124
  */
407
125
  describe('Reverse Cascade Delete', () => {
408
126
  test('ReferenceColumn: deleting referenced record deletes the holder', async () => {
409
- const postTable = new PostTable();
410
- const commentTable = new CommentTable();
127
+ const postTable = cascadeDeleteTestTables.Post;
128
+ const commentTable = cascadeDeleteTestTables.Comment;
411
129
 
412
130
  const post = await db.insert(postTable, { title: 'Hello World' });
413
131
  await db.insert(commentTable, {
@@ -428,8 +146,8 @@ export const cascadeDeleteTests = (
428
146
  });
429
147
 
430
148
  test('ReferenceArrayColumn: deleting a referenced record deletes the holder', async () => {
431
- const memberTable = new MemberArrRevTable();
432
- const groupTable = new GroupArrRevTable();
149
+ const memberTable = cascadeDeleteTestTables.MemberArrRev;
150
+ const groupTable = cascadeDeleteTestTables.GroupArrRev;
433
151
 
434
152
  const m1 = await db.insert(memberTable, { name: 'Alice' });
435
153
  const m2 = await db.insert(memberTable, { name: 'Bob' });
@@ -452,8 +170,8 @@ export const cascadeDeleteTests = (
452
170
  });
453
171
 
454
172
  test('DynamicReferenceColumn: deleting referenced record deletes the holder', async () => {
455
- const workerTable = new WorkerTable();
456
- const taskTable = new TaskTable();
173
+ const workerTable = cascadeDeleteTestTables.Worker;
174
+ const taskTable = cascadeDeleteTestTables.Task;
457
175
 
458
176
  const worker = await db.insert(workerTable, { name: 'Wally Worker' });
459
177
  await db.insert(taskTable, {