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
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import Base from "../base.js"
|
|
2
|
+
import CreateDatabase from "./sql/create-database.js"
|
|
3
|
+
import CreateIndex from "./sql/create-index.js"
|
|
4
|
+
import CreateTable from "./sql/create-table.js"
|
|
5
|
+
import Delete from "./sql/delete.js"
|
|
6
|
+
import DropTable from "./sql/drop-table.js"
|
|
7
|
+
import {digg} from "diggerize"
|
|
8
|
+
import escapeString from "sql-escape-string"
|
|
9
|
+
import Insert from "./sql/insert.js"
|
|
10
|
+
import Options from "./options.js"
|
|
11
|
+
import mssql from "mssql"
|
|
12
|
+
import QueryParser from "./query-parser.js"
|
|
13
|
+
import Table from "./table.js"
|
|
14
|
+
import Update from "./sql/update.js"
|
|
15
|
+
import {v4 as uuidv4} from "uuid"
|
|
16
|
+
|
|
17
|
+
export default class VelociousDatabaseDriversMssql extends Base{
|
|
18
|
+
async connect() {
|
|
19
|
+
const args = this.getArgs()
|
|
20
|
+
const sqlConfig = digg(args, "sqlConfig")
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
this.connection = await mssql.connect(sqlConfig)
|
|
24
|
+
} catch (error) {
|
|
25
|
+
throw new Error(`Couldn't connect to database: ${error.message}`) // Re-throw to fix unuseable stack trace.
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
disconnect() {
|
|
30
|
+
this.connection.end()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async close() {
|
|
34
|
+
await this.connection.close()
|
|
35
|
+
this.connection = undefined
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
createDatabaseSql(databaseName, args) {
|
|
39
|
+
const createArgs = Object.assign({databaseName, driver: this}, args)
|
|
40
|
+
const createDatabase = new CreateDatabase(createArgs)
|
|
41
|
+
|
|
42
|
+
return createDatabase.toSql()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
createIndexSql(indexData) {
|
|
46
|
+
const createArgs = Object.assign({driver: this}, indexData)
|
|
47
|
+
const createIndex = new CreateIndex(createArgs)
|
|
48
|
+
|
|
49
|
+
return createIndex.toSql()
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
createTableSql(tableData) {
|
|
53
|
+
const createArgs = Object.assign({tableData, driver: this})
|
|
54
|
+
const createTable = new CreateTable(createArgs)
|
|
55
|
+
|
|
56
|
+
return createTable.toSql()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async disableForeignKeys() {
|
|
60
|
+
await this.query("EXEC sp_MSforeachtable \"ALTER TABLE ? NOCHECK CONSTRAINT all\"")
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async enableForeignKeys() {
|
|
64
|
+
await this.query("EXEC sp_MSforeachtable @command1=\"print '?'\", @command2=\"ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all\"")
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
dropTableSql(tableName, args = {}) {
|
|
68
|
+
const dropArgs = Object.assign({tableName, driver: this}, args)
|
|
69
|
+
const dropTable = new DropTable(dropArgs)
|
|
70
|
+
|
|
71
|
+
return dropTable.toSql()
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
getType = () => "mssql"
|
|
75
|
+
primaryKeyType = () => "bigint"
|
|
76
|
+
|
|
77
|
+
async query(sql) {
|
|
78
|
+
let result, request
|
|
79
|
+
|
|
80
|
+
if (this._currentTransaction) {
|
|
81
|
+
request = new mssql.Request(this._currentTransaction)
|
|
82
|
+
} else {
|
|
83
|
+
request = mssql
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
result = await request.query(sql)
|
|
88
|
+
} catch (error) {
|
|
89
|
+
// Re-throw error because the stack-trace is broken and can't be used for app-development.
|
|
90
|
+
throw new Error(`Query failed '${error.message})': ${sql}`)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return result.recordsets[0]
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
queryToSql(query) {
|
|
97
|
+
return new QueryParser({query}).toSql()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
shouldSetAutoIncrementWhenPrimaryKey = () => true
|
|
101
|
+
|
|
102
|
+
escape(value) {
|
|
103
|
+
const type = typeof value
|
|
104
|
+
|
|
105
|
+
if (type != "string") value = `${value}`
|
|
106
|
+
|
|
107
|
+
const resultWithQuotes = escapeString(value)
|
|
108
|
+
const result = resultWithQuotes.substring(1, resultWithQuotes.length - 1)
|
|
109
|
+
|
|
110
|
+
return result
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
quote(value) {
|
|
114
|
+
const type = typeof value
|
|
115
|
+
|
|
116
|
+
if (type == "number") return value
|
|
117
|
+
if (type != "string") value = `${value}`
|
|
118
|
+
|
|
119
|
+
return escapeString(value)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
quoteColumn = (string) => this.options().quoteColumnName(string)
|
|
123
|
+
quoteTable = (string) => this.options().quoteTableName(string)
|
|
124
|
+
|
|
125
|
+
deleteSql({tableName, conditions}) {
|
|
126
|
+
const deleteInstruction = new Delete({conditions, driver: this, tableName})
|
|
127
|
+
|
|
128
|
+
return deleteInstruction.toSql()
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
insertSql(args) {
|
|
132
|
+
const insertArgs = Object.assign({driver: this}, args)
|
|
133
|
+
const insert = new Insert(insertArgs)
|
|
134
|
+
|
|
135
|
+
return insert.toSql()
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async getTables() {
|
|
139
|
+
const result = await this.query(`SELECT [TABLE_NAME] FROM [INFORMATION_SCHEMA].[TABLES] WHERE [TABLE_CATALOG] = DB_NAME() AND [TABLE_SCHEMA] = 'dbo'`)
|
|
140
|
+
const tables = []
|
|
141
|
+
|
|
142
|
+
for (const row of result) {
|
|
143
|
+
const table = new Table(this, row)
|
|
144
|
+
|
|
145
|
+
tables.push(table)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return tables
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async getTableByName(tableName) {
|
|
152
|
+
const result = await this.query(`SELECT [TABLE_NAME] FROM [INFORMATION_SCHEMA].[TABLES] WHERE [TABLE_CATALOG] = DB_NAME() AND [TABLE_SCHEMA] = 'dbo' AND [TABLE_NAME] = ${this.quote(tableName)}`)
|
|
153
|
+
|
|
154
|
+
if (!result[0]) throw new Error(`Couldn't find a table by that name: ${tableName}`)
|
|
155
|
+
|
|
156
|
+
return new Table(this, result[0])
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async lastInsertID() {
|
|
160
|
+
const result = await this.query("SELECT SCOPE_IDENTITY() AS last_insert_id")
|
|
161
|
+
const lastInsertID = digg(result, 0, "last_insert_id")
|
|
162
|
+
|
|
163
|
+
if (lastInsertID === null) throw new Error("Couldn't get the last inserted ID")
|
|
164
|
+
|
|
165
|
+
return lastInsertID
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
options() {
|
|
169
|
+
if (!this._options) this._options = new Options({driver: this})
|
|
170
|
+
|
|
171
|
+
return this._options
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async startTransaction() {
|
|
175
|
+
if (this._currentTransaction) throw new Error("A transaction is already running")
|
|
176
|
+
|
|
177
|
+
this._currentTransaction = new mssql.Transaction()
|
|
178
|
+
await this._currentTransaction.begin()
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async commitTransaction() {
|
|
182
|
+
if (!this._currentTransaction) throw new Error("A transaction isn't running")
|
|
183
|
+
|
|
184
|
+
await this._currentTransaction.commit()
|
|
185
|
+
this._currentTransaction = null
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async rollbackTransaction() {
|
|
189
|
+
if (!this._currentTransaction) throw new Error("A transaction isn't running")
|
|
190
|
+
|
|
191
|
+
await this._currentTransaction.rollback()
|
|
192
|
+
this._currentTransaction = null
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async startSavePoint(savePointName) {
|
|
196
|
+
await this.query(`SAVE TRANSACTION [${savePointName}]`)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
async releaseSavePoint(savePointName) {
|
|
200
|
+
// Do nothing in MS-SQL.
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async rollbackSavePoint(savePointName) {
|
|
204
|
+
await this.query(`ROLLBACK TRANSACTION [${savePointName}]`)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
generateSavePointName() {
|
|
208
|
+
return `sp${uuidv4().replaceAll("-", "")}`.substring(0, 32)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
updateSql({conditions, data, tableName}) {
|
|
212
|
+
const update = new Update({conditions, data, driver: this, tableName})
|
|
213
|
+
|
|
214
|
+
return update.toSql()
|
|
215
|
+
}
|
|
216
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import QueryParserOptions from "../../query-parser/options.js"
|
|
2
|
+
|
|
3
|
+
export default class VelociousDatabaseDriversMssqlOptions extends QueryParserOptions {
|
|
4
|
+
constructor(options) {
|
|
5
|
+
options.columnQuote = "\""
|
|
6
|
+
options.indexQuote = "\""
|
|
7
|
+
options.stringQuote = "'"
|
|
8
|
+
options.tableQuote = "\""
|
|
9
|
+
|
|
10
|
+
super(options)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
quote(string) {
|
|
14
|
+
if (!this.driver) throw new Error("Driver not set")
|
|
15
|
+
|
|
16
|
+
return this.driver.quote(string)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
quoteColumnName = (string) => {
|
|
20
|
+
if (string.includes("[") || string.includes("]")) throw new Error(`Possible SQL injection in column name: ${string}`)
|
|
21
|
+
|
|
22
|
+
return `[${string}]`
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
quoteDatabaseName(databaseName) {
|
|
26
|
+
if (typeof databaseName != "string") throw new Error(`Invalid database name given: ${databaseName}`)
|
|
27
|
+
if (databaseName.includes("[") || databaseName.includes("]")) throw new Error(`Possible SQL injection in database name: ${databaseName}`)
|
|
28
|
+
|
|
29
|
+
return `[${databaseName}]`
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
quoteIndexName = (string) => {
|
|
33
|
+
if (string.includes("[") || string.includes("]")) throw new Error(`Possible SQL injection in index name: ${string}`)
|
|
34
|
+
|
|
35
|
+
return `[${string}]`
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
quoteTableName = (string) => {
|
|
39
|
+
if (string.includes("[") || string.includes("]")) throw new Error(`Possible SQL injection in table name: ${string}`)
|
|
40
|
+
|
|
41
|
+
return `[${string}]`
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import CreateDatabaseBase from "../../../query/create-database-base.js"
|
|
2
|
+
|
|
3
|
+
export default class VelociousDatabaseConnectionDriversMssqlSqlCreateDatabase extends CreateDatabaseBase {
|
|
4
|
+
constructor({driver, databaseName, ifNotExists}) {
|
|
5
|
+
super({driver})
|
|
6
|
+
this.databaseName = databaseName
|
|
7
|
+
this.ifNotExists = ifNotExists
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
toSql() {
|
|
11
|
+
const {databaseName} = this
|
|
12
|
+
const options = this.getOptions()
|
|
13
|
+
|
|
14
|
+
let sql = ""
|
|
15
|
+
|
|
16
|
+
if (this.ifNotExists) {
|
|
17
|
+
sql += `IF NOT EXISTS(SELECT * FROM [sys].[databases] WHERE [name] = ${options.quote(databaseName)}) BEGIN `
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
sql += `CREATE DATABASE ${options.quoteDatabaseName(databaseName)}`
|
|
21
|
+
|
|
22
|
+
if (this.ifNotExists) {
|
|
23
|
+
sql += " END"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return sql
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import DeleteBase from "../../../query/delete-base.js"
|
|
2
|
+
|
|
3
|
+
export default class VelociousDatabaseConnectionDriversMssqlSqlDelete extends DeleteBase {
|
|
4
|
+
toSql() {
|
|
5
|
+
let sql = `DELETE FROM ${this.getOptions().quoteTableName(this.tableName)} WHERE `
|
|
6
|
+
let count = 0
|
|
7
|
+
|
|
8
|
+
for (let columnName in this.conditions) {
|
|
9
|
+
if (count > 0) sql += " AND "
|
|
10
|
+
|
|
11
|
+
sql += this.getOptions().quoteColumnName(columnName)
|
|
12
|
+
sql += " = "
|
|
13
|
+
sql += this.getOptions().quote(this.conditions[columnName])
|
|
14
|
+
count++
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return sql
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import UpdateBase from "../../../query/update-base.js"
|
|
2
|
+
|
|
3
|
+
export default class VelociousDatabaseConnectionDriversMssqlSqlUpdate extends UpdateBase {
|
|
4
|
+
toSql() {
|
|
5
|
+
let sql = `UPDATE ${this.getOptions().quoteTableName(this.tableName)} SET `
|
|
6
|
+
let count = 0
|
|
7
|
+
|
|
8
|
+
for (let columnName in this.data) {
|
|
9
|
+
if (count > 0) sql += ", "
|
|
10
|
+
|
|
11
|
+
sql += this.getOptions().quoteColumnName(columnName)
|
|
12
|
+
sql += " = "
|
|
13
|
+
sql += this.getOptions().quote(this.data[columnName])
|
|
14
|
+
count++
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
sql += " WHERE "
|
|
18
|
+
count = 0
|
|
19
|
+
|
|
20
|
+
for (let columnName in this.conditions) {
|
|
21
|
+
if (count > 0) sql += " AND "
|
|
22
|
+
|
|
23
|
+
sql += this.getOptions().quoteColumnName(columnName)
|
|
24
|
+
sql += " = "
|
|
25
|
+
sql += this.getOptions().quote(this.conditions[columnName])
|
|
26
|
+
count++
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return sql
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import Column from "./column.js"
|
|
2
|
+
import {digg} from "diggerize"
|
|
3
|
+
import ForeignKey from "./foreign-key.js"
|
|
4
|
+
|
|
5
|
+
export default class VelociousDatabaseDriversMssqlTable {
|
|
6
|
+
constructor(driver, data) {
|
|
7
|
+
this.data = data
|
|
8
|
+
this.driver = driver
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async getColumns() {
|
|
12
|
+
const result = await this.driver.query(`SELECT [COLUMN_NAME] FROM [INFORMATION_SCHEMA].[COLUMNS] WHERE [TABLE_NAME] = ${this.driver.quote(this.getName())}`)
|
|
13
|
+
const columns = []
|
|
14
|
+
|
|
15
|
+
for (const data of result) {
|
|
16
|
+
const column = new Column(this, data)
|
|
17
|
+
|
|
18
|
+
columns.push(column)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return columns
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async getForeignKeys() {
|
|
25
|
+
const sql = `
|
|
26
|
+
SELECT
|
|
27
|
+
fk.name AS ForeignKeyName,
|
|
28
|
+
tp.name AS ParentTable,
|
|
29
|
+
ref.name AS ReferencedTable,
|
|
30
|
+
cp.name AS ParentColumn,
|
|
31
|
+
cref.name AS ReferencedColumn,
|
|
32
|
+
tp.name AS TableName
|
|
33
|
+
FROM sys.foreign_keys fk
|
|
34
|
+
INNER JOIN sys.foreign_key_columns fkc
|
|
35
|
+
ON fkc.constraint_object_id = fk.object_id
|
|
36
|
+
INNER JOIN sys.tables tp
|
|
37
|
+
ON fkc.parent_object_id = tp.object_id
|
|
38
|
+
INNER JOIN sys.columns cp
|
|
39
|
+
ON fkc.parent_object_id = cp.object_id
|
|
40
|
+
AND fkc.parent_column_id = cp.column_id
|
|
41
|
+
INNER JOIN sys.tables ref
|
|
42
|
+
ON fkc.referenced_object_id = ref.object_id
|
|
43
|
+
INNER JOIN sys.columns cref
|
|
44
|
+
ON fkc.referenced_object_id = cref.object_id
|
|
45
|
+
AND fkc.referenced_column_id = cref.column_id
|
|
46
|
+
WHERE tp.name = ${this.driver.quote(this.getName())}
|
|
47
|
+
ORDER BY ForeignKeyName, ParentTable, ReferencedTable;
|
|
48
|
+
`
|
|
49
|
+
|
|
50
|
+
const foreignKeyRows = await this.driver.query(sql)
|
|
51
|
+
const foreignKeys = []
|
|
52
|
+
|
|
53
|
+
for (const foreignKeyRow of foreignKeyRows) {
|
|
54
|
+
const foreignKey = new ForeignKey(foreignKeyRow)
|
|
55
|
+
|
|
56
|
+
foreignKeys.push(foreignKey)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return foreignKeys
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
getName() {
|
|
63
|
+
return digg(this.data, "TABLE_NAME")
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -5,6 +5,7 @@ import CreateIndex from "./sql/create-index.js"
|
|
|
5
5
|
import CreateTable from "./sql/create-table.js"
|
|
6
6
|
import Delete from "./sql/delete.js"
|
|
7
7
|
import {digg} from "diggerize"
|
|
8
|
+
import DropTable from "./sql/drop-table.js"
|
|
8
9
|
import Insert from "./sql/insert.js"
|
|
9
10
|
import Options from "./options.js"
|
|
10
11
|
import mysql from "mysql"
|
|
@@ -65,11 +66,31 @@ export default class VelociousDatabaseDriversMysql extends Base{
|
|
|
65
66
|
return createTable.toSql()
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
async disableForeignKeys() {
|
|
70
|
+
await this.query("SET FOREIGN_KEY_CHECKS = 0")
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async enableForeignKeys() {
|
|
74
|
+
await this.query("SET FOREIGN_KEY_CHECKS = 1")
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
dropTableSql(tableName, args = {}) {
|
|
78
|
+
const dropArgs = Object.assign({tableName, driver: this}, args)
|
|
79
|
+
const dropTable = new DropTable(dropArgs)
|
|
80
|
+
|
|
81
|
+
return dropTable.toSql()
|
|
82
|
+
}
|
|
83
|
+
|
|
68
84
|
getType = () => "mysql"
|
|
69
85
|
primaryKeyType = () => "bigint"
|
|
70
86
|
|
|
71
87
|
async query(sql) {
|
|
72
|
-
|
|
88
|
+
try {
|
|
89
|
+
return await query(this.connection, sql)
|
|
90
|
+
} catch (error) {
|
|
91
|
+
// Re-throw to un-corrupt stacktrace
|
|
92
|
+
throw new Error(error.message)
|
|
93
|
+
}
|
|
73
94
|
}
|
|
74
95
|
|
|
75
96
|
queryToSql(query) {
|
|
@@ -78,26 +99,18 @@ export default class VelociousDatabaseDriversMysql extends Base{
|
|
|
78
99
|
|
|
79
100
|
shouldSetAutoIncrementWhenPrimaryKey = () => true
|
|
80
101
|
|
|
81
|
-
escape(
|
|
102
|
+
escape(value) {
|
|
82
103
|
if (!this.connection) throw new Error("Can't escape before connected")
|
|
83
104
|
|
|
84
|
-
|
|
85
|
-
}
|
|
105
|
+
const escapedValueWithQuotes = this.connection.escape(value)
|
|
86
106
|
|
|
87
|
-
|
|
88
|
-
return `${this.escape(string)}`
|
|
107
|
+
return escapedValueWithQuotes.slice(1, escapedValueWithQuotes.length - 1)
|
|
89
108
|
}
|
|
90
109
|
|
|
91
|
-
|
|
92
|
-
if (
|
|
93
|
-
|
|
94
|
-
return `\`${string}\``
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
quoteTable = (string) => {
|
|
98
|
-
if (string.includes("`")) throw new Error(`Possible SQL injection in table name: ${string}`)
|
|
110
|
+
quote(value) {
|
|
111
|
+
if (!this.connection) throw new Error("Can't escape before connected")
|
|
99
112
|
|
|
100
|
-
return
|
|
113
|
+
return this.connection.escape(value)
|
|
101
114
|
}
|
|
102
115
|
|
|
103
116
|
deleteSql({tableName, conditions}) {
|
|
@@ -133,9 +146,7 @@ export default class VelociousDatabaseDriversMysql extends Base{
|
|
|
133
146
|
}
|
|
134
147
|
|
|
135
148
|
options() {
|
|
136
|
-
if (!this._options) {
|
|
137
|
-
this._options = new Options({driver: this})
|
|
138
|
-
}
|
|
149
|
+
if (!this._options) this._options = new Options({driver: this})
|
|
139
150
|
|
|
140
151
|
return this._options
|
|
141
152
|
}
|
|
@@ -2,7 +2,7 @@ export default async function query(connection, sql) {
|
|
|
2
2
|
return new Promise((resolve, reject) => {
|
|
3
3
|
connection.query(sql, (error, results, fields) => {
|
|
4
4
|
if (error) {
|
|
5
|
-
reject(error)
|
|
5
|
+
reject(new Error(`Query failed because of ${error}: ${sql}`))
|
|
6
6
|
} else {
|
|
7
7
|
const rows = []
|
|
8
8
|
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import {digg} from "diggerize"
|
|
2
2
|
|
|
3
|
-
import AlterTable from "
|
|
3
|
+
import AlterTable from "./sql/alter-table.js"
|
|
4
4
|
import Base from "../base.js"
|
|
5
|
-
import CreateIndex from "
|
|
6
|
-
import CreateTable from "
|
|
7
|
-
import Delete from "
|
|
5
|
+
import CreateIndex from "./sql/create-index.js"
|
|
6
|
+
import CreateTable from "./sql/create-table.js"
|
|
7
|
+
import Delete from "./sql/delete.js"
|
|
8
|
+
import DropTable from "./sql/drop-table.js"
|
|
8
9
|
import escapeString from "sql-escape-string"
|
|
9
|
-
import Insert from "
|
|
10
|
-
import Options from "
|
|
11
|
-
import QueryParser from "
|
|
10
|
+
import Insert from "./sql/insert.js"
|
|
11
|
+
import Options from "./options.js"
|
|
12
|
+
import QueryParser from "./query-parser.js"
|
|
12
13
|
import Table from "./table.js"
|
|
13
|
-
import Update from "
|
|
14
|
+
import Update from "./sql/update.js"
|
|
14
15
|
|
|
15
16
|
export default class VelociousDatabaseDriversSqliteBase extends Base {
|
|
16
17
|
alterTableSql(columnData) {
|
|
@@ -34,6 +35,21 @@ export default class VelociousDatabaseDriversSqliteBase extends Base {
|
|
|
34
35
|
return createTable.toSql()
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
async disableForeignKeys() {
|
|
39
|
+
await this.query("PRAGMA foreign_keys = 0")
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async enableForeignKeys() {
|
|
43
|
+
await this.query("PRAGMA foreign_keys = 1")
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
dropTableSql(tableName, args = {}) {
|
|
47
|
+
const dropArgs = Object.assign({tableName, driver: this}, args)
|
|
48
|
+
const dropTable = new DropTable(dropArgs)
|
|
49
|
+
|
|
50
|
+
return dropTable.toSql()
|
|
51
|
+
}
|
|
52
|
+
|
|
37
53
|
deleteSql = (args) => new Delete(Object.assign({driver: this}, args)).toSql()
|
|
38
54
|
getType = () => "sqlite"
|
|
39
55
|
insertSql = (args) => new Insert(Object.assign({driver: this}, args)).toSql()
|
|
@@ -121,9 +137,7 @@ export default class VelociousDatabaseDriversSqliteBase extends Base {
|
|
|
121
137
|
}
|
|
122
138
|
|
|
123
139
|
options() {
|
|
124
|
-
if (!this._options) {
|
|
125
|
-
this._options = new Options({driver: this})
|
|
126
|
-
}
|
|
140
|
+
if (!this._options) this._options = new Options({driver: this})
|
|
127
141
|
|
|
128
142
|
return this._options
|
|
129
143
|
}
|
|
@@ -169,17 +183,5 @@ export default class VelociousDatabaseDriversSqliteBase extends Base {
|
|
|
169
183
|
return escapeString(value)
|
|
170
184
|
}
|
|
171
185
|
|
|
172
|
-
quoteColumn = (string) => {
|
|
173
|
-
if (string.includes("`")) throw new Error(`Possible SQL injection in column name: ${string}`)
|
|
174
|
-
|
|
175
|
-
return `\`${string}\``
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
quoteTable = (string) => {
|
|
179
|
-
if (string.includes("`")) throw new Error(`Possible SQL injection in table name: ${string}`)
|
|
180
|
-
|
|
181
|
-
return `\`${string}\``
|
|
182
|
-
}
|
|
183
|
-
|
|
184
186
|
updateSql = ({conditions, data, tableName}) => new Update({conditions, data, driver: this, tableName}).toSql()
|
|
185
187
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {digg} from "diggerize"
|
|
2
|
+
import envSense from "env-sense/src/use-env-sense.js"
|
|
2
3
|
import query from "./query"
|
|
3
4
|
import * as SQLite from "expo-sqlite"
|
|
4
5
|
|
|
@@ -6,6 +7,10 @@ import Base from "./base"
|
|
|
6
7
|
|
|
7
8
|
export default class VelociousDatabaseDriversSqliteNative extends Base {
|
|
8
9
|
async connect() {
|
|
10
|
+
const {isBrowser, isNative, isServer} = envSense()
|
|
11
|
+
|
|
12
|
+
if (!isNative) throw new Error(`SQLite native driver running inside non-native environment: ${JSON.stringify({isBrowser, isNative, isServer})}`)
|
|
13
|
+
|
|
9
14
|
const args = this.getArgs()
|
|
10
15
|
|
|
11
16
|
if (!args.name) throw new Error("No name given for SQLite Native")
|
|
@@ -51,5 +56,9 @@ export default class VelociousDatabaseDriversSqliteNative extends Base {
|
|
|
51
56
|
this.connection = undefined
|
|
52
57
|
}
|
|
53
58
|
|
|
54
|
-
query = async (sql) =>
|
|
59
|
+
query = async (sql) => {
|
|
60
|
+
if (!this.connection) throw new Error("Not connected yet")
|
|
61
|
+
|
|
62
|
+
return await query(this.connection, sql)
|
|
63
|
+
}
|
|
55
64
|
}
|
|
@@ -18,7 +18,9 @@ export default class VelociousDatabaseInitializerFromRequireContext {
|
|
|
18
18
|
await modelClass.initializeRecord({configuration})
|
|
19
19
|
|
|
20
20
|
if (await modelClass.hasTranslationsTable()) {
|
|
21
|
-
|
|
21
|
+
const translationClass = modelClass.getTranslationClass()
|
|
22
|
+
|
|
23
|
+
await translationClass.initializeRecord({configuration})
|
|
22
24
|
}
|
|
23
25
|
}
|
|
24
26
|
}
|