@chidchanun/bcp 0.2.2 → 0.2.4
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/README.md +117 -121
- package/docs/api-manifest.json +2 -2
- package/docs/api-reference.md +21 -2
- package/docs/application-packaging.md +243 -0
- package/docs/database-migrations.md +79 -19
- package/docs/database.md +197 -28
- package/docs/deployment.md +94 -7
- package/docs/docs-web-manifest.json +7 -4
- package/docs/platform-manifest.json +24 -5
- package/docs/releases/0.2.3.md +77 -0
- package/docs/releases/0.2.4.md +152 -0
- package/package.json +1 -1
- package/packages/cli/src/application-packaging.ts +1162 -0
- package/packages/cli/src/args.ts +2 -0
- package/packages/cli/src/bootstrap.ts +1 -0
- package/packages/cli/src/database-migrations.ts +91 -21
- package/packages/cli/src/index.ts +60 -2
- package/packages/client/src/database-mysql.ts +291 -0
- package/packages/client/src/database-postgresql.ts +355 -0
- package/packages/client/src/database-sqlite.ts +445 -0
- package/packages/client/src/database.mjs +709 -57
- package/packages/client/src/database.ts +347 -182
|
@@ -1,7 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
createMysqlDatabaseAdapter,
|
|
3
|
+
} from "./database-mysql.js";
|
|
4
|
+
import {
|
|
5
|
+
createPostgresqlDatabaseAdapter,
|
|
6
|
+
} from "./database-postgresql.js";
|
|
7
|
+
import {
|
|
8
|
+
createSqliteDatabaseAdapter,
|
|
9
|
+
} from "./database-sqlite.js";
|
|
10
|
+
|
|
11
|
+
export type DatabaseDriver =
|
|
12
|
+
| "mysql"
|
|
13
|
+
| "postgresql"
|
|
14
|
+
| "sqlite";
|
|
15
|
+
|
|
16
|
+
export interface DatabaseConnectionOptions {
|
|
4
17
|
driver?: DatabaseDriver;
|
|
18
|
+
url?: string;
|
|
5
19
|
host?: string;
|
|
6
20
|
port?: number;
|
|
7
21
|
user?: string;
|
|
@@ -28,44 +42,62 @@ export interface TransactionDatabase {
|
|
|
28
42
|
): Promise<T>;
|
|
29
43
|
}
|
|
30
44
|
|
|
31
|
-
interface
|
|
32
|
-
|
|
45
|
+
export interface ResolvedDatabaseOptions
|
|
46
|
+
extends Required<
|
|
47
|
+
Omit<
|
|
48
|
+
DatabaseConnectionOptions,
|
|
49
|
+
"url"
|
|
50
|
+
>
|
|
51
|
+
> {
|
|
52
|
+
url?: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface DatabaseAdapter {
|
|
56
|
+
readonly driver: string;
|
|
57
|
+
connect(): Promise<void>;
|
|
58
|
+
query<T = unknown>(
|
|
33
59
|
sql: string,
|
|
34
60
|
parameters?: DatabaseParameters
|
|
35
|
-
): Promise<
|
|
36
|
-
execute(
|
|
61
|
+
): Promise<T>;
|
|
62
|
+
execute<T = unknown>(
|
|
37
63
|
sql: string,
|
|
38
64
|
parameters?: DatabaseParameters
|
|
39
|
-
): Promise<
|
|
65
|
+
): Promise<T>;
|
|
66
|
+
transaction<T>(
|
|
67
|
+
callback: (
|
|
68
|
+
database: TransactionDatabase
|
|
69
|
+
) => Promise<T>
|
|
70
|
+
): Promise<T>;
|
|
71
|
+
disconnect(): Promise<void>;
|
|
40
72
|
}
|
|
41
73
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
release(): void;
|
|
47
|
-
}
|
|
74
|
+
export type DatabaseAdapterFactory =
|
|
75
|
+
() =>
|
|
76
|
+
| DatabaseAdapter
|
|
77
|
+
| Promise<DatabaseAdapter>;
|
|
48
78
|
|
|
49
|
-
interface
|
|
50
|
-
|
|
51
|
-
|
|
79
|
+
export interface DatabaseOptions
|
|
80
|
+
extends DatabaseConnectionOptions {
|
|
81
|
+
adapter?:
|
|
82
|
+
| DatabaseAdapter
|
|
83
|
+
| DatabaseAdapterFactory;
|
|
52
84
|
}
|
|
53
85
|
|
|
54
|
-
interface
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
86
|
+
interface DriverDefaults {
|
|
87
|
+
host: string;
|
|
88
|
+
port: number;
|
|
89
|
+
user: string;
|
|
90
|
+
database: string;
|
|
91
|
+
connectionLimit: number;
|
|
92
|
+
charset: string;
|
|
58
93
|
}
|
|
59
94
|
|
|
60
|
-
const MYSQL_MODULE_SPECIFIER =
|
|
61
|
-
"mysql2/promise";
|
|
62
|
-
|
|
63
95
|
export class BcpDatabase {
|
|
64
96
|
private readonly options:
|
|
65
97
|
DatabaseOptions;
|
|
66
98
|
|
|
67
|
-
private
|
|
68
|
-
Promise<
|
|
99
|
+
private adapterPromise:
|
|
100
|
+
Promise<DatabaseAdapter> | null =
|
|
69
101
|
null;
|
|
70
102
|
|
|
71
103
|
constructor(
|
|
@@ -76,38 +108,42 @@ export class BcpDatabase {
|
|
|
76
108
|
};
|
|
77
109
|
}
|
|
78
110
|
|
|
111
|
+
async connect(): Promise<void> {
|
|
112
|
+
await this.getAdapter();
|
|
113
|
+
}
|
|
114
|
+
|
|
79
115
|
async query<T = unknown>(
|
|
80
116
|
sql: string,
|
|
81
117
|
parameters?: DatabaseParameters
|
|
82
118
|
): Promise<T> {
|
|
83
|
-
assertSql(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
await
|
|
89
|
-
sql,
|
|
90
|
-
parameters
|
|
91
|
-
);
|
|
119
|
+
assertSql(
|
|
120
|
+
sql
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
const adapter =
|
|
124
|
+
await this.getAdapter();
|
|
92
125
|
|
|
93
|
-
return
|
|
126
|
+
return adapter.query<T>(
|
|
127
|
+
sql,
|
|
128
|
+
parameters
|
|
129
|
+
);
|
|
94
130
|
}
|
|
95
131
|
|
|
96
132
|
async execute<T = unknown>(
|
|
97
133
|
sql: string,
|
|
98
134
|
parameters?: DatabaseParameters
|
|
99
135
|
): Promise<T> {
|
|
100
|
-
assertSql(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
await
|
|
106
|
-
sql,
|
|
107
|
-
parameters
|
|
108
|
-
);
|
|
136
|
+
assertSql(
|
|
137
|
+
sql
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
const adapter =
|
|
141
|
+
await this.getAdapter();
|
|
109
142
|
|
|
110
|
-
return
|
|
143
|
+
return adapter.execute<T>(
|
|
144
|
+
sql,
|
|
145
|
+
parameters
|
|
146
|
+
);
|
|
111
147
|
}
|
|
112
148
|
|
|
113
149
|
async transaction<T>(
|
|
@@ -115,104 +151,63 @@ export class BcpDatabase {
|
|
|
115
151
|
database: TransactionDatabase
|
|
116
152
|
) => Promise<T>
|
|
117
153
|
): Promise<T> {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
) {
|
|
122
|
-
throw new TypeError(
|
|
123
|
-
"BCP Database: transaction callback must be a function."
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const pool =
|
|
128
|
-
await this.getPool();
|
|
129
|
-
const connection =
|
|
130
|
-
await pool.getConnection();
|
|
131
|
-
|
|
132
|
-
await connection.beginTransaction();
|
|
133
|
-
|
|
134
|
-
const transactionDatabase:
|
|
135
|
-
TransactionDatabase = {
|
|
136
|
-
query: async <R = unknown>(
|
|
137
|
-
sql: string,
|
|
138
|
-
parameters?: DatabaseParameters
|
|
139
|
-
): Promise<R> => {
|
|
140
|
-
assertSql(sql);
|
|
141
|
-
|
|
142
|
-
const [rows] =
|
|
143
|
-
await connection.query(
|
|
144
|
-
sql,
|
|
145
|
-
parameters
|
|
146
|
-
);
|
|
147
|
-
|
|
148
|
-
return rows as R;
|
|
149
|
-
},
|
|
150
|
-
execute: async <R = unknown>(
|
|
151
|
-
sql: string,
|
|
152
|
-
parameters?: DatabaseParameters
|
|
153
|
-
): Promise<R> => {
|
|
154
|
-
assertSql(sql);
|
|
155
|
-
|
|
156
|
-
const [result] =
|
|
157
|
-
await connection.execute(
|
|
158
|
-
sql,
|
|
159
|
-
parameters
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
return result as R;
|
|
163
|
-
},
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
try {
|
|
167
|
-
const result =
|
|
168
|
-
await callback(
|
|
169
|
-
transactionDatabase
|
|
170
|
-
);
|
|
154
|
+
assertTransactionCallback(
|
|
155
|
+
callback
|
|
156
|
+
);
|
|
171
157
|
|
|
172
|
-
|
|
158
|
+
const adapter =
|
|
159
|
+
await this.getAdapter();
|
|
173
160
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
} catch {
|
|
179
|
-
// Preserve the original transaction error.
|
|
180
|
-
}
|
|
161
|
+
return adapter.transaction(
|
|
162
|
+
callback
|
|
163
|
+
);
|
|
164
|
+
}
|
|
181
165
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
connection.release();
|
|
185
|
-
}
|
|
166
|
+
async disconnect(): Promise<void> {
|
|
167
|
+
await this.close();
|
|
186
168
|
}
|
|
187
169
|
|
|
188
170
|
async close(): Promise<void> {
|
|
189
|
-
const
|
|
190
|
-
this.
|
|
171
|
+
const pendingAdapter =
|
|
172
|
+
this.adapterPromise;
|
|
191
173
|
|
|
192
|
-
this.
|
|
174
|
+
this.adapterPromise =
|
|
193
175
|
null;
|
|
194
176
|
|
|
195
|
-
if (!
|
|
177
|
+
if (!pendingAdapter) {
|
|
196
178
|
return;
|
|
197
179
|
}
|
|
198
180
|
|
|
199
|
-
|
|
200
|
-
|
|
181
|
+
let adapter:
|
|
182
|
+
DatabaseAdapter;
|
|
183
|
+
|
|
184
|
+
try {
|
|
185
|
+
adapter =
|
|
186
|
+
await pendingAdapter;
|
|
187
|
+
} catch {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
201
190
|
|
|
202
|
-
await
|
|
191
|
+
await adapter.disconnect();
|
|
203
192
|
}
|
|
204
193
|
|
|
205
|
-
private
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
)
|
|
194
|
+
private async getAdapter():
|
|
195
|
+
Promise<DatabaseAdapter> {
|
|
196
|
+
if (!this.adapterPromise) {
|
|
197
|
+
this.adapterPromise =
|
|
198
|
+
initializeDatabaseAdapter(
|
|
199
|
+
this.options
|
|
212
200
|
);
|
|
213
201
|
}
|
|
214
202
|
|
|
215
|
-
|
|
203
|
+
try {
|
|
204
|
+
return await this.adapterPromise;
|
|
205
|
+
} catch (error) {
|
|
206
|
+
this.adapterPromise =
|
|
207
|
+
null;
|
|
208
|
+
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
216
211
|
}
|
|
217
212
|
}
|
|
218
213
|
|
|
@@ -225,38 +220,50 @@ export function createDatabase(
|
|
|
225
220
|
}
|
|
226
221
|
|
|
227
222
|
export function resolveDatabaseOptions(
|
|
228
|
-
options:
|
|
223
|
+
options: DatabaseConnectionOptions = {},
|
|
229
224
|
environment: NodeJS.ProcessEnv =
|
|
230
225
|
process.env
|
|
231
|
-
):
|
|
226
|
+
): ResolvedDatabaseOptions {
|
|
227
|
+
const url =
|
|
228
|
+
nonEmpty(
|
|
229
|
+
options.url ??
|
|
230
|
+
environment.DATABASE_URL
|
|
231
|
+
) ??
|
|
232
|
+
undefined;
|
|
232
233
|
const driver =
|
|
233
|
-
options.driver ??
|
|
234
234
|
normalizeDriver(
|
|
235
|
-
|
|
236
|
-
|
|
235
|
+
String(
|
|
236
|
+
options.driver ??
|
|
237
|
+
environment.DB_DRIVER ??
|
|
238
|
+
inferDriverFromDatabaseUrl(
|
|
239
|
+
url
|
|
240
|
+
) ??
|
|
241
|
+
"mysql"
|
|
242
|
+
)
|
|
237
243
|
);
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
) {
|
|
242
|
-
throw new Error(
|
|
243
|
-
`BCP Database: unsupported database driver "${driver}".`
|
|
244
|
+
const defaults =
|
|
245
|
+
getDriverDefaults(
|
|
246
|
+
driver
|
|
244
247
|
);
|
|
245
|
-
}
|
|
246
248
|
|
|
247
249
|
return {
|
|
248
250
|
driver,
|
|
251
|
+
...(url
|
|
252
|
+
? {
|
|
253
|
+
url,
|
|
254
|
+
}
|
|
255
|
+
: {}),
|
|
249
256
|
host:
|
|
250
257
|
nonEmpty(
|
|
251
258
|
options.host ??
|
|
252
259
|
environment.DB_HOST
|
|
253
260
|
) ??
|
|
254
|
-
|
|
261
|
+
defaults.host,
|
|
255
262
|
port:
|
|
256
263
|
resolvePositiveInteger(
|
|
257
264
|
options.port ??
|
|
258
265
|
environment.DB_PORT,
|
|
259
|
-
|
|
266
|
+
defaults.port,
|
|
260
267
|
"DB_PORT"
|
|
261
268
|
),
|
|
262
269
|
user:
|
|
@@ -264,7 +271,7 @@ export function resolveDatabaseOptions(
|
|
|
264
271
|
options.user ??
|
|
265
272
|
environment.DB_USER
|
|
266
273
|
) ??
|
|
267
|
-
|
|
274
|
+
defaults.user,
|
|
268
275
|
password:
|
|
269
276
|
String(
|
|
270
277
|
options.password ??
|
|
@@ -276,12 +283,12 @@ export function resolveDatabaseOptions(
|
|
|
276
283
|
options.database ??
|
|
277
284
|
environment.DB_NAME
|
|
278
285
|
) ??
|
|
279
|
-
|
|
286
|
+
defaults.database,
|
|
280
287
|
connectionLimit:
|
|
281
288
|
resolvePositiveInteger(
|
|
282
289
|
options.connectionLimit ??
|
|
283
290
|
environment.DB_CONNECTION_LIMIT,
|
|
284
|
-
|
|
291
|
+
defaults.connectionLimit,
|
|
285
292
|
"DB_CONNECTION_LIMIT"
|
|
286
293
|
),
|
|
287
294
|
waitForConnections:
|
|
@@ -303,54 +310,67 @@ export function resolveDatabaseOptions(
|
|
|
303
310
|
options.charset ??
|
|
304
311
|
environment.DB_CHARSET
|
|
305
312
|
) ??
|
|
306
|
-
|
|
313
|
+
defaults.charset,
|
|
307
314
|
};
|
|
308
315
|
}
|
|
309
316
|
|
|
310
317
|
export const db =
|
|
311
318
|
createDatabase();
|
|
312
319
|
|
|
313
|
-
async function
|
|
314
|
-
options:
|
|
315
|
-
): Promise<
|
|
316
|
-
let
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
320
|
+
async function initializeDatabaseAdapter(
|
|
321
|
+
options: DatabaseOptions
|
|
322
|
+
): Promise<DatabaseAdapter> {
|
|
323
|
+
let adapter:
|
|
324
|
+
DatabaseAdapter;
|
|
325
|
+
|
|
326
|
+
if (options.adapter) {
|
|
327
|
+
adapter =
|
|
328
|
+
typeof options.adapter ===
|
|
329
|
+
"function"
|
|
330
|
+
? await options.adapter()
|
|
331
|
+
: options.adapter;
|
|
332
|
+
} else {
|
|
333
|
+
const resolvedOptions =
|
|
334
|
+
resolveDatabaseOptions(
|
|
335
|
+
options
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
switch (
|
|
339
|
+
resolvedOptions.driver
|
|
340
|
+
) {
|
|
341
|
+
case "postgresql": {
|
|
342
|
+
adapter =
|
|
343
|
+
createPostgresqlDatabaseAdapter(
|
|
344
|
+
resolvedOptions
|
|
345
|
+
);
|
|
346
|
+
break;
|
|
330
347
|
}
|
|
331
|
-
|
|
348
|
+
|
|
349
|
+
case "sqlite": {
|
|
350
|
+
adapter =
|
|
351
|
+
createSqliteDatabaseAdapter(
|
|
352
|
+
resolvedOptions
|
|
353
|
+
);
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
default: {
|
|
358
|
+
adapter =
|
|
359
|
+
createMysqlDatabaseAdapter(
|
|
360
|
+
resolvedOptions
|
|
361
|
+
);
|
|
362
|
+
break;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
332
365
|
}
|
|
333
366
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
password:
|
|
342
|
-
options.password,
|
|
343
|
-
database:
|
|
344
|
-
options.database,
|
|
345
|
-
waitForConnections:
|
|
346
|
-
options.waitForConnections,
|
|
347
|
-
connectionLimit:
|
|
348
|
-
options.connectionLimit,
|
|
349
|
-
queueLimit:
|
|
350
|
-
options.queueLimit,
|
|
351
|
-
charset:
|
|
352
|
-
options.charset,
|
|
353
|
-
});
|
|
367
|
+
assertDatabaseAdapter(
|
|
368
|
+
adapter
|
|
369
|
+
);
|
|
370
|
+
|
|
371
|
+
await adapter.connect();
|
|
372
|
+
|
|
373
|
+
return adapter;
|
|
354
374
|
}
|
|
355
375
|
|
|
356
376
|
function normalizeDriver(
|
|
@@ -367,11 +387,121 @@ function normalizeDriver(
|
|
|
367
387
|
return "mysql";
|
|
368
388
|
}
|
|
369
389
|
|
|
390
|
+
if (
|
|
391
|
+
normalized === "postgresql" ||
|
|
392
|
+
normalized === "postgres" ||
|
|
393
|
+
normalized === "pg"
|
|
394
|
+
) {
|
|
395
|
+
return "postgresql";
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (
|
|
399
|
+
normalized === "sqlite" ||
|
|
400
|
+
normalized === "sqlite3"
|
|
401
|
+
) {
|
|
402
|
+
return "sqlite";
|
|
403
|
+
}
|
|
404
|
+
|
|
370
405
|
throw new Error(
|
|
371
406
|
`BCP Database: unsupported database driver "${value}".`
|
|
372
407
|
);
|
|
373
408
|
}
|
|
374
409
|
|
|
410
|
+
function inferDriverFromDatabaseUrl(
|
|
411
|
+
value: string | undefined
|
|
412
|
+
): DatabaseDriver | null {
|
|
413
|
+
if (!value) {
|
|
414
|
+
return null;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if (
|
|
418
|
+
/^postgres(?:ql)?:\/\//i.test(
|
|
419
|
+
value
|
|
420
|
+
)
|
|
421
|
+
) {
|
|
422
|
+
return "postgresql";
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (
|
|
426
|
+
/^mysql:\/\//i.test(
|
|
427
|
+
value
|
|
428
|
+
)
|
|
429
|
+
) {
|
|
430
|
+
return "mysql";
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (
|
|
434
|
+
value === ":memory:" ||
|
|
435
|
+
/^(?:sqlite|file):/i.test(
|
|
436
|
+
value
|
|
437
|
+
) ||
|
|
438
|
+
/\.(?:sqlite|sqlite3|db)$/i.test(
|
|
439
|
+
value
|
|
440
|
+
)
|
|
441
|
+
) {
|
|
442
|
+
return "sqlite";
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
return null;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
function getDriverDefaults(
|
|
449
|
+
driver: DatabaseDriver
|
|
450
|
+
): DriverDefaults {
|
|
451
|
+
if (
|
|
452
|
+
driver === "postgresql"
|
|
453
|
+
) {
|
|
454
|
+
return {
|
|
455
|
+
host:
|
|
456
|
+
"localhost",
|
|
457
|
+
port:
|
|
458
|
+
5432,
|
|
459
|
+
user:
|
|
460
|
+
"postgres",
|
|
461
|
+
database:
|
|
462
|
+
"bcp_app",
|
|
463
|
+
connectionLimit:
|
|
464
|
+
10,
|
|
465
|
+
charset:
|
|
466
|
+
"utf8",
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
if (
|
|
471
|
+
driver === "sqlite"
|
|
472
|
+
) {
|
|
473
|
+
return {
|
|
474
|
+
host:
|
|
475
|
+
"",
|
|
476
|
+
port:
|
|
477
|
+
0,
|
|
478
|
+
user:
|
|
479
|
+
"",
|
|
480
|
+
database:
|
|
481
|
+
"./data/bcp.sqlite",
|
|
482
|
+
connectionLimit:
|
|
483
|
+
1,
|
|
484
|
+
charset:
|
|
485
|
+
"utf8",
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
return {
|
|
490
|
+
host:
|
|
491
|
+
"localhost",
|
|
492
|
+
port:
|
|
493
|
+
3306,
|
|
494
|
+
user:
|
|
495
|
+
"root",
|
|
496
|
+
database:
|
|
497
|
+
"bcp_app",
|
|
498
|
+
connectionLimit:
|
|
499
|
+
10,
|
|
500
|
+
charset:
|
|
501
|
+
"utf8mb4",
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
|
|
375
505
|
function nonEmpty(
|
|
376
506
|
value: unknown
|
|
377
507
|
): string | null {
|
|
@@ -490,3 +620,38 @@ function assertSql(
|
|
|
490
620
|
);
|
|
491
621
|
}
|
|
492
622
|
}
|
|
623
|
+
|
|
624
|
+
function assertTransactionCallback(
|
|
625
|
+
callback: unknown
|
|
626
|
+
): asserts callback is (
|
|
627
|
+
database: TransactionDatabase
|
|
628
|
+
) => Promise<unknown> {
|
|
629
|
+
if (
|
|
630
|
+
typeof callback !==
|
|
631
|
+
"function"
|
|
632
|
+
) {
|
|
633
|
+
throw new TypeError(
|
|
634
|
+
"BCP Database: transaction callback must be a function."
|
|
635
|
+
);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
function assertDatabaseAdapter(
|
|
640
|
+
adapter: DatabaseAdapter
|
|
641
|
+
): void {
|
|
642
|
+
if (
|
|
643
|
+
!adapter ||
|
|
644
|
+
typeof adapter !== "object" ||
|
|
645
|
+
typeof adapter.driver !== "string" ||
|
|
646
|
+
adapter.driver.trim() === "" ||
|
|
647
|
+
typeof adapter.connect !== "function" ||
|
|
648
|
+
typeof adapter.query !== "function" ||
|
|
649
|
+
typeof adapter.execute !== "function" ||
|
|
650
|
+
typeof adapter.transaction !== "function" ||
|
|
651
|
+
typeof adapter.disconnect !== "function"
|
|
652
|
+
) {
|
|
653
|
+
throw new TypeError(
|
|
654
|
+
"BCP Database: adapter must implement driver, connect, query, execute, transaction and disconnect."
|
|
655
|
+
);
|
|
656
|
+
}
|
|
657
|
+
}
|