velocious 1.0.93 → 1.0.95
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/package.json +1 -1
- package/src/application.js +19 -0
- package/src/cli/base-command.js +1 -0
- package/src/cli/commands/db/migrate.js +2 -0
- package/src/cli/commands/generate/base-models.js +7 -0
- package/src/cli/commands/generate/model.js +1 -1
- package/src/configuration-resolver.js +6 -3
- package/src/configuration.js +27 -4
- package/src/database/drivers/base-column.js +69 -0
- package/src/database/drivers/base-columns-index.js +19 -0
- package/src/database/drivers/base-foreign-key.js +12 -0
- package/src/database/drivers/base-table.js +32 -0
- package/src/database/drivers/base.js +125 -3
- package/src/database/migrator.js +17 -2
- package/src/database/query/drop-table-base.js +8 -0
- package/src/database/query/index.js +42 -0
- package/src/database/query-parser/from-parser.js +17 -6
- package/src/database/query-parser/group-parser.js +21 -8
- package/src/database/record/index.js +12 -11
- package/src/database/record/relationships/base.js +29 -6
- package/src/database/table-data/index.js +198 -6
- package/src/environment-handlers/base.js +58 -0
- package/src/environment-handlers/browser.js +0 -24
- package/src/environment-handlers/node/cli/commands/generate/base-models.js +123 -0
- package/src/environment-handlers/node.js +6 -1
- package/src/initializer.js +4 -0
- package/src/logger.js +54 -2
- package/src/routes/base-route.js +25 -4
- package/src/routes/get-route.js +3 -1
- package/src/routes/namespace-route.js +3 -1
- package/src/routes/post-route.js +3 -1
- package/src/routes/resource-route.js +3 -1
- package/src/utils/backtrace-cleaner.js +10 -0
|
@@ -10,6 +10,10 @@ import TableForeignKey from "../table-data/table-foreign-key.js"
|
|
|
10
10
|
import wait from "awaitery/src/wait.js"
|
|
11
11
|
|
|
12
12
|
export default class VelociousDatabaseDriversBase {
|
|
13
|
+
/**
|
|
14
|
+
* @param {object} config
|
|
15
|
+
* @param {import("../../configuration.js").default} configuration
|
|
16
|
+
*/
|
|
13
17
|
constructor(config, configuration) {
|
|
14
18
|
this._args = config
|
|
15
19
|
this.configuration = configuration
|
|
@@ -19,6 +23,14 @@ export default class VelociousDatabaseDriversBase {
|
|
|
19
23
|
this._transactionsActionsMutex = new Mutex()
|
|
20
24
|
}
|
|
21
25
|
|
|
26
|
+
/**
|
|
27
|
+
* @param {string} tableName
|
|
28
|
+
* @param {string} columnName
|
|
29
|
+
* @param {string} referencedTableName
|
|
30
|
+
* @param {string} referencedColumnName
|
|
31
|
+
* @param {object} args
|
|
32
|
+
* @returns {Promise<void>}
|
|
33
|
+
*/
|
|
22
34
|
async addForeignKey(tableName, columnName, referencedTableName, referencedColumnName, args) {
|
|
23
35
|
const tableForeignKeyArgs = Object.assign(
|
|
24
36
|
{
|
|
@@ -41,6 +53,18 @@ export default class VelociousDatabaseDriversBase {
|
|
|
41
53
|
}
|
|
42
54
|
}
|
|
43
55
|
|
|
56
|
+
/**
|
|
57
|
+
* @interface
|
|
58
|
+
* @returns {Promise<string[]>}
|
|
59
|
+
*/
|
|
60
|
+
alterTableSql() {
|
|
61
|
+
throw new Error("alterTableSql not implemented")
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @param {...Parameters<this["createTableSql"]>} args
|
|
66
|
+
* @returns {void}
|
|
67
|
+
*/
|
|
44
68
|
async createTable(...args) {
|
|
45
69
|
const sqls = this.createTableSql(...args)
|
|
46
70
|
|
|
@@ -49,12 +73,20 @@ export default class VelociousDatabaseDriversBase {
|
|
|
49
73
|
}
|
|
50
74
|
}
|
|
51
75
|
|
|
76
|
+
/**
|
|
77
|
+
* @param {...Parameters<this["deleteSql"]>} args
|
|
78
|
+
* @returns {void}
|
|
79
|
+
*/
|
|
52
80
|
async delete(...args) {
|
|
53
81
|
const sql = this.deleteSql(...args)
|
|
54
82
|
|
|
55
83
|
await this.query(sql)
|
|
56
84
|
}
|
|
57
85
|
|
|
86
|
+
/**
|
|
87
|
+
* @param {...Parameters<this['dropTableSql']>} args
|
|
88
|
+
* @returns {void}
|
|
89
|
+
*/
|
|
58
90
|
async dropTable(...args) {
|
|
59
91
|
const sqls = this.dropTableSql(...args)
|
|
60
92
|
|
|
@@ -63,20 +95,45 @@ export default class VelociousDatabaseDriversBase {
|
|
|
63
95
|
}
|
|
64
96
|
}
|
|
65
97
|
|
|
98
|
+
/**
|
|
99
|
+
* @interface
|
|
100
|
+
* @param {string} _tableName
|
|
101
|
+
* @param {object} _args
|
|
102
|
+
* @param {boolean} _args.cascade
|
|
103
|
+
* @param {boolean} _args.ifExists
|
|
104
|
+
* @returns {string}
|
|
105
|
+
*/
|
|
106
|
+
dropTableSql(_tableName, _args) { // eslint-disable-line no-unused-vars
|
|
107
|
+
throw new Error("dropTableSql not implemented")
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @returns {object}
|
|
112
|
+
*/
|
|
66
113
|
getArgs() {
|
|
67
114
|
return this._args
|
|
68
115
|
}
|
|
69
116
|
|
|
117
|
+
/**
|
|
118
|
+
* @returns {import("../../configuration.js").default}
|
|
119
|
+
*/
|
|
70
120
|
getConfiguration() {
|
|
71
121
|
if (!this.configuration) throw new Error("No configuration set")
|
|
72
122
|
|
|
73
123
|
return this.configuration
|
|
74
124
|
}
|
|
75
125
|
|
|
126
|
+
/**
|
|
127
|
+
* @returns {number}
|
|
128
|
+
*/
|
|
76
129
|
getIdSeq() {
|
|
77
130
|
return this.idSeq
|
|
78
131
|
}
|
|
79
132
|
|
|
133
|
+
/**
|
|
134
|
+
* @interface
|
|
135
|
+
* @returns {Array<import("./base-table.js").default>}
|
|
136
|
+
*/
|
|
80
137
|
getTables() {
|
|
81
138
|
throw new Error(`${this.constructor.name}#getTables not implemented`)
|
|
82
139
|
}
|
|
@@ -106,6 +163,10 @@ export default class VelociousDatabaseDriversBase {
|
|
|
106
163
|
await this.query(sql)
|
|
107
164
|
}
|
|
108
165
|
|
|
166
|
+
/**
|
|
167
|
+
* @interface
|
|
168
|
+
* @returns {Promise<number>}
|
|
169
|
+
*/
|
|
109
170
|
lastInsertID() {
|
|
110
171
|
throw new Error(`${this.constructor.name}#lastInsertID not implemented`)
|
|
111
172
|
}
|
|
@@ -181,8 +242,12 @@ export default class VelociousDatabaseDriversBase {
|
|
|
181
242
|
return await this.query(sql)
|
|
182
243
|
}
|
|
183
244
|
|
|
184
|
-
|
|
185
|
-
|
|
245
|
+
/**
|
|
246
|
+
* @param {number} newIdSeq
|
|
247
|
+
* @returns {void}
|
|
248
|
+
*/
|
|
249
|
+
setIdSeq(newIdSeq) {
|
|
250
|
+
this.idSeq = newIdSeq
|
|
186
251
|
}
|
|
187
252
|
|
|
188
253
|
/**
|
|
@@ -246,6 +311,9 @@ export default class VelociousDatabaseDriversBase {
|
|
|
246
311
|
return result
|
|
247
312
|
}
|
|
248
313
|
|
|
314
|
+
/**
|
|
315
|
+
* @returns {Promise<void>}
|
|
316
|
+
*/
|
|
249
317
|
async startTransaction() {
|
|
250
318
|
await this._transactionsActionsMutex.sync(async () => {
|
|
251
319
|
await this._startTransactionAction()
|
|
@@ -253,10 +321,16 @@ export default class VelociousDatabaseDriversBase {
|
|
|
253
321
|
})
|
|
254
322
|
}
|
|
255
323
|
|
|
324
|
+
/**
|
|
325
|
+
* @returns {Promise<void>}
|
|
326
|
+
*/
|
|
256
327
|
async _startTransactionAction() {
|
|
257
328
|
await this.query("BEGIN TRANSACTION")
|
|
258
329
|
}
|
|
259
330
|
|
|
331
|
+
/**
|
|
332
|
+
* @returns {Promise<void>}
|
|
333
|
+
*/
|
|
260
334
|
async commitTransaction() {
|
|
261
335
|
await this._transactionsActionsMutex.sync(async () => {
|
|
262
336
|
await this._commitTransactionAction()
|
|
@@ -264,13 +338,16 @@ export default class VelociousDatabaseDriversBase {
|
|
|
264
338
|
})
|
|
265
339
|
}
|
|
266
340
|
|
|
341
|
+
/**
|
|
342
|
+
* @returns {Promise<void>}
|
|
343
|
+
*/
|
|
267
344
|
async _commitTransactionAction() {
|
|
268
345
|
await this.query("COMMIT")
|
|
269
346
|
}
|
|
270
347
|
|
|
271
348
|
/**
|
|
272
349
|
* @param {string} sql
|
|
273
|
-
* @returns {Promise<Array
|
|
350
|
+
* @returns {Promise<Array<Record<string, any>>>}
|
|
274
351
|
*/
|
|
275
352
|
async query(sql) {
|
|
276
353
|
let tries = 0
|
|
@@ -292,10 +369,18 @@ export default class VelociousDatabaseDriversBase {
|
|
|
292
369
|
}
|
|
293
370
|
}
|
|
294
371
|
|
|
372
|
+
/**
|
|
373
|
+
* @interface
|
|
374
|
+
* @param {Error} _error
|
|
375
|
+
* @returns {boolean}
|
|
376
|
+
*/
|
|
295
377
|
retryableDatabaseError(_error) { // eslint-disable-line no-unused-vars
|
|
296
378
|
return false
|
|
297
379
|
}
|
|
298
380
|
|
|
381
|
+
/**
|
|
382
|
+
* @returns {Promise<void>}
|
|
383
|
+
*/
|
|
299
384
|
async rollbackTransaction() {
|
|
300
385
|
await this._transactionsActionsMutex.sync(async () => {
|
|
301
386
|
await this._rollbackTransactionAction()
|
|
@@ -303,20 +388,34 @@ export default class VelociousDatabaseDriversBase {
|
|
|
303
388
|
})
|
|
304
389
|
}
|
|
305
390
|
|
|
391
|
+
/**
|
|
392
|
+
* @returns {Promise<void>}
|
|
393
|
+
*/
|
|
306
394
|
async _rollbackTransactionAction() {
|
|
307
395
|
await this.query("ROLLBACK")
|
|
308
396
|
}
|
|
309
397
|
|
|
398
|
+
/**
|
|
399
|
+
* @returns {string}
|
|
400
|
+
*/
|
|
310
401
|
generateSavePointName() {
|
|
311
402
|
return `sp${new UUID(4).format().replaceAll("-", "")}`
|
|
312
403
|
}
|
|
313
404
|
|
|
405
|
+
/**
|
|
406
|
+
* @param {string} savePointName
|
|
407
|
+
* @returns {Promise<void>}
|
|
408
|
+
*/
|
|
314
409
|
async startSavePoint(savePointName) {
|
|
315
410
|
await this._transactionsActionsMutex.sync(async () => {
|
|
316
411
|
await this._startSavePointAction(savePointName)
|
|
317
412
|
})
|
|
318
413
|
}
|
|
319
414
|
|
|
415
|
+
/**
|
|
416
|
+
* @param {string} savePointName
|
|
417
|
+
* @returns {Promise<void>}
|
|
418
|
+
*/
|
|
320
419
|
async _startSavePointAction(savePointName) {
|
|
321
420
|
await this.query(`SAVEPOINT ${savePointName}`)
|
|
322
421
|
}
|
|
@@ -343,26 +442,45 @@ export default class VelociousDatabaseDriversBase {
|
|
|
343
442
|
}
|
|
344
443
|
}
|
|
345
444
|
|
|
445
|
+
/**
|
|
446
|
+
* @param {string} savePointName
|
|
447
|
+
* @returns {Promise<void>}
|
|
448
|
+
*/
|
|
346
449
|
async releaseSavePoint(savePointName) {
|
|
347
450
|
await this._transactionsActionsMutex.sync(async () => {
|
|
348
451
|
await this._releaseSavePointAction(savePointName)
|
|
349
452
|
})
|
|
350
453
|
}
|
|
351
454
|
|
|
455
|
+
/**
|
|
456
|
+
* @param {string} savePointName
|
|
457
|
+
* @returns {Promise<void>}
|
|
458
|
+
*/
|
|
352
459
|
async _releaseSavePointAction(savePointName) {
|
|
353
460
|
await this.query(`RELEASE SAVEPOINT ${savePointName}`)
|
|
354
461
|
}
|
|
355
462
|
|
|
463
|
+
/**
|
|
464
|
+
* @param {string} savePointName
|
|
465
|
+
* @returns {Promise<void>}
|
|
466
|
+
*/
|
|
356
467
|
async rollbackSavePoint(savePointName) {
|
|
357
468
|
await this._transactionsActionsMutex.sync(async () => {
|
|
358
469
|
await this._rollbackSavePointAction(savePointName)
|
|
359
470
|
})
|
|
360
471
|
}
|
|
361
472
|
|
|
473
|
+
/**
|
|
474
|
+
* @param {string} savePointName
|
|
475
|
+
* @returns {Promise<void>}
|
|
476
|
+
*/
|
|
362
477
|
async _rollbackSavePointAction(savePointName) {
|
|
363
478
|
await this.query(`ROLLBACK TO SAVEPOINT ${savePointName}`)
|
|
364
479
|
}
|
|
365
480
|
|
|
481
|
+
/**
|
|
482
|
+
* @returns {Promise<void>}
|
|
483
|
+
*/
|
|
366
484
|
async truncateAllTables() {
|
|
367
485
|
await this.withDisabledForeignKeys(async () => {
|
|
368
486
|
let tries = 0
|
|
@@ -408,6 +526,10 @@ export default class VelociousDatabaseDriversBase {
|
|
|
408
526
|
await this.query(sql)
|
|
409
527
|
}
|
|
410
528
|
|
|
529
|
+
/**
|
|
530
|
+
* @param {function() : void} callback
|
|
531
|
+
* @returns {Promise<any>}
|
|
532
|
+
*/
|
|
411
533
|
async withDisabledForeignKeys(callback) {
|
|
412
534
|
await this.disableForeignKeys()
|
|
413
535
|
|
package/src/database/migrator.js
CHANGED
|
@@ -5,20 +5,30 @@ import restArgsError from "../utils/rest-args-error.js"
|
|
|
5
5
|
import TableData from "./table-data/index.js"
|
|
6
6
|
|
|
7
7
|
export default class VelociousDatabaseMigrator {
|
|
8
|
+
/**
|
|
9
|
+
* @param {object} args
|
|
10
|
+
* @param {import("../configuration.js").default} args.configuration
|
|
11
|
+
*/
|
|
8
12
|
constructor({configuration, ...restArgs}) {
|
|
9
13
|
restArgsError(restArgs)
|
|
10
14
|
|
|
11
15
|
if (!configuration) throw new Error("configuration argument is required")
|
|
12
16
|
|
|
13
17
|
this.configuration = configuration
|
|
14
|
-
this.logger = new Logger(this)
|
|
18
|
+
this.logger = new Logger(this, {debug: false})
|
|
15
19
|
}
|
|
16
20
|
|
|
21
|
+
/**
|
|
22
|
+
* @returns {Promise<void>}
|
|
23
|
+
*/
|
|
17
24
|
async prepare() {
|
|
18
25
|
await this.createMigrationsTable()
|
|
19
26
|
await this.loadMigrationsVersions()
|
|
20
27
|
}
|
|
21
28
|
|
|
29
|
+
/**
|
|
30
|
+
* @returns {Promise<void>}
|
|
31
|
+
*/
|
|
22
32
|
async createMigrationsTable() {
|
|
23
33
|
const dbs = await this.configuration.getCurrentConnections()
|
|
24
34
|
|
|
@@ -48,6 +58,11 @@ export default class VelociousDatabaseMigrator {
|
|
|
48
58
|
}
|
|
49
59
|
}
|
|
50
60
|
|
|
61
|
+
/**
|
|
62
|
+
* @param {string} dbIdentifier
|
|
63
|
+
* @param {string} version
|
|
64
|
+
* @returns {Promise<boolean>}
|
|
65
|
+
*/
|
|
51
66
|
hasRunMigrationVersion(dbIdentifier, version) {
|
|
52
67
|
if (!this.migrationsVersions) throw new Error("Migrations versions hasn't been loaded yet")
|
|
53
68
|
if (!this.migrationsVersions[dbIdentifier]) throw new Error(`Migrations versions hasn't been loaded yet for db: ${dbIdentifier}`)
|
|
@@ -197,7 +212,7 @@ export default class VelociousDatabaseMigrator {
|
|
|
197
212
|
for (const migration of files) {
|
|
198
213
|
await this.runMigrationFile({
|
|
199
214
|
migration,
|
|
200
|
-
require: requireContext(migration.file).default
|
|
215
|
+
require: () => requireContext(migration.file).default
|
|
201
216
|
})
|
|
202
217
|
}
|
|
203
218
|
}
|
|
@@ -3,6 +3,14 @@ import QueryBase from "./base.js"
|
|
|
3
3
|
import restArgsError from "../../utils/rest-args-error.js"
|
|
4
4
|
|
|
5
5
|
export default class VelociousDatabaseQueryDropTableBase extends QueryBase {
|
|
6
|
+
/**
|
|
7
|
+
* @param {object} args
|
|
8
|
+
* @param {boolean} args.cascade
|
|
9
|
+
* @param {import("./../drivers/base.js").default} args.driver
|
|
10
|
+
* @param {boolean} args.ifExists
|
|
11
|
+
* @param {object} args.options
|
|
12
|
+
* @param {string} args.tableName
|
|
13
|
+
*/
|
|
6
14
|
constructor({cascade, driver, ifExists, options, tableName, ...restArgs}) {
|
|
7
15
|
super({driver, options})
|
|
8
16
|
|
|
@@ -11,7 +11,34 @@ import WhereHash from "./where-hash.js"
|
|
|
11
11
|
import WherePlain from "./where-plain.js"
|
|
12
12
|
import restArgsError from "../../utils/rest-args-error.js"
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* @typedef {Record<string, boolean|NestedPreloadRecord>} NestedPreloadRecord
|
|
16
|
+
*/
|
|
17
|
+
|
|
14
18
|
export default class VelociousDatabaseQuery {
|
|
19
|
+
/**
|
|
20
|
+
* @param {object} args
|
|
21
|
+
* @template {import("../drivers/base.js").default} Tdriver
|
|
22
|
+
* @param {Tdriver} args.driver
|
|
23
|
+
* @template {import("./from-base.js").default} TfromBase
|
|
24
|
+
* @param {TfromBase[]} args.froms
|
|
25
|
+
* @param {string[]} args.groups
|
|
26
|
+
* @template {import("./join-base.js").default} TjoinBase
|
|
27
|
+
* @param {TjoinBase[]} args.joins
|
|
28
|
+
* @param {import("../handler.js").default} args.handler
|
|
29
|
+
* @param {number} args.limit
|
|
30
|
+
* @template {import("../record/index.js").default} Trecord
|
|
31
|
+
* @param {typeof Trecord} args.modelClass
|
|
32
|
+
* @param {number} args.offset
|
|
33
|
+
* @template {import("./order-basejs").default} TorderBase
|
|
34
|
+
* @param {TorderBase[]} args.orders
|
|
35
|
+
* @param {number} args.page
|
|
36
|
+
* @param {number} args.perPage
|
|
37
|
+
* @param {NestedPreloadRecord} args.preload
|
|
38
|
+
* @param {Record<string, Array<string>>} args.selects
|
|
39
|
+
* @template {import("./where-base.js").default} TwhereBase
|
|
40
|
+
* @param {TwhereBase[]} args.wheres
|
|
41
|
+
*/
|
|
15
42
|
constructor({driver, froms = [], groups = [], joins = [], handler, limit = null, modelClass, offset = null, orders = [], page = null, perPage, preload = {}, selects = [], wheres = [], ...restArgs}) {
|
|
16
43
|
if (!driver) throw new Error("No driver given to query")
|
|
17
44
|
if (!handler) throw new Error("No handler given to query")
|
|
@@ -100,6 +127,21 @@ export default class VelociousDatabaseQuery {
|
|
|
100
127
|
return countResult
|
|
101
128
|
}
|
|
102
129
|
|
|
130
|
+
/**
|
|
131
|
+
* @template {import("./from-base.js").default} T
|
|
132
|
+
* @returns {T[]}
|
|
133
|
+
*/
|
|
134
|
+
getFroms() {
|
|
135
|
+
return this._froms
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @returns {string[]}
|
|
140
|
+
*/
|
|
141
|
+
getGroups() {
|
|
142
|
+
return this._groups
|
|
143
|
+
}
|
|
144
|
+
|
|
103
145
|
/**
|
|
104
146
|
* @returns {import("../query-parser/options.js").default}
|
|
105
147
|
*/
|
|
@@ -1,20 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import restArgsError from "../../utils/rest-args-error.js"
|
|
2
4
|
|
|
3
5
|
export default class VelociousDatabaseQueryParserFromParser {
|
|
4
|
-
|
|
6
|
+
/**
|
|
7
|
+
* @param {object} args
|
|
8
|
+
* @param {boolean} args.pretty
|
|
9
|
+
* @param {import("../query/index.js").default} args.query
|
|
10
|
+
*/
|
|
11
|
+
constructor({pretty, query, ...restArgs}) {
|
|
12
|
+
restArgsError(restArgs)
|
|
13
|
+
|
|
5
14
|
this.pretty = pretty
|
|
6
15
|
this.query = query
|
|
7
16
|
}
|
|
8
17
|
|
|
18
|
+
/** @returns {string} */
|
|
9
19
|
toSql() {
|
|
10
|
-
const {pretty, query} =
|
|
20
|
+
const {pretty, query} = this
|
|
21
|
+
const froms = query.getFroms()
|
|
11
22
|
|
|
12
23
|
let sql = " FROM"
|
|
13
24
|
|
|
14
|
-
for (const fromKey in
|
|
15
|
-
const from =
|
|
25
|
+
for (const fromKey in froms) {
|
|
26
|
+
const from = froms[fromKey]
|
|
16
27
|
|
|
17
|
-
if (fromKey > 0) {
|
|
28
|
+
if (typeof fromKey == "number" && fromKey > 0) {
|
|
18
29
|
sql += ","
|
|
19
30
|
}
|
|
20
31
|
|
|
@@ -1,24 +1,37 @@
|
|
|
1
|
-
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import restArgsError from "../../utils/rest-args-error.js"
|
|
2
4
|
|
|
3
5
|
export default class VelociousDatabaseQueryParserFromParser {
|
|
4
|
-
|
|
6
|
+
/**
|
|
7
|
+
* @param {object} args
|
|
8
|
+
* @param {boolean} args.pretty
|
|
9
|
+
* @param {import("../query/index.js").default} args.query
|
|
10
|
+
*/
|
|
11
|
+
constructor({pretty, query, ...restArgs}) {
|
|
12
|
+
restArgsError(restArgs)
|
|
13
|
+
|
|
5
14
|
this.pretty = pretty
|
|
6
15
|
this.query = query
|
|
7
16
|
}
|
|
8
17
|
|
|
18
|
+
/**
|
|
19
|
+
* @returns {string}
|
|
20
|
+
*/
|
|
9
21
|
toSql() {
|
|
10
|
-
const {pretty, query} =
|
|
22
|
+
const {pretty, query} = this
|
|
23
|
+
const groups = query.getGroups()
|
|
11
24
|
|
|
12
|
-
if (
|
|
25
|
+
if (groups.length == 0) {
|
|
13
26
|
return ""
|
|
14
27
|
}
|
|
15
28
|
|
|
16
29
|
let sql = " GROUP BY"
|
|
17
30
|
|
|
18
|
-
for (const groupKey in
|
|
19
|
-
const group =
|
|
31
|
+
for (const groupKey in groups) {
|
|
32
|
+
const group = groups[groupKey]
|
|
20
33
|
|
|
21
|
-
if (groupKey > 0) {
|
|
34
|
+
if (typeof groupKey == "number" && groupKey > 0) {
|
|
22
35
|
sql += ","
|
|
23
36
|
}
|
|
24
37
|
|
|
@@ -31,7 +44,7 @@ export default class VelociousDatabaseQueryParserFromParser {
|
|
|
31
44
|
if (typeof group == "string") {
|
|
32
45
|
sql += group
|
|
33
46
|
} else {
|
|
34
|
-
|
|
47
|
+
throw new Error(`Unsupported group type: ${typeof group}`)
|
|
35
48
|
}
|
|
36
49
|
}
|
|
37
50
|
|
|
@@ -44,8 +44,7 @@ class ValidationError extends Error {
|
|
|
44
44
|
|
|
45
45
|
class VelociousDatabaseRecord {
|
|
46
46
|
/**
|
|
47
|
-
* @
|
|
48
|
-
* @returns {Record<string, T>}
|
|
47
|
+
* @returns {Record<string, import("./validators/base.js").default>}
|
|
49
48
|
*/
|
|
50
49
|
static validatorTypes() {
|
|
51
50
|
if (!this._validatorTypes) this._validatorTypes = {}
|
|
@@ -55,16 +54,14 @@ class VelociousDatabaseRecord {
|
|
|
55
54
|
|
|
56
55
|
/**
|
|
57
56
|
* @param {string} name
|
|
58
|
-
* @
|
|
59
|
-
* @param {T} validatorClass
|
|
57
|
+
* @param {import("./validators/base.js").default} validatorClass
|
|
60
58
|
*/
|
|
61
59
|
static registerValidatorType(name, validatorClass) {
|
|
62
60
|
this.validatorTypes()[name] = validatorClass
|
|
63
61
|
}
|
|
64
62
|
|
|
65
63
|
/**
|
|
66
|
-
* @
|
|
67
|
-
* @returns {T}
|
|
64
|
+
* @returns {import("./validators/base.js").default}
|
|
68
65
|
*/
|
|
69
66
|
static getValidatorType(validatorName) {
|
|
70
67
|
if (!(validatorName in this.validatorTypes())) throw new Error(`Validator type ${validatorName} not found`)
|
|
@@ -189,8 +186,7 @@ class VelociousDatabaseRecord {
|
|
|
189
186
|
}
|
|
190
187
|
|
|
191
188
|
/**
|
|
192
|
-
* @
|
|
193
|
-
* @returns {T}
|
|
189
|
+
* @returns {import("./relationships/base.js").default}
|
|
194
190
|
*/
|
|
195
191
|
static getRelationshipByName(relationshipName) {
|
|
196
192
|
if (!this._relationships) this._relationships = {}
|
|
@@ -203,7 +199,7 @@ class VelociousDatabaseRecord {
|
|
|
203
199
|
}
|
|
204
200
|
|
|
205
201
|
/**
|
|
206
|
-
* @returns {Array}
|
|
202
|
+
* @returns {Array<import("./relationships/base.js").default>}
|
|
207
203
|
*/
|
|
208
204
|
static getRelationships() {
|
|
209
205
|
if (this._relationships) return Object.values(this._relationships)
|
|
@@ -269,7 +265,7 @@ class VelociousDatabaseRecord {
|
|
|
269
265
|
}
|
|
270
266
|
|
|
271
267
|
/**
|
|
272
|
-
* @param {
|
|
268
|
+
* @param {Record<string, any>} attributes
|
|
273
269
|
* @returns {Promise<InstanceType<typeof this>>}
|
|
274
270
|
*/
|
|
275
271
|
static async create(attributes) {
|
|
@@ -306,6 +302,7 @@ class VelociousDatabaseRecord {
|
|
|
306
302
|
* Adds a has-many-relationship to the model class.
|
|
307
303
|
* @param {string} relationshipName The name of the relationship (e.g. "posts")
|
|
308
304
|
* @param {object} options The options for the relationship (e.g. {className: "Post"})
|
|
305
|
+
* @returns {void}
|
|
309
306
|
*/
|
|
310
307
|
static hasMany(relationshipName, options = {}) {
|
|
311
308
|
return this._defineRelationship(relationshipName, Object.assign({type: "hasMany"}, options))
|
|
@@ -315,6 +312,7 @@ class VelociousDatabaseRecord {
|
|
|
315
312
|
* Adds a has-one-relationship to the model class.
|
|
316
313
|
* @param {string} relationshipName The name of the relationship (e.g. "post")
|
|
317
314
|
* @param {object} options The options for the relationship (e.g. {className: "Post"})
|
|
315
|
+
* @returns {void}
|
|
318
316
|
*/
|
|
319
317
|
static hasOne(relationshipName, options = {}) {
|
|
320
318
|
return this._defineRelationship(relationshipName, Object.assign({type: "hasOne"}, options))
|
|
@@ -526,6 +524,9 @@ class VelociousDatabaseRecord {
|
|
|
526
524
|
return this._columnNames
|
|
527
525
|
}
|
|
528
526
|
|
|
527
|
+
/**
|
|
528
|
+
* @returns {import("../drivers/base-table.js").default}
|
|
529
|
+
*/
|
|
529
530
|
static _getTable() {
|
|
530
531
|
if (!this._table) throw new Error(`${this.name} hasn't been initialized yet`)
|
|
531
532
|
|
|
@@ -1045,7 +1046,7 @@ class VelociousDatabaseRecord {
|
|
|
1045
1046
|
|
|
1046
1047
|
/**
|
|
1047
1048
|
* Assigns the given attributes to the record.
|
|
1048
|
-
* @param {
|
|
1049
|
+
* @param {Record<string, any>} attributesToAssign
|
|
1049
1050
|
* @returns {void}
|
|
1050
1051
|
*/
|
|
1051
1052
|
assign(attributesToAssign) {
|
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
import restArgsError from "../../../utils/rest-args-error.js"
|
|
2
2
|
|
|
3
3
|
export default class VelociousDatabaseRecordBaseRelationship {
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* @param {object} args
|
|
6
|
+
* @param {string} args.className
|
|
7
|
+
* @param {import("../../../configuration.js").default} args.configuration
|
|
8
|
+
* @param {string} args.dependent
|
|
9
|
+
* @param {boolean|object} args.foreignKey
|
|
10
|
+
* @param {string} args.inverseOf
|
|
11
|
+
* @param {typeof import("../index.js").default} args.klass
|
|
12
|
+
* @param {typeof import("../index.js").default} args.modelClass
|
|
13
|
+
* @param {string} args.primaryKey
|
|
14
|
+
* @param {boolean} args.polymorphic
|
|
15
|
+
* @param {string} args.relationshipName
|
|
16
|
+
* @param {string} args.through
|
|
17
|
+
* @param {string} args.type
|
|
18
|
+
*/
|
|
19
|
+
constructor({className, configuration, dependent, foreignKey, inverseOf, klass, modelClass, primaryKey = "id", polymorphic, relationshipName, through, type, ...restArgs}) { // eslint-disable-line no-unused-vars
|
|
5
20
|
restArgsError(restArgs)
|
|
6
21
|
|
|
7
22
|
if (!modelClass) throw new Error(`'modelClass' wasn't given for ${relationshipName}`)
|
|
@@ -14,6 +29,7 @@ export default class VelociousDatabaseRecordBaseRelationship {
|
|
|
14
29
|
this._inverseOf
|
|
15
30
|
this.klass = klass
|
|
16
31
|
this.modelClass = modelClass
|
|
32
|
+
this._polymorphic = polymorphic
|
|
17
33
|
this._primaryKey = primaryKey
|
|
18
34
|
this.relationshipName = relationshipName
|
|
19
35
|
this.through = through
|
|
@@ -42,8 +58,7 @@ export default class VelociousDatabaseRecordBaseRelationship {
|
|
|
42
58
|
}
|
|
43
59
|
|
|
44
60
|
/**
|
|
45
|
-
* @
|
|
46
|
-
* @returns {typeof T}
|
|
61
|
+
* @returns {typeof import("../index.js").default}
|
|
47
62
|
*/
|
|
48
63
|
getModelClass() { return this.modelClass }
|
|
49
64
|
|
|
@@ -52,6 +67,13 @@ export default class VelociousDatabaseRecordBaseRelationship {
|
|
|
52
67
|
*/
|
|
53
68
|
getRelationshipName() { return this.relationshipName }
|
|
54
69
|
|
|
70
|
+
/**
|
|
71
|
+
* @returns {boolean}
|
|
72
|
+
*/
|
|
73
|
+
getPolymorphic() {
|
|
74
|
+
return this._polymorphic
|
|
75
|
+
}
|
|
76
|
+
|
|
55
77
|
/**
|
|
56
78
|
* @returns {string} The name of the foreign key, e.g. "id" etc.
|
|
57
79
|
*/
|
|
@@ -63,11 +85,12 @@ export default class VelociousDatabaseRecordBaseRelationship {
|
|
|
63
85
|
getType() { return this.type }
|
|
64
86
|
|
|
65
87
|
/**
|
|
66
|
-
* @
|
|
67
|
-
* @returns {typeof T} The target model class for this relationship, e.g. if the relationship is "posts" then the target model class is the Post class.
|
|
88
|
+
* @returns {typeof import("../index.js").default} The target model class for this relationship, e.g. if the relationship is "posts" then the target model class is the Post class.
|
|
68
89
|
*/
|
|
69
90
|
getTargetModelClass() {
|
|
70
|
-
if (this.
|
|
91
|
+
if (this.getPolymorphic()) {
|
|
92
|
+
return null
|
|
93
|
+
} else if (this.className) {
|
|
71
94
|
return this.modelClass._getConfiguration().getModelClass(this.className)
|
|
72
95
|
} else if (this.klass) {
|
|
73
96
|
return this.klass
|