velocious 1.0.29 → 1.0.31
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 +5 -2
- package/peak_flow.yml +21 -0
- package/spec/cli/commands/db/create-spec.js +14 -2
- package/spec/cli/commands/db/migrate-spec.js +56 -25
- package/spec/database/drivers/mysql/connection-spec.js +2 -2
- package/spec/dummy/index.js +8 -7
- package/spec/dummy/src/config/configuration.example.js +25 -3
- package/spec/dummy/src/config/configuration.mariadb.js +97 -0
- package/spec/dummy/src/config/configuration.peakflow.mariadb.js +26 -3
- package/spec/dummy/src/config/configuration.peakflow.mssql.js +75 -0
- package/spec/dummy/src/config/configuration.peakflow.sqlite.js +27 -3
- package/spec/dummy/src/config/configuration.sqlite.js +58 -4
- package/spec/dummy/src/database/migrations/20250903112845-create-accounts.js +18 -0
- package/src/cli/commands/db/create.js +25 -15
- package/src/cli/commands/db/migrate.js +4 -82
- package/src/cli/commands/db/reset.js +40 -0
- package/src/configuration.js +71 -18
- package/src/database/drivers/base.js +97 -13
- package/src/database/drivers/mssql/column.js +10 -0
- package/src/database/drivers/mssql/connect-connection.js +12 -0
- package/src/database/drivers/mssql/foreign-key.js +13 -0
- package/src/database/drivers/mssql/index.js +216 -0
- package/src/database/drivers/mssql/options.js +43 -0
- package/src/database/drivers/mssql/query-parser.js +4 -0
- package/src/database/drivers/mssql/sql/create-database.js +28 -0
- package/src/database/drivers/mssql/sql/create-index.js +4 -0
- package/src/database/drivers/mssql/sql/create-table.js +4 -0
- package/src/database/drivers/mssql/sql/delete.js +19 -0
- package/src/database/drivers/mssql/sql/drop-table.js +4 -0
- package/src/database/drivers/mssql/sql/insert.js +4 -0
- package/src/database/drivers/mssql/sql/update.js +31 -0
- package/src/database/drivers/mssql/table.js +65 -0
- package/src/database/drivers/mysql/index.js +29 -18
- package/src/database/drivers/mysql/query.js +1 -1
- package/src/database/drivers/mysql/sql/drop-table.js +4 -0
- package/src/database/drivers/sqlite/base.js +25 -23
- package/src/database/drivers/sqlite/index.native.js +10 -1
- package/src/database/drivers/sqlite/sql/drop-table.js +4 -0
- package/src/database/initializer-from-require-context.js +3 -1
- package/src/database/migration/index.js +32 -23
- package/src/database/migrator.js +177 -28
- package/src/database/pool/async-tracked-multi-connection.js +2 -3
- package/src/database/pool/base.js +15 -3
- package/src/database/query/base.js +24 -4
- package/src/database/query/create-database-base.js +1 -3
- package/src/database/query/create-index-base.js +13 -4
- package/src/database/query/create-table-base.js +27 -11
- package/src/database/query/drop-table-base.js +39 -0
- package/src/database/query/index.js +5 -1
- package/src/database/query/insert-base.js +31 -6
- package/src/database/query-parser/limit-parser.js +11 -2
- package/src/database/query-parser/options.js +20 -8
- package/src/database/record/index.js +19 -3
- package/src/database/use-database.js +5 -4
- package/src/routes/base-route.js +7 -0
- package/src/routes/post-route.js +24 -0
- package/src/routes/resolver.js +1 -1
- package/src/templates/configuration.js +36 -3
- package/src/testing/test-runner.js +1 -1
- package/src/utils/nest-callbacks.js +15 -0
- package/src/big-brother.js +0 -37
- package/src/database/migrate-from-require-context.js +0 -72
- package/src/spec/index.js +0 -5
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import restArgsError from "../../utils/rest-args-error.js"
|
|
2
2
|
|
|
3
3
|
export default class VelociousDatabaseQueryInsertBase {
|
|
4
|
-
constructor({columns, data, driver, multiple, tableName, rows, ...restArgs}) {
|
|
4
|
+
constructor({columns, data, driver, multiple, tableName, returnLastInsertedColumnName, rows, ...restArgs}) {
|
|
5
5
|
if (!driver) throw new Error("No driver given to insert base")
|
|
6
6
|
if (!tableName) throw new Error(`Invalid table name given to insert base: ${tableName}`)
|
|
7
7
|
|
|
@@ -11,6 +11,7 @@ export default class VelociousDatabaseQueryInsertBase {
|
|
|
11
11
|
this.data = data
|
|
12
12
|
this.driver = driver
|
|
13
13
|
this.multiple = multiple
|
|
14
|
+
this.returnLastInsertedColumnName = returnLastInsertedColumnName
|
|
14
15
|
this.rows = rows
|
|
15
16
|
this.tableName = tableName
|
|
16
17
|
}
|
|
@@ -20,9 +21,23 @@ export default class VelociousDatabaseQueryInsertBase {
|
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
toSql() {
|
|
23
|
-
|
|
24
|
+
const {driver} = this
|
|
25
|
+
|
|
26
|
+
let sql = `INSERT INTO ${driver.quoteTable(this.tableName)}`
|
|
24
27
|
let count = 0
|
|
25
|
-
let columns
|
|
28
|
+
let columns, lastInsertedSQL
|
|
29
|
+
|
|
30
|
+
if (this.returnLastInsertedColumnName) {
|
|
31
|
+
if (driver.getType() == "mssql") {
|
|
32
|
+
lastInsertedSQL = ` OUTPUT INSERTED.${driver.quoteColumn(this.returnLastInsertedColumnName)} AS lastInsertID`
|
|
33
|
+
|
|
34
|
+
if (Object.keys(this.data).length <= 0) {
|
|
35
|
+
sql += lastInsertedSQL
|
|
36
|
+
}
|
|
37
|
+
} else if (driver.getType() == "mysql") {
|
|
38
|
+
lastInsertedSQL = ` RETURNING ${driver.quoteColumn(this.returnLastInsertedColumnName)} AS lastInsertID`
|
|
39
|
+
}
|
|
40
|
+
}
|
|
26
41
|
|
|
27
42
|
if (this.columns && this.rows) {
|
|
28
43
|
columns = this.columns
|
|
@@ -38,13 +53,17 @@ export default class VelociousDatabaseQueryInsertBase {
|
|
|
38
53
|
for (const columnName of columns) {
|
|
39
54
|
if (count > 0) sql += ", "
|
|
40
55
|
|
|
41
|
-
sql +=
|
|
56
|
+
sql += driver.quoteColumn(columnName)
|
|
42
57
|
count++
|
|
43
58
|
}
|
|
44
59
|
|
|
45
60
|
sql += ")"
|
|
46
61
|
}
|
|
47
62
|
|
|
63
|
+
if (this.returnLastInsertedColumnName && driver.getType() == "mssql" && Object.keys(this.data).length > 0) {
|
|
64
|
+
sql += lastInsertedSQL
|
|
65
|
+
}
|
|
66
|
+
|
|
48
67
|
if (this.columns && this.rows) {
|
|
49
68
|
if (this.rows.length > 0) {
|
|
50
69
|
sql += " VALUES "
|
|
@@ -62,13 +81,19 @@ export default class VelociousDatabaseQueryInsertBase {
|
|
|
62
81
|
if (Object.keys(this.data).length > 0) {
|
|
63
82
|
sql += " VALUES "
|
|
64
83
|
sql += this._valuesSql(Object.values(this.data))
|
|
65
|
-
} else if (
|
|
84
|
+
} else if (driver.getType() == "sqlite" || driver.getType() == "mssql") {
|
|
66
85
|
sql += " DEFAULT VALUES"
|
|
67
|
-
} else if (
|
|
86
|
+
} else if (driver.getType() == "mysql") {
|
|
68
87
|
sql += " () VALUES ()"
|
|
69
88
|
}
|
|
70
89
|
}
|
|
71
90
|
|
|
91
|
+
if (this.returnLastInsertedColumnName) {
|
|
92
|
+
if (driver.getType() == "mysql") {
|
|
93
|
+
sql += lastInsertedSQL
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
72
97
|
return sql
|
|
73
98
|
}
|
|
74
99
|
|
|
@@ -8,6 +8,7 @@ export default class VelocuiousDatabaseQueryParserLimitParser {
|
|
|
8
8
|
|
|
9
9
|
toSql() {
|
|
10
10
|
const {pretty, query} = digs(this, "pretty", "query")
|
|
11
|
+
const driver = query.driver
|
|
11
12
|
let sql = ""
|
|
12
13
|
|
|
13
14
|
if (query._limits.length == 0) return sql
|
|
@@ -19,7 +20,11 @@ export default class VelocuiousDatabaseQueryParserLimitParser {
|
|
|
19
20
|
sql += " "
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
if (driver.getType() == "mssql") {
|
|
24
|
+
// sql += "BETWEEN"
|
|
25
|
+
} else {
|
|
26
|
+
sql += "LIMIT"
|
|
27
|
+
}
|
|
23
28
|
|
|
24
29
|
for (const limitKey in query._limits) {
|
|
25
30
|
const limit = query._limits[limitKey]
|
|
@@ -32,7 +37,11 @@ export default class VelocuiousDatabaseQueryParserLimitParser {
|
|
|
32
37
|
sql += " "
|
|
33
38
|
}
|
|
34
39
|
|
|
35
|
-
|
|
40
|
+
if (driver.getType() == "mssql") {
|
|
41
|
+
sql += `OFFSET 0 ROWS FETCH FIRST ${this.query.getOptions().quote(limit)} ROWS ONLY`
|
|
42
|
+
} else {
|
|
43
|
+
sql += this.query.getOptions().quote(limit)
|
|
44
|
+
}
|
|
36
45
|
}
|
|
37
46
|
|
|
38
47
|
return sql
|
|
@@ -11,22 +11,34 @@ export default class VelociousDatabaseQueryParserOptions {
|
|
|
11
11
|
if (!this.driver) throw new Error("No driver given to parser options")
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
quote(value) {
|
|
15
|
+
if (typeof value == "number") return value
|
|
16
|
+
|
|
17
|
+
return this.quoteString(value)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
quoteDatabaseName(databaseName) {
|
|
21
|
+
if (databaseName.includes(this.tableQuote)) throw new Error(`Possible SQL injection in database name: ${databaseName}`)
|
|
22
|
+
|
|
23
|
+
return `${this.tableQuote}${databaseName}${this.tableQuote}`
|
|
24
|
+
}
|
|
25
|
+
|
|
14
26
|
quoteColumnName(columnName) {
|
|
15
|
-
if (!columnName
|
|
27
|
+
if (!columnName) throw new Error("No column name was given")
|
|
28
|
+
if (columnName.includes(this.columnQuote)) throw new Error(`Invalid column name: ${columnName}`)
|
|
16
29
|
|
|
17
30
|
return `${this.columnQuote}${columnName}${this.columnQuote}`
|
|
18
31
|
}
|
|
19
32
|
|
|
20
|
-
|
|
21
|
-
if (!
|
|
33
|
+
quoteIndexName(indexName) {
|
|
34
|
+
if (!indexName || indexName.includes(this.columnQuote)) throw new Error(`Invalid column name: ${indexName}`)
|
|
22
35
|
|
|
23
|
-
return `${this.
|
|
36
|
+
return `${this.columnQuote}${indexName}${this.columnQuote}`
|
|
24
37
|
}
|
|
25
38
|
|
|
26
|
-
|
|
27
|
-
if (
|
|
28
|
-
return value
|
|
39
|
+
quoteTableName(tableName) {
|
|
40
|
+
if (!tableName || tableName.includes(this.tableQuote)) throw new Error(`Invalid table name: ${tableName}`)
|
|
29
41
|
|
|
30
|
-
return this.
|
|
42
|
+
return `${this.tableQuote}${tableName}${this.tableQuote}`
|
|
31
43
|
}
|
|
32
44
|
}
|
|
@@ -117,7 +117,8 @@ export default class VelociousDatabaseRecord {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
static connection() {
|
|
120
|
-
const
|
|
120
|
+
const databasePool = this._getConfiguration().getDatabasePool(this.getDatabaseIdentifier())
|
|
121
|
+
const connection = databasePool.getCurrentConnection()
|
|
121
122
|
|
|
122
123
|
if (!connection) throw new Error("No connection?")
|
|
123
124
|
|
|
@@ -229,6 +230,14 @@ export default class VelociousDatabaseRecord {
|
|
|
229
230
|
}
|
|
230
231
|
}
|
|
231
232
|
|
|
233
|
+
static getDatabaseIdentifier() {
|
|
234
|
+
return this._databaseIdentifier || "default"
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
static setDatabaseIdentifier(databaseIdentifier) {
|
|
238
|
+
this._databaseIdentifier = databaseIdentifier
|
|
239
|
+
}
|
|
240
|
+
|
|
232
241
|
getAttribute(name) {
|
|
233
242
|
const columnName = inflection.underscore(name)
|
|
234
243
|
|
|
@@ -681,11 +690,18 @@ export default class VelociousDatabaseRecord {
|
|
|
681
690
|
|
|
682
691
|
const data = Object.assign({}, this._belongsToChanges(), this.attributes())
|
|
683
692
|
const sql = this._connection().insertSql({
|
|
693
|
+
returnLastInsertedColumnName: this.constructor.primaryKey(),
|
|
684
694
|
tableName: this._tableName(),
|
|
685
695
|
data
|
|
686
696
|
})
|
|
687
|
-
await this._connection().query(sql)
|
|
688
|
-
|
|
697
|
+
const insertResult = await this._connection().query(sql)
|
|
698
|
+
let id
|
|
699
|
+
|
|
700
|
+
if (insertResult && insertResult[0]?.lastInsertID) {
|
|
701
|
+
id = insertResult[0]?.lastInsertID
|
|
702
|
+
} else {
|
|
703
|
+
id = await this._connection().lastInsertID()
|
|
704
|
+
}
|
|
689
705
|
|
|
690
706
|
await this._reloadWithId(id)
|
|
691
707
|
this.setIsNewRecord(false)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import DatabaseMigrateFromRequireContext from "./migrate-from-require-context.js"
|
|
2
1
|
import React from "react"
|
|
3
2
|
import useEnvSense from "env-sense/src/use-env-sense.js"
|
|
4
3
|
|
|
5
4
|
import Configuration from "../configuration.js"
|
|
5
|
+
import Migrator from "./migrator.js"
|
|
6
6
|
import restArgsError from "../utils/rest-args-error.js"
|
|
7
7
|
|
|
8
8
|
const loadMigrations = function loadMigrations({migrationsRequireContext, ...restArgs}) {
|
|
@@ -14,10 +14,11 @@ const loadMigrations = function loadMigrations({migrationsRequireContext, ...res
|
|
|
14
14
|
instance.running = true
|
|
15
15
|
|
|
16
16
|
try {
|
|
17
|
-
await Configuration.current().
|
|
18
|
-
const
|
|
17
|
+
await Configuration.current().withConnections(async () => {
|
|
18
|
+
const migrator = new Migrator({configuration: Configuration.current()})
|
|
19
19
|
|
|
20
|
-
await
|
|
20
|
+
await migrator.prepare()
|
|
21
|
+
await migrator.migrateFilesFromRequireContext(migrationsRequireContext)
|
|
21
22
|
})
|
|
22
23
|
|
|
23
24
|
await Configuration.current().initialize()
|
package/src/routes/base-route.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import GetRoute from "./get-route.js"
|
|
2
|
+
import PostRoute from "./post-route.js"
|
|
2
3
|
import ResourceRoute from "./resource-route.js"
|
|
3
4
|
|
|
4
5
|
var VelociousBaseRoute
|
|
@@ -19,6 +20,12 @@ export function initBaseRoute() {
|
|
|
19
20
|
throw new Error(`No 'matchWithPath' implemented on ${this.constructor.name}`)
|
|
20
21
|
}
|
|
21
22
|
|
|
23
|
+
post(name, args) {
|
|
24
|
+
const route = new PostRoute({name, args})
|
|
25
|
+
|
|
26
|
+
this.routes.push(route)
|
|
27
|
+
}
|
|
28
|
+
|
|
22
29
|
resources(name, callback) {
|
|
23
30
|
const route = new ResourceRoute({name})
|
|
24
31
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import BaseRoute, {initBaseRoute} from "./base-route.js"
|
|
2
|
+
import escapeStringRegexp from "escape-string-regexp"
|
|
3
|
+
|
|
4
|
+
initBaseRoute()
|
|
5
|
+
|
|
6
|
+
export default class VelociousRoutePostRoute extends BaseRoute {
|
|
7
|
+
constructor({name}) {
|
|
8
|
+
super()
|
|
9
|
+
this.name = name
|
|
10
|
+
this.regExp = new RegExp(`^(${escapeStringRegexp(name)})(.*)$`)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
matchWithPath({params, path}) {
|
|
14
|
+
const match = path.match(this.regExp)
|
|
15
|
+
|
|
16
|
+
if (match) {
|
|
17
|
+
const [_beginnigSlash, _matchedName, restPath] = match
|
|
18
|
+
|
|
19
|
+
params.action = this.name
|
|
20
|
+
|
|
21
|
+
return {restPath}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
package/src/routes/resolver.js
CHANGED
|
@@ -58,7 +58,7 @@ export default class VelociousRoutesResolver {
|
|
|
58
58
|
throw new Error(`Missing action on controller: ${controller}#${action}`)
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
await this.configuration.
|
|
61
|
+
await this.configuration.withConnections(async () => {
|
|
62
62
|
await controllerInstance._runBeforeCallbacks()
|
|
63
63
|
await controllerInstance[action]()
|
|
64
64
|
})
|
|
@@ -4,18 +4,51 @@ import MysqlDriver from "velocious/src/database/drivers/mysql/index.js"
|
|
|
4
4
|
|
|
5
5
|
export default new Configuration({
|
|
6
6
|
database: {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
development: {
|
|
8
|
+
default: {
|
|
9
9
|
driver: MysqlDriver,
|
|
10
10
|
poolType: AsyncTrackedMultiConnection,
|
|
11
11
|
type: "mysql",
|
|
12
12
|
host: "mariadb",
|
|
13
13
|
username: "username",
|
|
14
14
|
password: "password",
|
|
15
|
-
database: "
|
|
15
|
+
database: "database_development"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
production: {
|
|
19
|
+
default: {
|
|
20
|
+
driver: MysqlDriver,
|
|
21
|
+
poolType: AsyncTrackedMultiConnection,
|
|
22
|
+
type: "mysql",
|
|
23
|
+
host: "mariadb",
|
|
24
|
+
username: "username",
|
|
25
|
+
password: "password",
|
|
26
|
+
database: "database_production"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
test: {
|
|
30
|
+
default: {
|
|
31
|
+
driver: MysqlDriver,
|
|
32
|
+
poolType: AsyncTrackedMultiConnection,
|
|
33
|
+
type: "mysql",
|
|
34
|
+
host: "mariadb",
|
|
35
|
+
username: "username",
|
|
36
|
+
password: "password",
|
|
37
|
+
database: "database_test"
|
|
16
38
|
}
|
|
17
39
|
}
|
|
18
40
|
},
|
|
41
|
+
initializeModels: async ({configuration}) => {
|
|
42
|
+
const modelsPath = await fs.realpath(`${path.dirname(import.meta.dirname)}/../src/models`)
|
|
43
|
+
const requireContextModels = requireContext(modelsPath, true, /^(.+)\.js$/)
|
|
44
|
+
const initializerFromRequireContext = new InitializerFromRequireContext({requireContext: requireContextModels})
|
|
45
|
+
|
|
46
|
+
await configuration.withConnections(async () => {
|
|
47
|
+
await initializerFromRequireContext.initialize({configuration})
|
|
48
|
+
})
|
|
49
|
+
},
|
|
50
|
+
locale: () => "en",
|
|
51
|
+
locales: ["de", "en"],
|
|
19
52
|
localeFallbacks: {
|
|
20
53
|
de: ["de", "en"],
|
|
21
54
|
en: ["en", "de"]
|
|
@@ -71,7 +71,7 @@ export default class TestRunner {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
await this.configuration.
|
|
74
|
+
await this.configuration.withConnections(async () => {
|
|
75
75
|
for (const subDescription in tests.subs) {
|
|
76
76
|
const subTest = tests.subs[subDescription]
|
|
77
77
|
const newDecriptions = descriptions.concat([subDescription])
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export default async function nestCallbacks(callbacksToNestInside, callback) {
|
|
2
|
+
let runCallback = callback
|
|
3
|
+
|
|
4
|
+
for (const callbackToNestInside of callbacksToNestInside) {
|
|
5
|
+
let actualRunCallback = runCallback
|
|
6
|
+
|
|
7
|
+
const nextRunRequest = async () => {
|
|
8
|
+
await callbackToNestInside(actualRunCallback)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
runCallback = nextRunRequest
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
await runCallback()
|
|
15
|
+
}
|
package/src/big-brother.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
export default class VelociousBigBrother {
|
|
2
|
-
constructor() {
|
|
3
|
-
this.enabledLoggers = {
|
|
4
|
-
databaseQuery: false
|
|
5
|
-
}
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
checkExists(name) {
|
|
9
|
-
if (!(name in this.enabledLoggers)) throw new Error(`Invalid logger name: ${name}`)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
isEnabled(name) {
|
|
13
|
-
this.checkExists(name)
|
|
14
|
-
|
|
15
|
-
return this.enabledLoggers[name]
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
async run({after, before, name}, callback) {
|
|
19
|
-
this.checkExists(name)
|
|
20
|
-
|
|
21
|
-
if (!this.enabledLoggers[name]) {
|
|
22
|
-
return await callback()
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (before) {
|
|
26
|
-
before()
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const startTime = new Date()
|
|
30
|
-
const result = await callback()
|
|
31
|
-
const endTime = new Date()
|
|
32
|
-
|
|
33
|
-
if (after) {
|
|
34
|
-
after({result})
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import Configuration from "../configuration.js"
|
|
2
|
-
import * as inflection from "inflection"
|
|
3
|
-
import Migrator from "./migrator.js"
|
|
4
|
-
|
|
5
|
-
export default class VelociousDatabaseMigrateFromRequireContext {
|
|
6
|
-
constructor(configuration) {
|
|
7
|
-
this.configuration = configuration || Configuration.current()
|
|
8
|
-
this.migrator = new Migrator({configuration: this.configuration})
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
async execute(requireContext) {
|
|
12
|
-
await this.migrator.prepare()
|
|
13
|
-
|
|
14
|
-
const files = requireContext.keys()
|
|
15
|
-
.map((file) => {
|
|
16
|
-
// "13,14" because somes "require-context"-npm-module deletes first character!?
|
|
17
|
-
const match = file.match(/(\d{13,14})-(.+)\.js$/)
|
|
18
|
-
|
|
19
|
-
if (!match) return null
|
|
20
|
-
|
|
21
|
-
// Fix require-context-npm-module deletes first character
|
|
22
|
-
let fileName = file
|
|
23
|
-
let dateNumber = match[1]
|
|
24
|
-
|
|
25
|
-
if (dateNumber.length == 13) {
|
|
26
|
-
dateNumber = `2${dateNumber}`
|
|
27
|
-
fileName = `2${fileName}`
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Parse regex
|
|
31
|
-
const date = parseInt(dateNumber)
|
|
32
|
-
const migrationName = match[2]
|
|
33
|
-
const migrationClassName = inflection.camelize(migrationName.replaceAll("-", "_"))
|
|
34
|
-
|
|
35
|
-
return {
|
|
36
|
-
file: fileName,
|
|
37
|
-
date,
|
|
38
|
-
migrationClassName
|
|
39
|
-
}
|
|
40
|
-
})
|
|
41
|
-
.filter((migration) => Boolean(migration))
|
|
42
|
-
.sort((migration1, migration2) => migration1.date - migration2.date)
|
|
43
|
-
|
|
44
|
-
for (const migration of files) {
|
|
45
|
-
if (!this.migrator.hasRunMigrationVersion(migration.date)) {
|
|
46
|
-
await this.runMigrationFile(migration, requireContext)
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async runMigrationFile(migration, requireContext) {
|
|
52
|
-
if (!this.configuration) throw new Error("No configuration set")
|
|
53
|
-
if (!this.configuration.isDatabasePoolInitialized()) await this.configuration.initializeDatabasePool()
|
|
54
|
-
|
|
55
|
-
await this.configuration.getDatabasePool().withConnection(async (db) => {
|
|
56
|
-
const MigrationClass = requireContext(migration.file).default
|
|
57
|
-
const migrationInstance = new MigrationClass({
|
|
58
|
-
configuration: this.configuration
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
if (migrationInstance.change) {
|
|
62
|
-
await migrationInstance.change()
|
|
63
|
-
} else if (migrationInstance.up) {
|
|
64
|
-
await migrationInstance.up()
|
|
65
|
-
} else {
|
|
66
|
-
throw new Error(`'change' or 'up' didn't exist on migration: ${migration.file}`)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
await db.insert({tableName: "schema_migrations", data: {version: migration.date}})
|
|
70
|
-
})
|
|
71
|
-
}
|
|
72
|
-
}
|