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.
Files changed (86) hide show
  1. package/eslint.config.js +1 -0
  2. package/package.json +2 -1
  3. package/spec/database/connection/drivers/mysql/query-parser-spec.js +4 -4
  4. package/spec/http-server/post-spec.js +2 -0
  5. package/src/application.js +27 -9
  6. package/src/configuration-resolver.js +29 -10
  7. package/src/configuration-types.js +44 -0
  8. package/src/configuration.js +63 -33
  9. package/src/database/drivers/base-column.js +6 -1
  10. package/src/database/drivers/base-columns-index.js +11 -1
  11. package/src/database/drivers/base-foreign-key.js +45 -0
  12. package/src/database/drivers/base-table.js +24 -2
  13. package/src/database/drivers/base.js +211 -39
  14. package/src/database/drivers/mssql/index.js +1 -3
  15. package/src/database/drivers/sqlite/sql/alter-table.js +4 -2
  16. package/src/database/handler.js +5 -0
  17. package/src/database/migration/index.js +77 -19
  18. package/src/database/migrator/files-finder.js +21 -22
  19. package/src/database/migrator/types.js +29 -0
  20. package/src/database/migrator.js +98 -59
  21. package/src/database/pool/async-tracked-multi-connection.js +42 -7
  22. package/src/database/pool/base-methods-forward.js +37 -0
  23. package/src/database/pool/base.js +79 -46
  24. package/src/database/pool/single-multi-use.js +18 -3
  25. package/src/database/query/alter-table-base.js +4 -4
  26. package/src/database/query/base.js +9 -2
  27. package/src/database/query/create-database-base.js +8 -0
  28. package/src/database/query/create-index-base.js +20 -5
  29. package/src/database/query/create-table-base.js +28 -9
  30. package/src/database/query/from-base.js +17 -0
  31. package/src/database/query/from-plain.js +8 -3
  32. package/src/database/query/from-table.js +8 -3
  33. package/src/database/query/index.js +43 -32
  34. package/src/database/query/join-base.js +28 -1
  35. package/src/database/query/join-object.js +67 -0
  36. package/src/database/query/join-plain.js +6 -1
  37. package/src/database/query/order-base.js +18 -0
  38. package/src/database/query/order-plain.js +8 -2
  39. package/src/database/query/select-base.js +15 -0
  40. package/src/database/query/select-plain.js +6 -1
  41. package/src/database/query/select-table-and-column.js +8 -2
  42. package/src/database/query/where-base.js +23 -1
  43. package/src/database/query/where-hash.js +15 -0
  44. package/src/database/query/where-plain.js +6 -0
  45. package/src/database/query-parser/base-query-parser.js +8 -2
  46. package/src/database/query-parser/from-parser.js +2 -0
  47. package/src/database/query-parser/joins-parser.js +10 -45
  48. package/src/database/query-parser/select-parser.js +2 -0
  49. package/src/database/record/index.js +1 -1
  50. package/src/database/table-data/index.js +39 -121
  51. package/src/database/table-data/table-column.js +54 -25
  52. package/src/database/table-data/table-foreign-key.js +5 -3
  53. package/src/database/table-data/table-index.js +12 -6
  54. package/src/database/table-data/table-reference.js +2 -0
  55. package/src/database/use-database.js +4 -2
  56. package/src/environment-handlers/base.js +41 -8
  57. package/src/environment-handlers/node/cli/commands/destroy/migration.js +3 -0
  58. package/src/environment-handlers/node/cli/commands/generate/migration.js +3 -0
  59. package/src/environment-handlers/node/cli/commands/generate/model.js +3 -0
  60. package/src/environment-handlers/node/cli/commands/init.js +3 -0
  61. package/src/environment-handlers/node/cli/commands/test.js +17 -3
  62. package/src/environment-handlers/node.js +59 -28
  63. package/src/http-client/header.js +6 -0
  64. package/src/http-client/request.js +31 -5
  65. package/src/http-client/response.js +31 -7
  66. package/src/http-server/client/index.js +24 -4
  67. package/src/http-server/client/request-buffer/form-data-part.js +11 -0
  68. package/src/http-server/client/request-buffer/header.js +6 -0
  69. package/src/http-server/client/request-buffer/index.js +91 -13
  70. package/src/http-server/client/request-parser.js +26 -0
  71. package/src/http-server/client/request-runner.js +15 -3
  72. package/src/http-server/client/request.js +17 -0
  73. package/src/http-server/client/response.js +41 -1
  74. package/src/http-server/index.js +32 -4
  75. package/src/http-server/server-client.js +33 -2
  76. package/src/http-server/worker-handler/index.js +42 -9
  77. package/src/http-server/worker-handler/worker-script.js +2 -0
  78. package/src/http-server/worker-handler/worker-thread.js +34 -6
  79. package/src/logger.js +21 -15
  80. package/src/routes/app-routes.js +1 -1
  81. package/src/testing/test-files-finder.js +96 -9
  82. package/src/testing/test-runner.js +77 -25
  83. package/src/utils/backtrace-cleaner.js +6 -4
  84. package/src/utils/ensure-error.js +13 -0
  85. package/src/utils/file-exists.js +3 -1
  86. 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 {}
@@ -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 {string} version
64
- * @returns {Promise<boolean>}
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 {*} requireContext
109
+ * @param {import("./migrator/types.js").RequireMigrationContextType} requireContext
98
110
  * @returns {Promise<void>}
99
111
  */
100
112
  async migrateFilesFromRequireContext(requireContext) {
101
- const files = requireContext
102
- .keys()
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
- if (!match) return null
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
- // Fix require-context-npm-module deletes first character
110
- let fileName = file
111
- let dateNumber = match[1]
120
+ if (!match) continue
112
121
 
113
- if (dateNumber.length == 13) {
114
- dateNumber = `2${dateNumber}`
115
- fileName = `2${fileName}`
116
- }
122
+ // Fix require-context-npm-module deletes first character
123
+ let fileName = file
124
+ let dateNumber = match[1]
117
125
 
118
- // Parse regex
119
- const date = parseInt(dateNumber)
120
- const migrationName = match[2]
121
- const migrationClassName = inflection.camelize(migrationName.replaceAll("-", "_"))
126
+ if (dateNumber.length == 13) {
127
+ dateNumber = `2${dateNumber}`
128
+ fileName = `2${fileName}`
129
+ }
122
130
 
123
- return {
124
- file: fileName,
125
- date,
126
- migrationClassName
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
- .filter((migration) => Boolean(migration))
130
- .sort((migration1, migration2) => migration1.date - migration2.date)
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
- if (!match) return null
208
+ /** @type {import("./migrator/types.js").MigrationObjectType[]} */
209
+ let files = []
197
210
 
198
- const date = parseInt(match[1])
199
- const migrationName = match[2]
200
- const migrationClassName = inflection.camelize(migrationName)
211
+ for (const file of migrationFiles) {
212
+ const match = file.match(/^(\d{14})-(.+)\.js$/)
201
213
 
202
- return {
203
- file,
204
- fullPath: `${migrationsPath}/${file}`, // eslint-disable-line no-undef
205
- date,
206
- migrationClassName
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
- .filter((migration) => Boolean(migration))
210
- .sort((migration1, migration2) => migration1.date - migration2.date)
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
- require: () => requireContext(migration.file).default
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 {{date: number}[]} files
261
- * @param {function(string) : void} importCallback Function to import a file
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 () => await importCallback(migration.fullPath),
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 | null>} The latest migration version
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 {object} args.migration
307
- * @param {function() : void} args.requireMigration
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
- if (migrationInstance.change) {
387
+ try {
363
388
  await migrationInstance.change()
364
- } else if (migrationInstance.up) {
365
- await migrationInstance.up()
366
- } else {
367
- throw new Error(`'change' or 'up' didn't exist on migration: ${migration.file}`)
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
- if (migrationInstance.down) {
414
+ try {
380
415
  await migrationInstance.down()
381
- } else {
382
- throw new Error(`'down' didn't exist on migration: ${migration.file}`)
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
- constructor(args = {}) {
6
- super(args)
7
- this.connections = []
8
- this.connectionsInUse = {}
9
- this.asyncLocalStorage = new AsyncLocalStorage()
10
- this.idSeq = 0
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
- return this.connectionsInUse[id]
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
- if (!globalThis.velociousDatabasePoolBase) {
6
- globalThis.velociousDatabasePoolBase = {
7
- current: null
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 (!globalThis.velociousDatabasePoolBase.current) {
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 globalThis.velociousDatabasePoolBase.current
20
+ return shared.currentPool
18
21
  }
19
22
 
20
- constructor(args = {}) {
21
- this.configuration = args.configuration || Configuration.current()
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 (!args.identifier) throw new Error("No identifier was given")
32
+ if (!identifier) throw new Error("No identifier was given")
25
33
 
26
- this.connections = []
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
- globalThis.velociousDatabasePoolBase.current = this
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
- const forwardMethods = [
68
- "alterTable",
69
- "alterTableSql",
70
- "createIndex",
71
- "createIndexSql",
72
- "createTable",
73
- "createTableSql",
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
- checkin(connection) { // eslint-disable-line no-unused-vars
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() // Ensure a connection is present
18
- await callback(this.connection)
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
- import {digs} from "diggerize"
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
- * @template Tdriver extends import("../driver/base.js").default
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} = digs(this, "tableData")
28
+ const {tableData} = this
29
29
  const options = this.getOptions()
30
30
 
31
31
  let sql = `ALTER TABLE ${options.quoteTableName(tableData.getName())} `