velocious 1.0.96 → 1.0.98
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/eslint.config.js +1 -0
- package/package.json +2 -1
- package/spec/database/connection/drivers/mysql/query-parser-spec.js +4 -4
- package/spec/http-server/post-spec.js +2 -0
- package/src/application.js +27 -9
- package/src/configuration-resolver.js +29 -10
- package/src/configuration-types.js +44 -0
- package/src/configuration.js +63 -33
- package/src/database/drivers/base-column.js +6 -1
- package/src/database/drivers/base-columns-index.js +11 -1
- package/src/database/drivers/base-foreign-key.js +45 -0
- package/src/database/drivers/base-table.js +24 -2
- package/src/database/drivers/base.js +211 -39
- package/src/database/drivers/mssql/index.js +1 -3
- package/src/database/drivers/sqlite/sql/alter-table.js +4 -2
- package/src/database/handler.js +5 -0
- package/src/database/migration/index.js +77 -19
- package/src/database/migrator/files-finder.js +21 -22
- package/src/database/migrator/types.js +29 -0
- package/src/database/migrator.js +98 -59
- package/src/database/pool/async-tracked-multi-connection.js +42 -7
- package/src/database/pool/base-methods-forward.js +37 -0
- package/src/database/pool/base.js +79 -46
- package/src/database/pool/single-multi-use.js +18 -3
- package/src/database/query/alter-table-base.js +4 -4
- package/src/database/query/base.js +9 -2
- package/src/database/query/create-database-base.js +8 -0
- package/src/database/query/create-index-base.js +20 -5
- package/src/database/query/create-table-base.js +28 -9
- package/src/database/query/from-base.js +17 -0
- package/src/database/query/from-plain.js +8 -3
- package/src/database/query/from-table.js +8 -3
- package/src/database/query/index.js +43 -32
- package/src/database/query/join-base.js +28 -1
- package/src/database/query/join-object.js +67 -0
- package/src/database/query/join-plain.js +6 -1
- package/src/database/query/order-base.js +18 -0
- package/src/database/query/order-plain.js +8 -2
- package/src/database/query/select-base.js +15 -0
- package/src/database/query/select-plain.js +6 -1
- package/src/database/query/select-table-and-column.js +8 -2
- package/src/database/query/where-base.js +23 -1
- package/src/database/query/where-hash.js +15 -0
- package/src/database/query/where-plain.js +6 -0
- package/src/database/query-parser/base-query-parser.js +8 -2
- package/src/database/query-parser/from-parser.js +2 -0
- package/src/database/query-parser/joins-parser.js +10 -45
- package/src/database/query-parser/select-parser.js +2 -0
- package/src/database/record/index.js +1 -1
- package/src/database/table-data/index.js +39 -121
- package/src/database/table-data/table-column.js +54 -25
- package/src/database/table-data/table-foreign-key.js +5 -3
- package/src/database/table-data/table-index.js +12 -6
- package/src/database/table-data/table-reference.js +2 -0
- package/src/database/use-database.js +4 -2
- package/src/environment-handlers/base.js +41 -8
- package/src/environment-handlers/node/cli/commands/destroy/migration.js +3 -0
- package/src/environment-handlers/node/cli/commands/generate/migration.js +3 -0
- package/src/environment-handlers/node/cli/commands/generate/model.js +3 -0
- package/src/environment-handlers/node/cli/commands/init.js +3 -0
- package/src/environment-handlers/node/cli/commands/test.js +17 -3
- package/src/environment-handlers/node.js +59 -28
- package/src/http-client/header.js +6 -0
- package/src/http-client/request.js +31 -5
- package/src/http-client/response.js +31 -7
- package/src/http-server/client/index.js +24 -4
- package/src/http-server/client/request-buffer/form-data-part.js +11 -0
- package/src/http-server/client/request-buffer/header.js +6 -0
- package/src/http-server/client/request-buffer/index.js +91 -13
- package/src/http-server/client/request-parser.js +26 -0
- package/src/http-server/client/request-runner.js +15 -3
- package/src/http-server/client/request.js +17 -0
- package/src/http-server/client/response.js +41 -1
- package/src/http-server/index.js +32 -4
- package/src/http-server/server-client.js +33 -2
- package/src/http-server/worker-handler/index.js +42 -9
- package/src/http-server/worker-handler/worker-script.js +2 -0
- package/src/http-server/worker-handler/worker-thread.js +34 -6
- package/src/logger.js +21 -15
- package/src/routes/app-routes.js +1 -1
- package/src/testing/test-files-finder.js +96 -9
- package/src/testing/test-runner.js +77 -25
- package/src/utils/backtrace-cleaner.js +6 -4
- package/src/utils/ensure-error.js +13 -0
- package/src/utils/file-exists.js +3 -1
- package/src/utils/rest-args-error.js +2 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {object} MigrationObjectType
|
|
3
|
+
* @property {number} date
|
|
4
|
+
* @property {string} file
|
|
5
|
+
* @property {string} [fullPath]
|
|
6
|
+
* @property {string} migrationClassName
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {function() : typeof import("../migration/index.js").default} ImportCallbackType
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {function(string) : Promise<typeof import("../migration/index.js").default>} ImportFullpathCallbackType
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {() => Promise<typeof import("../migration/index.js").default>} RequireMigrationType
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {(id: string) => {default: typeof import("../migration/index.js").default}} RequireMigrationContextRequireType
|
|
23
|
+
* @typedef {RequireMigrationContextRequireType & {
|
|
24
|
+
* keys: () => string[],
|
|
25
|
+
* id: string
|
|
26
|
+
* }} RequireMigrationContextType
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
export {}
|
package/src/database/migrator.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import {digg} from "diggerize"
|
|
2
4
|
import * as inflection from "inflection"
|
|
3
5
|
import {Logger} from "../logger.js"
|
|
6
|
+
import {NotImplementedError} from "./migration/index.js"
|
|
4
7
|
import restArgsError from "../utils/rest-args-error.js"
|
|
5
8
|
import TableData from "./table-data/index.js"
|
|
6
9
|
|
|
7
10
|
export default class VelociousDatabaseMigrator {
|
|
11
|
+
/** @type {Record<string, Record<string, boolean>>} */
|
|
12
|
+
migrationsVersions = {}
|
|
13
|
+
|
|
8
14
|
/**
|
|
9
15
|
* @param {object} args
|
|
10
16
|
* @param {import("../configuration.js").default} args.configuration
|
|
@@ -60,8 +66,8 @@ export default class VelociousDatabaseMigrator {
|
|
|
60
66
|
|
|
61
67
|
/**
|
|
62
68
|
* @param {string} dbIdentifier
|
|
63
|
-
* @param {
|
|
64
|
-
* @returns {
|
|
69
|
+
* @param {number} version
|
|
70
|
+
* @returns {boolean}
|
|
65
71
|
*/
|
|
66
72
|
hasRunMigrationVersion(dbIdentifier, version) {
|
|
67
73
|
if (!this.migrationsVersions) throw new Error("Migrations versions hasn't been loaded yet")
|
|
@@ -74,12 +80,18 @@ export default class VelociousDatabaseMigrator {
|
|
|
74
80
|
return false
|
|
75
81
|
}
|
|
76
82
|
|
|
83
|
+
/**
|
|
84
|
+
* @param {import("./migrator/types.js").MigrationObjectType[]} files
|
|
85
|
+
* @param {import("./migrator/types.js").ImportFullpathCallbackType} importCallback
|
|
86
|
+
*/
|
|
77
87
|
async migrateFiles(files, importCallback) {
|
|
78
88
|
await this.configuration.ensureConnections(async () => {
|
|
79
89
|
for (const migration of files) {
|
|
80
90
|
await this.runMigrationFile({
|
|
81
91
|
migration,
|
|
82
92
|
requireMigration: async () => {
|
|
93
|
+
if (!migration.fullPath) throw new Error(`Migration didn't have a fullPath key: ${Object.keys(migration).join(", ")}`)
|
|
94
|
+
|
|
83
95
|
const migrationImport = await importCallback(migration.fullPath)
|
|
84
96
|
|
|
85
97
|
if (!migrationImport) {
|
|
@@ -94,46 +106,47 @@ export default class VelociousDatabaseMigrator {
|
|
|
94
106
|
}
|
|
95
107
|
|
|
96
108
|
/**
|
|
97
|
-
* @param {
|
|
109
|
+
* @param {import("./migrator/types.js").RequireMigrationContextType} requireContext
|
|
98
110
|
* @returns {Promise<void>}
|
|
99
111
|
*/
|
|
100
112
|
async migrateFilesFromRequireContext(requireContext) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
.map((file) => {
|
|
104
|
-
// "13,14" because somes "require-context"-npm-module deletes first character!?
|
|
105
|
-
const match = file.match(/(\d{13,14})-(.+)\.js$/)
|
|
113
|
+
/** @type {import("./migrator/types.js").MigrationObjectType[]} */
|
|
114
|
+
let files = []
|
|
106
115
|
|
|
107
|
-
|
|
116
|
+
for (const file of requireContext.keys()) {
|
|
117
|
+
// "13,14" because somes "require-context"-npm-module deletes first character!?
|
|
118
|
+
const match = file.match(/(\d{13,14})-(.+)\.js$/)
|
|
108
119
|
|
|
109
|
-
|
|
110
|
-
let fileName = file
|
|
111
|
-
let dateNumber = match[1]
|
|
120
|
+
if (!match) continue
|
|
112
121
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
122
|
+
// Fix require-context-npm-module deletes first character
|
|
123
|
+
let fileName = file
|
|
124
|
+
let dateNumber = match[1]
|
|
117
125
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
126
|
+
if (dateNumber.length == 13) {
|
|
127
|
+
dateNumber = `2${dateNumber}`
|
|
128
|
+
fileName = `2${fileName}`
|
|
129
|
+
}
|
|
122
130
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
131
|
+
// Parse regex
|
|
132
|
+
const date = parseInt(dateNumber)
|
|
133
|
+
const migrationName = match[2]
|
|
134
|
+
const migrationClassName = inflection.camelize(migrationName.replaceAll("-", "_"))
|
|
135
|
+
|
|
136
|
+
files.push({
|
|
137
|
+
file: fileName,
|
|
138
|
+
date,
|
|
139
|
+
migrationClassName
|
|
128
140
|
})
|
|
129
|
-
|
|
130
|
-
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
files = files.sort((migration1, migration2) => migration1.date - migration2.date)
|
|
131
144
|
|
|
132
145
|
await this.configuration.ensureConnections(async () => {
|
|
133
146
|
for (const migration of files) {
|
|
134
147
|
await this.runMigrationFile({
|
|
135
148
|
migration,
|
|
136
|
-
requireMigration: () => requireContext(migration.file).default
|
|
149
|
+
requireMigration: async () => requireContext(migration.file).default
|
|
137
150
|
})
|
|
138
151
|
}
|
|
139
152
|
})
|
|
@@ -174,6 +187,7 @@ export default class VelociousDatabaseMigrator {
|
|
|
174
187
|
}
|
|
175
188
|
|
|
176
189
|
/**
|
|
190
|
+
* @param {import("./drivers/base.js").default} db
|
|
177
191
|
* @returns {Promise<boolean>}
|
|
178
192
|
*/
|
|
179
193
|
async migrationsTableExist(db) {
|
|
@@ -185,34 +199,39 @@ export default class VelociousDatabaseMigrator {
|
|
|
185
199
|
}
|
|
186
200
|
|
|
187
201
|
/**
|
|
202
|
+
* @param {import("./migrator/types.js").RequireMigrationContextType} requireContext
|
|
188
203
|
* @returns {Promise<void>}
|
|
189
204
|
*/
|
|
190
205
|
async executeRequireContext(requireContext) {
|
|
191
206
|
const migrationFiles = requireContext.keys()
|
|
192
|
-
const files = migrationFiles
|
|
193
|
-
.map((file) => {
|
|
194
|
-
const match = file.match(/^(\d{14})-(.+)\.js$/)
|
|
195
207
|
|
|
196
|
-
|
|
208
|
+
/** @type {import("./migrator/types.js").MigrationObjectType[]} */
|
|
209
|
+
let files = []
|
|
197
210
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
const migrationClassName = inflection.camelize(migrationName)
|
|
211
|
+
for (const file of migrationFiles) {
|
|
212
|
+
const match = file.match(/^(\d{14})-(.+)\.js$/)
|
|
201
213
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
214
|
+
if (!match) continue
|
|
215
|
+
|
|
216
|
+
const date = parseInt(match[1])
|
|
217
|
+
const migrationName = match[2]
|
|
218
|
+
const migrationClassName = inflection.camelize(migrationName)
|
|
219
|
+
|
|
220
|
+
const migrationObject = /** @type {import("./migrator/types.js").MigrationObjectType} */ ({
|
|
221
|
+
file,
|
|
222
|
+
date,
|
|
223
|
+
migrationClassName
|
|
208
224
|
})
|
|
209
|
-
|
|
210
|
-
.
|
|
225
|
+
|
|
226
|
+
files.push(migrationObject)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
files = files.sort((migration1, migration2) => migration1.date - migration2.date)
|
|
211
230
|
|
|
212
231
|
for (const migration of files) {
|
|
213
232
|
await this.runMigrationFile({
|
|
214
233
|
migration,
|
|
215
|
-
|
|
234
|
+
requireMigration: async () => requireContext(migration.file).default
|
|
216
235
|
})
|
|
217
236
|
}
|
|
218
237
|
}
|
|
@@ -257,8 +276,8 @@ export default class VelociousDatabaseMigrator {
|
|
|
257
276
|
}
|
|
258
277
|
|
|
259
278
|
/**
|
|
260
|
-
* @param {
|
|
261
|
-
* @param {
|
|
279
|
+
* @param {import("./migrator/types.js").MigrationObjectType[]} files
|
|
280
|
+
* @param {import("./migrator/types.js").ImportFullpathCallbackType} importCallback Function to import a file
|
|
262
281
|
* @returns {Promise<void>}
|
|
263
282
|
*/
|
|
264
283
|
async rollback(files, importCallback) {
|
|
@@ -277,17 +296,22 @@ export default class VelociousDatabaseMigrator {
|
|
|
277
296
|
|
|
278
297
|
await this.runMigrationFile({
|
|
279
298
|
migration,
|
|
280
|
-
requireMigration: async () =>
|
|
299
|
+
requireMigration: async () => {
|
|
300
|
+
if (!migration.fullPath) throw new Error(`Migration didn't have a fullPath key: ${Object.keys(migration).join(", ")}`)
|
|
301
|
+
|
|
302
|
+
return await importCallback(migration.fullPath)
|
|
303
|
+
},
|
|
281
304
|
direction: "down"
|
|
282
305
|
})
|
|
283
306
|
}
|
|
284
307
|
|
|
285
308
|
/**
|
|
286
|
-
* @returns {Promise<string |
|
|
309
|
+
* @returns {Promise<string | undefined>} The latest migration version
|
|
287
310
|
*/
|
|
288
311
|
async _latestMigrationVersion() {
|
|
289
312
|
if (!this.migrationsVersions) await this.loadMigrationsVersions()
|
|
290
313
|
|
|
314
|
+
/** @type {string | undefined} */
|
|
291
315
|
let highestVersion
|
|
292
316
|
|
|
293
317
|
for (const dbIdentifier in this.migrationsVersions) {
|
|
@@ -303,9 +327,9 @@ export default class VelociousDatabaseMigrator {
|
|
|
303
327
|
|
|
304
328
|
/**
|
|
305
329
|
* @param {object} args
|
|
306
|
-
* @param {
|
|
307
|
-
* @param {
|
|
308
|
-
* @param {string} args.direction
|
|
330
|
+
* @param {import("./migrator/types.js").MigrationObjectType} args.migration
|
|
331
|
+
* @param {import("./migrator/types.js").RequireMigrationType} args.requireMigration
|
|
332
|
+
* @param {string} [args.direction]
|
|
309
333
|
*/
|
|
310
334
|
async runMigrationFile({migration, requireMigration, direction = "up"}) {
|
|
311
335
|
if (!this.configuration) throw new Error("No configuration set")
|
|
@@ -354,17 +378,28 @@ export default class VelociousDatabaseMigrator {
|
|
|
354
378
|
const MigrationClass = migrationClass
|
|
355
379
|
const migrationInstance = new MigrationClass({
|
|
356
380
|
configuration: this.configuration,
|
|
381
|
+
databaseIdentifier: dbIdentifier,
|
|
357
382
|
db
|
|
358
383
|
})
|
|
359
384
|
const dateString = `${digg(migration, "date")}`
|
|
360
385
|
|
|
361
386
|
if (direction == "up") {
|
|
362
|
-
|
|
387
|
+
try {
|
|
363
388
|
await migrationInstance.change()
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
389
|
+
} catch (changeError) {
|
|
390
|
+
if (changeError instanceof NotImplementedError) {
|
|
391
|
+
try {
|
|
392
|
+
await migrationInstance.up()
|
|
393
|
+
} catch (upError) {
|
|
394
|
+
if (upError instanceof NotImplementedError) {
|
|
395
|
+
throw new Error(`'change' or 'up' didn't exist on migration: ${migration.file}`)
|
|
396
|
+
} else {
|
|
397
|
+
throw upError
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
} else {
|
|
401
|
+
throw changeError
|
|
402
|
+
}
|
|
368
403
|
}
|
|
369
404
|
|
|
370
405
|
const existingSchemaMigrations = await db.newQuery()
|
|
@@ -376,10 +411,14 @@ export default class VelociousDatabaseMigrator {
|
|
|
376
411
|
await db.insert({tableName: "schema_migrations", data: {version: dateString}})
|
|
377
412
|
}
|
|
378
413
|
} else if (direction == "down") {
|
|
379
|
-
|
|
414
|
+
try {
|
|
380
415
|
await migrationInstance.down()
|
|
381
|
-
}
|
|
382
|
-
|
|
416
|
+
} catch (downError) {
|
|
417
|
+
if (downError instanceof NotImplementedError) {
|
|
418
|
+
throw new Error(`'down' didn't exist on migration: ${migration.file} or migrating down with a change method isn't currently supported`)
|
|
419
|
+
} else {
|
|
420
|
+
throw downError
|
|
421
|
+
}
|
|
383
422
|
}
|
|
384
423
|
|
|
385
424
|
await db.delete({tableName: "schema_migrations", conditions: {version: dateString}})
|
|
@@ -1,18 +1,38 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import {AsyncLocalStorage} from "async_hooks"
|
|
2
4
|
import BasePool from "./base.js"
|
|
3
5
|
|
|
4
6
|
export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends BasePool {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
asyncLocalStorage = new AsyncLocalStorage()
|
|
8
|
+
|
|
9
|
+
/** @type {import("../drivers/base.js").default[]} */
|
|
10
|
+
connections = []
|
|
11
|
+
|
|
12
|
+
/** @type {Record<number, import("../drivers/base.js").default>} */
|
|
13
|
+
connectionsInUse = {}
|
|
14
|
+
|
|
15
|
+
idSeq = 0
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {object} args
|
|
19
|
+
* @param {import("../../configuration.js").default} args.configuration
|
|
20
|
+
* @param {string} args.identifier
|
|
21
|
+
*/
|
|
22
|
+
constructor({configuration, identifier}) {
|
|
23
|
+
super({configuration, identifier})
|
|
11
24
|
}
|
|
12
25
|
|
|
26
|
+
/**
|
|
27
|
+
* @param {import("../drivers/base.js").default} connection
|
|
28
|
+
*/
|
|
13
29
|
checkin(connection) {
|
|
14
30
|
const id = connection.getIdSeq()
|
|
15
31
|
|
|
32
|
+
if (typeof id !== "number") {
|
|
33
|
+
throw new Error(`idSeq on connection wasn't set? '${typeof id}' = ${id}`)
|
|
34
|
+
}
|
|
35
|
+
|
|
16
36
|
if (id in this.connectionsInUse) {
|
|
17
37
|
delete this.connectionsInUse[id]
|
|
18
38
|
}
|
|
@@ -22,6 +42,9 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
22
42
|
this.connections.push(connection)
|
|
23
43
|
}
|
|
24
44
|
|
|
45
|
+
/**
|
|
46
|
+
* @returns {Promise<import("../drivers/base.js").default>}
|
|
47
|
+
*/
|
|
25
48
|
async checkout() {
|
|
26
49
|
let connection = this.connections.shift()
|
|
27
50
|
|
|
@@ -39,6 +62,9 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
39
62
|
return connection
|
|
40
63
|
}
|
|
41
64
|
|
|
65
|
+
/**
|
|
66
|
+
* @param {function(import("../drivers/base.js").default) : void} callback
|
|
67
|
+
*/
|
|
42
68
|
async withConnection(callback) {
|
|
43
69
|
const connection = await this.checkout()
|
|
44
70
|
const id = connection.getIdSeq()
|
|
@@ -52,6 +78,9 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
52
78
|
})
|
|
53
79
|
}
|
|
54
80
|
|
|
81
|
+
/**
|
|
82
|
+
* @returns {import("../drivers/base.js").default}
|
|
83
|
+
*/
|
|
55
84
|
getCurrentConnection() {
|
|
56
85
|
const id = this.asyncLocalStorage.getStore()
|
|
57
86
|
|
|
@@ -63,6 +92,12 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
63
92
|
throw new Error(`Connection ${id} doesn't exist any more - has it been checked in again?`)
|
|
64
93
|
}
|
|
65
94
|
|
|
66
|
-
|
|
95
|
+
const currentConnection = this.connectionsInUse[id]
|
|
96
|
+
|
|
97
|
+
if (!currentConnection) {
|
|
98
|
+
throw new Error(`Couldn't get current connection from that ID: ${id}`)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return currentConnection
|
|
67
102
|
}
|
|
68
103
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {typeof import("./base.js").default} PoolBase
|
|
3
|
+
*/
|
|
4
|
+
export default function baseMethodsForward(PoolBase) {
|
|
5
|
+
const forwardMethods = [
|
|
6
|
+
"alterTable",
|
|
7
|
+
"alterTableSql",
|
|
8
|
+
"createIndex",
|
|
9
|
+
"createIndexSql",
|
|
10
|
+
"createTable",
|
|
11
|
+
"createTableSql",
|
|
12
|
+
"delete",
|
|
13
|
+
"deleteSql",
|
|
14
|
+
"getTables",
|
|
15
|
+
"insert",
|
|
16
|
+
"insertSql",
|
|
17
|
+
"primaryKeyType",
|
|
18
|
+
"query",
|
|
19
|
+
"quote",
|
|
20
|
+
"quoteColumn",
|
|
21
|
+
"quoteTable",
|
|
22
|
+
"select",
|
|
23
|
+
"update",
|
|
24
|
+
"updateSql"
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
for (const forwardMethod of forwardMethods) {
|
|
28
|
+
PoolBase.prototype[forwardMethod] = function(...args) {
|
|
29
|
+
const connection = this.getCurrentConnection()
|
|
30
|
+
const connectionMethod = connection[forwardMethod]
|
|
31
|
+
|
|
32
|
+
if (!connectionMethod) throw new Error(`${forwardMethod} isn't defined on driver`)
|
|
33
|
+
|
|
34
|
+
return connection[forwardMethod](...args)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -1,46 +1,96 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import Configuration from "../../configuration.js"
|
|
2
4
|
import {digg} from "diggerize"
|
|
3
5
|
import {Logger} from "../../logger.js"
|
|
6
|
+
import baseMethodsForward from "./base-methods-forward.js"
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
8
|
+
/** @type {{currentPool: VelociousDatabasePoolBase | null}} */
|
|
9
|
+
const shared = {
|
|
10
|
+
currentPool: null
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
class VelociousDatabasePoolBase {
|
|
14
|
+
/**
|
|
15
|
+
* @returns {VelociousDatabasePoolBase}
|
|
16
|
+
*/
|
|
12
17
|
static current() {
|
|
13
|
-
if (!
|
|
14
|
-
globalThis.velociousDatabasePoolBase.current = new this()
|
|
15
|
-
}
|
|
18
|
+
if (!shared.currentPool) throw new Error("A database pool hasn't been set")
|
|
16
19
|
|
|
17
|
-
return
|
|
20
|
+
return shared.currentPool
|
|
18
21
|
}
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
/**
|
|
24
|
+
* @param {object} args
|
|
25
|
+
* @param {Configuration} args.configuration
|
|
26
|
+
* @param {string} args.identifier
|
|
27
|
+
*/
|
|
28
|
+
constructor({configuration, identifier}) {
|
|
29
|
+
this.configuration = configuration || Configuration.current()
|
|
22
30
|
|
|
23
31
|
if (!this.configuration) throw new Error("No configuration given")
|
|
24
|
-
if (!
|
|
32
|
+
if (!identifier) throw new Error("No identifier was given")
|
|
25
33
|
|
|
26
|
-
this.
|
|
27
|
-
this.connectionsInUse = {}
|
|
28
|
-
this.identifier = args.identifier
|
|
34
|
+
this.identifier = identifier
|
|
29
35
|
this.logger = new Logger(this)
|
|
30
36
|
}
|
|
31
37
|
|
|
38
|
+
/**
|
|
39
|
+
* @interface
|
|
40
|
+
* @param {import("../drivers/base.js").default} _connection
|
|
41
|
+
*/
|
|
42
|
+
checkin(_connection) { // eslint-disable-line no-unused-vars
|
|
43
|
+
throw new Error("'checkin' not implemented")
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @interface
|
|
48
|
+
* @returns {Promise<import("../drivers/base.js").default>}
|
|
49
|
+
*/
|
|
50
|
+
checkout() {
|
|
51
|
+
throw new Error("'checkout' not implemented")
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @interface
|
|
56
|
+
* @returns {import("../drivers/base.js").default}
|
|
57
|
+
*/
|
|
58
|
+
getCurrentConnection() {
|
|
59
|
+
throw new Error("'getCurrentConnection' not implemented")
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @returns {{driver: typeof import("../drivers/base.js").default, type: string}}
|
|
64
|
+
*/
|
|
32
65
|
getConfiguration() {
|
|
33
66
|
return digg(this.configuration.getDatabaseConfiguration(), this.identifier)
|
|
34
67
|
}
|
|
35
68
|
|
|
69
|
+
/**
|
|
70
|
+
* @interface
|
|
71
|
+
* @returns {string}
|
|
72
|
+
*/
|
|
73
|
+
primaryKeyType() {
|
|
74
|
+
throw new Error("'primaryKeyType' not implemented")
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @returns {void}
|
|
79
|
+
*/
|
|
36
80
|
setCurrent() {
|
|
37
|
-
|
|
81
|
+
shared.currentPool = this
|
|
38
82
|
}
|
|
39
83
|
|
|
84
|
+
/**
|
|
85
|
+
* @param {typeof import("../drivers/base.js").default} driverClass
|
|
86
|
+
*/
|
|
40
87
|
setDriverClass(driverClass) {
|
|
41
88
|
this.driverClass = driverClass
|
|
42
89
|
}
|
|
43
90
|
|
|
91
|
+
/**
|
|
92
|
+
* @returns {Promise<import("../drivers/base.js").default>}
|
|
93
|
+
*/
|
|
44
94
|
async spawnConnection() {
|
|
45
95
|
const databaseConfig = this.getConfiguration()
|
|
46
96
|
|
|
@@ -51,6 +101,11 @@ class VelociousDatabasePoolBase {
|
|
|
51
101
|
return connection
|
|
52
102
|
}
|
|
53
103
|
|
|
104
|
+
/**
|
|
105
|
+
* @param {object} config
|
|
106
|
+
* @param {typeof import("../drivers/base.js").default} config.driver
|
|
107
|
+
* @returns {Promise<import("../drivers/base.js").default>}
|
|
108
|
+
*/
|
|
54
109
|
async spawnConnectionWithConfiguration(config) {
|
|
55
110
|
const DriverClass = config.driver || this.driverClass
|
|
56
111
|
|
|
@@ -62,39 +117,17 @@ class VelociousDatabasePoolBase {
|
|
|
62
117
|
|
|
63
118
|
return connection
|
|
64
119
|
}
|
|
65
|
-
}
|
|
66
120
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
"delete",
|
|
75
|
-
"deleteSql",
|
|
76
|
-
"getTables",
|
|
77
|
-
"insert",
|
|
78
|
-
"insertSql",
|
|
79
|
-
"primaryKeyType",
|
|
80
|
-
"query",
|
|
81
|
-
"quote",
|
|
82
|
-
"quoteColumn",
|
|
83
|
-
"quoteTable",
|
|
84
|
-
"select",
|
|
85
|
-
"update",
|
|
86
|
-
"updateSql"
|
|
87
|
-
]
|
|
88
|
-
|
|
89
|
-
for (const forwardMethod of forwardMethods) {
|
|
90
|
-
VelociousDatabasePoolBase.prototype[forwardMethod] = function(...args) {
|
|
91
|
-
const connection = this.getCurrentConnection()
|
|
92
|
-
const connectionMethod = connection[forwardMethod]
|
|
93
|
-
|
|
94
|
-
if (!connectionMethod) throw new Error(`${forwardMethod} isn't defined on driver`)
|
|
95
|
-
|
|
96
|
-
return connection[forwardMethod](...args)
|
|
121
|
+
/**
|
|
122
|
+
* @interface
|
|
123
|
+
* @param {function(import("../drivers/base.js").default) : void} _callback
|
|
124
|
+
* @returns {Promise<void>}
|
|
125
|
+
*/
|
|
126
|
+
withConnection(_callback) { // eslint-disable-line no-unused-vars
|
|
127
|
+
throw new Error("'withConnection' not implemented")
|
|
97
128
|
}
|
|
98
129
|
}
|
|
99
130
|
|
|
131
|
+
baseMethodsForward(VelociousDatabasePoolBase)
|
|
132
|
+
|
|
100
133
|
export default VelociousDatabasePoolBase
|
|
@@ -1,10 +1,18 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import BasePool from "./base.js"
|
|
2
4
|
|
|
3
5
|
export default class VelociousDatabasePoolSingleMultiUser extends BasePool {
|
|
4
|
-
|
|
6
|
+
/**
|
|
7
|
+
* @param {import("../drivers/base.js").default} _connection
|
|
8
|
+
*/
|
|
9
|
+
checkin(_connection) { // eslint-disable-line no-unused-vars
|
|
5
10
|
// Do nothing
|
|
6
11
|
}
|
|
7
12
|
|
|
13
|
+
/**
|
|
14
|
+
* @returns {Promise<import("../drivers/base.js").default>}
|
|
15
|
+
*/
|
|
8
16
|
async checkout() {
|
|
9
17
|
if (!this.connection) {
|
|
10
18
|
this.connection = await this.spawnConnection()
|
|
@@ -13,11 +21,18 @@ export default class VelociousDatabasePoolSingleMultiUser extends BasePool {
|
|
|
13
21
|
return this.connection
|
|
14
22
|
}
|
|
15
23
|
|
|
24
|
+
/**
|
|
25
|
+
* @param {function(import("../drivers/base.js").default) : void} callback
|
|
26
|
+
*/
|
|
16
27
|
async withConnection(callback) {
|
|
17
|
-
await this.checkout()
|
|
18
|
-
|
|
28
|
+
const connection = await this.checkout()
|
|
29
|
+
|
|
30
|
+
await callback(connection)
|
|
19
31
|
}
|
|
20
32
|
|
|
33
|
+
/**
|
|
34
|
+
* @returns {import("../drivers/base.js").default}
|
|
35
|
+
*/
|
|
21
36
|
getCurrentConnection() {
|
|
22
37
|
if (!this.connection) {
|
|
23
38
|
throw new Error("A connection hasn't been made yet")
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
2
3
|
import QueryBase from "./base.js"
|
|
3
4
|
import restArgsError from "../../utils/rest-args-error.js"
|
|
4
5
|
import TableData from "../table-data/index.js"
|
|
@@ -6,8 +7,7 @@ import TableData from "../table-data/index.js"
|
|
|
6
7
|
export default class VelociousDatabaseQueryAlterTableBase extends QueryBase {
|
|
7
8
|
/**
|
|
8
9
|
* @param {object} args
|
|
9
|
-
* @
|
|
10
|
-
* @param {Tdriver} args.driver
|
|
10
|
+
* @param {import("../drivers/base.js").default} args.driver
|
|
11
11
|
* @param {TableData} args.tableData
|
|
12
12
|
*/
|
|
13
13
|
constructor({driver, tableData, ...restArgs}) {
|
|
@@ -25,7 +25,7 @@ export default class VelociousDatabaseQueryAlterTableBase extends QueryBase {
|
|
|
25
25
|
toSqls() {
|
|
26
26
|
const databaseType = this.getDriver().getType()
|
|
27
27
|
const sqls = []
|
|
28
|
-
const {tableData} =
|
|
28
|
+
const {tableData} = this
|
|
29
29
|
const options = this.getOptions()
|
|
30
30
|
|
|
31
31
|
let sql = `ALTER TABLE ${options.quoteTableName(tableData.getName())} `
|