velocious 1.0.47 → 1.0.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/spec/cli/commands/db/migrate-spec.js +44 -6
- package/spec/database/drivers/columns-spec.js +27 -0
- package/spec/dummy/src/database/migrations/20250916111330-rename_authentication_tokens_token_to_user_token.js +11 -0
- package/src/database/drivers/base-column.js +4 -3
- package/src/database/drivers/base-foreign-key.js +31 -0
- package/src/database/drivers/base-table.js +15 -1
- package/src/database/drivers/base.js +44 -1
- package/src/database/drivers/mssql/column.js +7 -14
- package/src/database/drivers/mssql/columns-index.js +1 -1
- package/src/database/drivers/mssql/foreign-key.js +2 -5
- package/src/database/drivers/mssql/index.js +7 -5
- package/src/database/drivers/mssql/table.js +43 -1
- package/src/database/drivers/mysql/column.js +8 -3
- package/src/database/drivers/mysql/foreign-key.js +2 -5
- package/src/database/drivers/mysql/table.js +41 -0
- package/src/database/drivers/pgsql/column.js +8 -0
- package/src/database/drivers/pgsql/foreign-key.js +2 -5
- package/src/database/drivers/pgsql/table.js +56 -3
- package/src/database/drivers/sqlite/column.js +5 -3
- package/src/database/drivers/sqlite/columns-index.js +2 -2
- package/src/database/drivers/sqlite/foreign-key.js +8 -7
- package/src/database/drivers/sqlite/index.js +2 -0
- package/src/database/drivers/sqlite/index.native.js +3 -1
- package/src/database/drivers/sqlite/index.web.js +3 -1
- package/src/database/drivers/sqlite/sql/alter-table.js +79 -6
- package/src/database/migration/index.js +30 -18
- package/src/database/query/alter-table-base.js +6 -1
- package/src/database/query/create-index-base.js +28 -4
- package/src/database/query/create-table-base.js +14 -2
- package/src/database/table-data/index.js +12 -150
- package/src/database/table-data/table-column.js +145 -0
- package/src/database/table-data/table-foreign-key.js +23 -0
- package/src/database/table-data/table-index.js +18 -0
- package/src/database/table-data/table-reference.js +6 -0
|
@@ -9,6 +9,8 @@ export default class VelociousDatabaseDriversSqliteColumn extends BaseColumn {
|
|
|
9
9
|
this.table = table
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
getAutoIncrement() { return this.getPrimaryKey() }
|
|
13
|
+
|
|
12
14
|
async getIndexes() {
|
|
13
15
|
const indexes = await this.getTable().getIndexes()
|
|
14
16
|
const indexesForColumn = indexes.filter((index) => index.getColumnNames().includes(this.getName()))
|
|
@@ -16,9 +18,7 @@ export default class VelociousDatabaseDriversSqliteColumn extends BaseColumn {
|
|
|
16
18
|
return indexesForColumn
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
getDefault() {
|
|
20
|
-
return digg(this, "column", "dflt_value")
|
|
21
|
-
}
|
|
21
|
+
getDefault() { return digg(this, "column", "dflt_value") }
|
|
22
22
|
|
|
23
23
|
getName() {
|
|
24
24
|
const name = digg(this, "column", "name")
|
|
@@ -47,6 +47,8 @@ export default class VelociousDatabaseDriversSqliteColumn extends BaseColumn {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
getPrimaryKey() { return digg(this, "column", "pk") == 1 }
|
|
51
|
+
|
|
50
52
|
getType() {
|
|
51
53
|
const columnType = digg(this, "column", "type")
|
|
52
54
|
const match = columnType.match(/(.*)\((\d+)\)$/)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import BaseColumnsIndex from "../base-columns-index.js"
|
|
2
2
|
import {digg} from "diggerize"
|
|
3
|
-
import
|
|
3
|
+
import TableIndex from "../../table-data/table-index.js"
|
|
4
4
|
|
|
5
|
-
export default class
|
|
5
|
+
export default class VelociousDatabaseDriversSqliteColumnsIndex extends BaseColumnsIndex {
|
|
6
6
|
constructor(table, data) {
|
|
7
7
|
super()
|
|
8
8
|
this.data = data
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
import BaseForeignKey from "../base-foreign-key.js"
|
|
1
2
|
import {digg} from "diggerize"
|
|
2
3
|
|
|
3
|
-
export default class VelociousDatabaseDriversSqliteForeignKey {
|
|
4
|
+
export default class VelociousDatabaseDriversSqliteForeignKey extends BaseForeignKey {
|
|
4
5
|
constructor(data, {tableName}) {
|
|
5
|
-
|
|
6
|
+
super(data)
|
|
6
7
|
this.tableName = tableName
|
|
7
8
|
}
|
|
8
9
|
|
|
9
|
-
getColumnName
|
|
10
|
-
getName
|
|
11
|
-
getTableName
|
|
12
|
-
getReferencedColumnName
|
|
13
|
-
getReferencedTableName
|
|
10
|
+
getColumnName() { return digg(this, "data", "from") }
|
|
11
|
+
getName() { return `${this.getTableName()}_${this.getColumnName()}_${this.data.id}` }
|
|
12
|
+
getTableName() { return digg(this, "tableName") }
|
|
13
|
+
getReferencedColumnName() { return digg(this, "data", "to") }
|
|
14
|
+
getReferencedTableName() { return digg(this, "data", "table") }
|
|
14
15
|
}
|
|
@@ -56,7 +56,9 @@ export default class VelociousDatabaseDriversSqliteNative extends Base {
|
|
|
56
56
|
this.connection = undefined
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
async query(sql) {
|
|
60
|
+
console.error("Native SQL: ", sql)
|
|
61
|
+
|
|
60
62
|
if (!this.connection) throw new Error("Not connected yet")
|
|
61
63
|
|
|
62
64
|
return await query(this.connection, sql)
|
|
@@ -45,5 +45,7 @@ export default class VelociousDatabaseDriversSqliteWeb extends Base {
|
|
|
45
45
|
return `VelociousDatabaseDriversSqliteWeb---${this.args.name}`
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
query = async (sql) =>
|
|
48
|
+
query = async (sql) => {
|
|
49
|
+
return await this.getConnection().query(sql)
|
|
50
|
+
}
|
|
49
51
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import AlterTableBase from "../../../query/alter-table-base.js"
|
|
2
2
|
import CreateIndexBase from "../../../query/create-index-base.js"
|
|
3
3
|
import {digs} from "diggerize"
|
|
4
|
+
import * as inflection from "inflection"
|
|
5
|
+
import {Logger} from "../../../../logger.js"
|
|
4
6
|
import restArgsError from "../../../../utils/rest-args-error.js"
|
|
5
7
|
import TableData from "../../../table-data/index.js"
|
|
6
8
|
|
|
@@ -11,6 +13,7 @@ export default class VelociousDatabaseConnectionDriversSqliteSqlAlterTable exten
|
|
|
11
13
|
if (!(tableData instanceof TableData)) throw new Error("Invalid table data was given")
|
|
12
14
|
|
|
13
15
|
super({driver, tableData})
|
|
16
|
+
this.logger = new Logger(this)
|
|
14
17
|
this.tableData = tableData
|
|
15
18
|
}
|
|
16
19
|
|
|
@@ -21,7 +24,15 @@ export default class VelociousDatabaseConnectionDriversSqliteSqlAlterTable exten
|
|
|
21
24
|
const options = this.getOptions()
|
|
22
25
|
const tableName = tableData.getName()
|
|
23
26
|
const tempTableName = `${tableData.getName()}AlterTableTemp`
|
|
27
|
+
const newColumnNames = currentTableData.getColumns()
|
|
28
|
+
.filter((column) => !column.isNewColumn())
|
|
29
|
+
.map((column) => {
|
|
30
|
+
const newTableColumn = tableData.getColumns().find((tableColumn) => tableColumn.getName() == column.getName())
|
|
31
|
+
|
|
32
|
+
return newTableColumn?.getNewName() || newTableColumn?.getName() || column.getNewName() || column.getName()
|
|
33
|
+
})
|
|
24
34
|
const oldColumnNames = currentTableData.getColumns().filter((column) => !column.isNewColumn()).map((column) => column.getName())
|
|
35
|
+
const newColumnsSQL = newColumnNames.map((name) => options.quoteColumnName(name)).join(", ")
|
|
25
36
|
const oldColumnsSQL = oldColumnNames.map((name) => options.quoteColumnName(name)).join(", ")
|
|
26
37
|
|
|
27
38
|
tableData.setName(tempTableName)
|
|
@@ -29,13 +40,73 @@ export default class VelociousDatabaseConnectionDriversSqliteSqlAlterTable exten
|
|
|
29
40
|
const newTableData = new TableData(tempTableName)
|
|
30
41
|
|
|
31
42
|
for (const tableDataColumn of currentTableData.getColumns()) {
|
|
32
|
-
const newTableDataColumn =
|
|
43
|
+
const newTableDataColumn = tableData.getColumns().find((newTableDataColumn) => newTableDataColumn.getName() == tableDataColumn.getName())
|
|
44
|
+
|
|
45
|
+
if (newTableDataColumn) {
|
|
46
|
+
const settingsToClone = ["autoIncrement", "default", "index", "foreignKey", "maxLength", "primaryKey", "type"]
|
|
47
|
+
|
|
48
|
+
for (const settingToClone of settingsToClone) {
|
|
49
|
+
const camelizedSettingToClone = inflection.camelize(settingToClone)
|
|
50
|
+
|
|
51
|
+
if (!newTableDataColumn[`get${camelizedSettingToClone}`]) {
|
|
52
|
+
throw new Error(`No such method on column: get${camelizedSettingToClone}`)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!newTableDataColumn[`get${camelizedSettingToClone}`]()) {
|
|
56
|
+
newTableDataColumn[`set${camelizedSettingToClone}`](tableDataColumn[`get${camelizedSettingToClone}`]())
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
33
60
|
|
|
34
61
|
newTableData.addColumn(newTableDataColumn || tableDataColumn)
|
|
35
62
|
}
|
|
36
63
|
|
|
64
|
+
for (const tableDataColumn of tableData.getColumns()) {
|
|
65
|
+
if (!tableDataColumn.isNewColumn()) continue
|
|
66
|
+
|
|
67
|
+
newTableData.addColumn(tableDataColumn)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const foundForeignKeys = []
|
|
71
|
+
|
|
72
|
+
for (const tableDataForeignKey of currentTableData.getForeignKeys()) {
|
|
73
|
+
const newTableDataForeignKey = newTableData.getForeignKeys().find((newTableDataForeignKey) => newTableDataForeignKey.getName() == tableDataForeignKey.getName())
|
|
74
|
+
|
|
75
|
+
if (newTableDataForeignKey) foundForeignKeys.push(newTableDataForeignKey.getName())
|
|
76
|
+
|
|
77
|
+
const actualTableDataForeignKey = newTableDataForeignKey || tableDataForeignKey
|
|
78
|
+
|
|
79
|
+
// Register foreign key on the table
|
|
80
|
+
newTableData.addForeignKey(actualTableDataForeignKey)
|
|
81
|
+
|
|
82
|
+
// Register foreign key on the column
|
|
83
|
+
const tableDataColumn = newTableData.getColumns().find((newTableDataColumn) => newTableDataColumn.getName() == actualTableDataForeignKey.getColumnName())
|
|
84
|
+
|
|
85
|
+
if (!tableDataColumn) throw new Error(`Couldn't find column for foreign key: ${actualTableDataForeignKey.getName()}`)
|
|
86
|
+
|
|
87
|
+
this.logger.debug(() => [`Setting foreign key on column ${tableDataColumn.getName()}`])
|
|
88
|
+
tableDataColumn.setForeignKey(actualTableDataForeignKey)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
for (const foreignKey of tableData.getForeignKeys()) {
|
|
92
|
+
console.log(`Foreign key`, {foreignKey})
|
|
93
|
+
|
|
94
|
+
if (foundForeignKeys.includes(foreignKey.getName())) continue
|
|
95
|
+
|
|
96
|
+
// Register foreign key on the table
|
|
97
|
+
newTableData.addForeignKey(foreignKey)
|
|
98
|
+
|
|
99
|
+
// Register foreign key on the column
|
|
100
|
+
const tableDataColumn = newTableData.getColumns().find((newTableDataColumn) => newTableDataColumn.getName() == foreignKey.getColumnName())
|
|
101
|
+
|
|
102
|
+
if (!tableDataColumn) throw new Error(`Couldn't find column for foreign key: ${actualTableDataForeignKey.getName()}`)
|
|
103
|
+
|
|
104
|
+
this.logger.debug(() => [`Setting foreign key on column ${tableDataColumn.getName()}`])
|
|
105
|
+
tableDataColumn.setForeignKey(foreignKey)
|
|
106
|
+
}
|
|
107
|
+
|
|
37
108
|
const createNewTableSQL = this.getDriver().createTableSql(newTableData)
|
|
38
|
-
const insertSQL = `INSERT INTO ${options.quoteTableName(tempTableName)} (${
|
|
109
|
+
const insertSQL = `INSERT INTO ${options.quoteTableName(tempTableName)} (${newColumnsSQL}) SELECT ${oldColumnsSQL} FROM ${options.quoteTableName(tableName)}`
|
|
39
110
|
const dropTableSQL = `DROP TABLE ${options.quoteTableName(tableName)}`
|
|
40
111
|
const renameTableSQL = `ALTER TABLE ${options.quoteTableName(tempTableName)} RENAME TO ${options.quoteTableName(tableName)}`
|
|
41
112
|
const sqls = []
|
|
@@ -54,10 +125,14 @@ export default class VelociousDatabaseConnectionDriversSqliteSqlAlterTable exten
|
|
|
54
125
|
|
|
55
126
|
newTableData.addIndex(actualTableIndex)
|
|
56
127
|
|
|
57
|
-
|
|
128
|
+
const columnNames = actualTableIndex.getColumns().map((columnName) => {
|
|
129
|
+
const newTableColumn = tableData.getColumns().find((tableColumn) => tableColumn.getName() == columnName)
|
|
130
|
+
|
|
131
|
+
return newTableColumn?.getNewName() || newTableColumn?.getName() || columnName
|
|
132
|
+
})
|
|
58
133
|
|
|
59
134
|
const createIndexArgs = {
|
|
60
|
-
columns:
|
|
135
|
+
columns: columnNames,
|
|
61
136
|
driver: this.getDriver(),
|
|
62
137
|
name: actualTableIndex.getName(),
|
|
63
138
|
tableName,
|
|
@@ -68,8 +143,6 @@ export default class VelociousDatabaseConnectionDriversSqliteSqlAlterTable exten
|
|
|
68
143
|
sqls.push(sql)
|
|
69
144
|
}
|
|
70
145
|
|
|
71
|
-
console.log({sqls})
|
|
72
|
-
|
|
73
146
|
return sqls
|
|
74
147
|
}
|
|
75
148
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as inflection from "inflection"
|
|
2
2
|
import restArgsError from "../../utils/rest-args-error.js"
|
|
3
|
-
import TableData
|
|
3
|
+
import TableData from "../table-data/index.js"
|
|
4
4
|
|
|
5
5
|
export default class VelociousDatabaseMigration {
|
|
6
6
|
static onDatabases(databaseIdentifiers) {
|
|
@@ -29,15 +29,17 @@ export default class VelociousDatabaseMigration {
|
|
|
29
29
|
getDriver() { return this._db }
|
|
30
30
|
|
|
31
31
|
async addColumn(tableName, columnName, columnType, args) {
|
|
32
|
-
|
|
32
|
+
if (!columnType) throw new Error("No column type given")
|
|
33
|
+
|
|
34
|
+
const tableColumnArgs = Object.assign({isNewColumn: true, type: columnType}, args)
|
|
33
35
|
const tableData = new TableData(tableName)
|
|
34
36
|
|
|
35
37
|
tableData.addColumn(columnName, tableColumnArgs)
|
|
36
38
|
|
|
37
|
-
const sqls = await this.
|
|
39
|
+
const sqls = await this.getDriver().alterTableSql(tableData)
|
|
38
40
|
|
|
39
41
|
for (const sql of sqls) {
|
|
40
|
-
await this.
|
|
42
|
+
await this.getDriver().query(sql)
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
|
|
@@ -49,9 +51,9 @@ export default class VelociousDatabaseMigration {
|
|
|
49
51
|
},
|
|
50
52
|
args
|
|
51
53
|
)
|
|
52
|
-
const sql = this.
|
|
54
|
+
const sql = this.getDriver().createIndexSql(createIndexArgs)
|
|
53
55
|
|
|
54
|
-
await this.
|
|
56
|
+
await this.getDriver().query(sql)
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
async addForeignKey(tableName, referenceName) {
|
|
@@ -59,23 +61,29 @@ export default class VelociousDatabaseMigration {
|
|
|
59
61
|
const tableNameUnderscore = inflection.underscore(tableName)
|
|
60
62
|
const columnName = `${referenceNameUnderscore}_id`
|
|
61
63
|
const foreignKeyName = `fk_${tableName}_${referenceName}`
|
|
62
|
-
let sql = ""
|
|
63
|
-
|
|
64
|
-
sql += `ALTER TABLE ${this._db.quoteTable(tableName)}`
|
|
65
|
-
sql += ` ADD CONSTRAINT ${foreignKeyName} `
|
|
66
|
-
sql += ` FOREIGN KEY (${this._db.quoteColumn(columnName)})`
|
|
67
|
-
sql += ` REFERENCES ${tableNameUnderscore}(id)`
|
|
68
64
|
|
|
69
|
-
await this.
|
|
65
|
+
await this.getDriver().addForeignKey(
|
|
66
|
+
tableName,
|
|
67
|
+
columnName,
|
|
68
|
+
tableNameUnderscore,
|
|
69
|
+
"id",
|
|
70
|
+
{
|
|
71
|
+
isNewForeignKey: true,
|
|
72
|
+
name: foreignKeyName
|
|
73
|
+
}
|
|
74
|
+
)
|
|
70
75
|
}
|
|
71
76
|
|
|
72
77
|
async addReference(tableName, referenceName, args) {
|
|
78
|
+
const {foreignKey, type, unique, ...restArgs} = args
|
|
73
79
|
const columnName = `${inflection.underscore(referenceName)}_id`
|
|
74
80
|
|
|
75
|
-
|
|
76
|
-
|
|
81
|
+
restArgsError(restArgs)
|
|
82
|
+
|
|
83
|
+
await this.addColumn(tableName, columnName, type || "integer")
|
|
84
|
+
await this.addIndex(tableName, [columnName], {unique: unique})
|
|
77
85
|
|
|
78
|
-
if (
|
|
86
|
+
if (foreignKey) {
|
|
79
87
|
await this.addForeignKey(tableName, referenceName)
|
|
80
88
|
}
|
|
81
89
|
}
|
|
@@ -118,15 +126,19 @@ export default class VelociousDatabaseMigration {
|
|
|
118
126
|
callback(tableData)
|
|
119
127
|
}
|
|
120
128
|
|
|
121
|
-
const sqls = this.
|
|
129
|
+
const sqls = this.getDriver().createTableSql(tableData)
|
|
122
130
|
|
|
123
131
|
for (const sql of sqls) {
|
|
124
132
|
await this._db.query(sql)
|
|
125
133
|
}
|
|
126
134
|
}
|
|
127
135
|
|
|
136
|
+
async renameColumn(tableName, oldColumnName, newColumnName) {
|
|
137
|
+
await this.getDriver().renameColumn(tableName, oldColumnName, newColumnName)
|
|
138
|
+
}
|
|
139
|
+
|
|
128
140
|
async tableExists(tableName) {
|
|
129
|
-
const exists = await this.
|
|
141
|
+
const exists = await this.getDriver().tableExists(tableName)
|
|
130
142
|
|
|
131
143
|
return exists
|
|
132
144
|
}
|
|
@@ -27,15 +27,20 @@ export default class VelociousDatabaseQueryAlterTableBase extends QueryBase {
|
|
|
27
27
|
|
|
28
28
|
if (column.isNewColumn()) {
|
|
29
29
|
sql += "ADD "
|
|
30
|
+
sql += column.getSQL({driver: this.getDriver(), forAlterTable: true})
|
|
31
|
+
} else if (column.getNewName()) {
|
|
32
|
+
sql += `RENAME COLUMN ${options.quoteColumnName(column.getName())} TO ${options.quoteColumnName(column.getNewName())}`
|
|
30
33
|
} else {
|
|
31
34
|
if (databaseType == "mssql" || databaseType == "pgsql") {
|
|
32
35
|
sql += "ALTER COLUMN "
|
|
33
36
|
} else {
|
|
34
37
|
sql += "MODIFY "
|
|
35
38
|
}
|
|
39
|
+
|
|
40
|
+
sql += column.getSQL({driver: this.getDriver(), forAlterTable: true})
|
|
36
41
|
}
|
|
37
42
|
|
|
38
|
-
|
|
43
|
+
|
|
39
44
|
columnsCount++
|
|
40
45
|
}
|
|
41
46
|
|
|
@@ -12,7 +12,10 @@ export default class VelociousDatabaseQueryCreateIndexBase extends QueryBase {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
generateIndexName() {
|
|
15
|
-
|
|
15
|
+
const databaseType = this.getDriver().getType()
|
|
16
|
+
let indexName = `index_on_`
|
|
17
|
+
|
|
18
|
+
if (databaseType == "sqlite") indexName += `${this.tableName}_`
|
|
16
19
|
|
|
17
20
|
for (const columnIndex in this.columns) {
|
|
18
21
|
if (columnIndex > 0) indexName += "_and_"
|
|
@@ -33,17 +36,34 @@ export default class VelociousDatabaseQueryCreateIndexBase extends QueryBase {
|
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
toSql() {
|
|
39
|
+
const databaseType = this.getDriver().getType()
|
|
40
|
+
const indexName = this.name || this.generateIndexName()
|
|
36
41
|
const options = this.getOptions()
|
|
37
42
|
const {tableName} = this
|
|
38
|
-
let sql = "
|
|
43
|
+
let sql = ""
|
|
44
|
+
|
|
45
|
+
if (this.ifNotExists && databaseType == "mssql") {
|
|
46
|
+
sql += `
|
|
47
|
+
IF NOT EXISTS (
|
|
48
|
+
SELECT 1
|
|
49
|
+
FROM sys.indexes
|
|
50
|
+
WHERE
|
|
51
|
+
name = ${options.quote(indexName)} AND
|
|
52
|
+
object_id = OBJECT_ID(${options.quote(`dbo.${tableName}`)})
|
|
53
|
+
)
|
|
54
|
+
BEGIN
|
|
55
|
+
`
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
sql += "CREATE"
|
|
39
59
|
|
|
40
60
|
if (this.unique) sql += " UNIQUE"
|
|
41
61
|
|
|
42
62
|
sql += " INDEX"
|
|
43
63
|
|
|
44
|
-
if (this.ifNotExists) sql += " IF NOT EXISTS"
|
|
64
|
+
if (this.ifNotExists && databaseType != "mssql") sql += " IF NOT EXISTS"
|
|
45
65
|
|
|
46
|
-
sql += ` ${options.quoteIndexName(
|
|
66
|
+
sql += ` ${options.quoteIndexName(indexName)}`
|
|
47
67
|
sql += ` ON ${options.quoteTableName(tableName)} (`
|
|
48
68
|
|
|
49
69
|
for (const columnIndex in this.columns) {
|
|
@@ -63,6 +83,10 @@ export default class VelociousDatabaseQueryCreateIndexBase extends QueryBase {
|
|
|
63
83
|
|
|
64
84
|
sql += ")"
|
|
65
85
|
|
|
86
|
+
if (this.ifNotExists && databaseType == "mssql") {
|
|
87
|
+
sql += " END"
|
|
88
|
+
}
|
|
89
|
+
|
|
66
90
|
return sql
|
|
67
91
|
}
|
|
68
92
|
}
|
|
@@ -68,10 +68,15 @@ export default class VelociousDatabaseQueryCreateTableBase extends QueryBase {
|
|
|
68
68
|
sql += ")"
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
// Create indexes for all columns with the index argument
|
|
71
72
|
for (const column of tableData.getColumns()) {
|
|
72
73
|
if (!column.getIndex()) continue
|
|
73
74
|
|
|
74
|
-
|
|
75
|
+
let indexName = `index_on_`
|
|
76
|
+
|
|
77
|
+
if (databaseType == "sqlite") sql += `${tableData.getName()}_`
|
|
78
|
+
|
|
79
|
+
indexName += column.getName()
|
|
75
80
|
|
|
76
81
|
sql += ","
|
|
77
82
|
|
|
@@ -100,6 +105,7 @@ export default class VelociousDatabaseQueryCreateTableBase extends QueryBase {
|
|
|
100
105
|
const createIndexArgs = {
|
|
101
106
|
columns: index.getColumns(),
|
|
102
107
|
driver: this.getDriver(),
|
|
108
|
+
ifNotExists: true,
|
|
103
109
|
name: index.getName(),
|
|
104
110
|
tableName: tableData.getName(),
|
|
105
111
|
unique: index.getUnique()
|
|
@@ -109,14 +115,20 @@ export default class VelociousDatabaseQueryCreateTableBase extends QueryBase {
|
|
|
109
115
|
sqls.push(sql)
|
|
110
116
|
}
|
|
111
117
|
|
|
118
|
+
// Create indexes for all columns with the index argument
|
|
112
119
|
for (const column of tableData.getColumns()) {
|
|
113
120
|
if (!column.getIndex()) continue
|
|
114
121
|
|
|
115
|
-
const indexName = `index_on_${tableData.getName()}_${column.getName()}`
|
|
116
122
|
const {unique, ...restIndexArgs} = column.getIndex()
|
|
117
123
|
|
|
118
124
|
restArgsError(restIndexArgs)
|
|
119
125
|
|
|
126
|
+
let indexName = `index_on_`
|
|
127
|
+
|
|
128
|
+
if (databaseType == "sqlite") indexName += `${tableData.getName()}_`
|
|
129
|
+
|
|
130
|
+
indexName += column.getName()
|
|
131
|
+
|
|
120
132
|
const createIndexArgs = {
|
|
121
133
|
columns: [column.getName()],
|
|
122
134
|
driver: this.getDriver(),
|
|
@@ -1,152 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
class TableColumn {
|
|
5
|
-
constructor(name, args) {
|
|
6
|
-
if (args) {
|
|
7
|
-
const {autoIncrement, default: columnDefault, foreignKey, index, isNewColumn, maxLength, name, null: argsNull, primaryKey, type, ...restArgs} = args
|
|
8
|
-
|
|
9
|
-
if (Object.keys(args).length == 0) {
|
|
10
|
-
throw new Error("Empty args given")
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
restArgsError(restArgs)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
this.args = args
|
|
17
|
-
this.name = name
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
getAutoIncrement() { return this.args?.autoIncrement }
|
|
21
|
-
getDefault() { return this.args?.default }
|
|
22
|
-
getForeignKey() { return this.args?.foreignKey }
|
|
23
|
-
getIndex() { return this.args?.index }
|
|
24
|
-
getMaxLength() { return this.args?.maxLength }
|
|
25
|
-
getName() { return this.name }
|
|
26
|
-
getNull() { return this.args?.null }
|
|
27
|
-
setNull(nullable) { this.args.null = nullable }
|
|
28
|
-
getPrimaryKey() { return this.args?.primaryKey }
|
|
29
|
-
getType() { return this.args?.type }
|
|
30
|
-
isNewColumn() { return this.args?.isNewColumn }
|
|
31
|
-
|
|
32
|
-
getSQL({forAlterTable, driver}) {
|
|
33
|
-
const databaseType = driver.getType()
|
|
34
|
-
const options = driver.options()
|
|
35
|
-
let maxlength = this.getMaxLength()
|
|
36
|
-
let type = this.getType().toUpperCase()
|
|
37
|
-
|
|
38
|
-
if (type == "DATETIME" && databaseType == "pgsql") {
|
|
39
|
-
type = "TIMESTAMP"
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (type == "STRING") {
|
|
43
|
-
type = "VARCHAR"
|
|
44
|
-
maxlength ||= 255
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (databaseType == "mssql" && type == "BOOLEAN") {
|
|
48
|
-
type = "BIT"
|
|
49
|
-
} else if (databaseType == "mssql" && type == "UUID") {
|
|
50
|
-
type = "VARCHAR"
|
|
51
|
-
maxlength ||= 36
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (databaseType == "sqlite" && this.getAutoIncrement() && this.getPrimaryKey()) {
|
|
55
|
-
type = "INTEGER"
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (databaseType == "pgsql" && this.getAutoIncrement() && this.getPrimaryKey()) {
|
|
59
|
-
type = "SERIAL"
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
let sql = `${options.quoteColumnName(this.getName())} `
|
|
63
|
-
|
|
64
|
-
if (databaseType == "pgsql" && forAlterTable) sql += "TYPE "
|
|
65
|
-
|
|
66
|
-
sql += type
|
|
67
|
-
|
|
68
|
-
if (maxlength !== undefined && maxlength !== null) sql += `(${maxlength})`
|
|
69
|
-
|
|
70
|
-
if (this.getAutoIncrement() && driver.shouldSetAutoIncrementWhenPrimaryKey()) {
|
|
71
|
-
if (databaseType == "mssql") {
|
|
72
|
-
sql += " IDENTITY"
|
|
73
|
-
} else if (databaseType == "pgsql") {
|
|
74
|
-
if (this.getAutoIncrement() && this.getPrimaryKey()) {
|
|
75
|
-
// Do nothing
|
|
76
|
-
} else {
|
|
77
|
-
throw new Error("pgsql auto increment must be primary key")
|
|
78
|
-
}
|
|
79
|
-
} else {
|
|
80
|
-
sql += " AUTO_INCREMENT"
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (typeof this.getDefault() == "function") {
|
|
85
|
-
const defaultValue = this.getDefault()()
|
|
86
|
-
|
|
87
|
-
sql += ` DEFAULT (`
|
|
88
|
-
|
|
89
|
-
if (databaseType == "pgsql" && defaultValue == "UUID()") {
|
|
90
|
-
sql += "gen_random_uuid()"
|
|
91
|
-
} else if (databaseType == "mssql" && defaultValue == "UUID()") {
|
|
92
|
-
sql += "NEWID()"
|
|
93
|
-
} else {
|
|
94
|
-
sql += defaultValue
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
sql += ")"
|
|
98
|
-
} else if (this.getDefault()) {
|
|
99
|
-
sql += ` DEFAULT ${options.quote(this.getDefault())}`
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (this.getPrimaryKey()) sql += " PRIMARY KEY"
|
|
103
|
-
if (this.getNull() === false) sql += " NOT NULL"
|
|
104
|
-
|
|
105
|
-
if (this.getForeignKey()) {
|
|
106
|
-
let foreignKeyTable, foreignKeyColumn
|
|
107
|
-
|
|
108
|
-
if (this.getForeignKey() === true) {
|
|
109
|
-
foreignKeyColumn = "id"
|
|
110
|
-
foreignKeyTable = inflection.pluralize(this.getName().replace(/_id$/, ""))
|
|
111
|
-
} else {
|
|
112
|
-
throw new Error(`Unknown foreign key type given: ${this.getForeignKey()} (${typeof this.getForeignKey()})`)
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
sql += ` REFERENCES ${options.quoteTableName(foreignKeyTable)}(${options.quoteColumnName(foreignKeyColumn)})`
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return sql
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
class TableIndex {
|
|
123
|
-
constructor(columns, args) {
|
|
124
|
-
if (args) {
|
|
125
|
-
const {name, unique, ...restArgs} = args
|
|
126
|
-
|
|
127
|
-
restArgsError(restArgs)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
this.args = args
|
|
131
|
-
this.columns = columns
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
getColumns() { return this.columns }
|
|
135
|
-
getName() { return this.args.name }
|
|
136
|
-
getUnique() { return Boolean(this.args.unique) }
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
class TableReference {
|
|
140
|
-
constructor(name, args) {
|
|
141
|
-
this.args = args
|
|
142
|
-
this.name = name
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
export {TableColumn, TableIndex}
|
|
1
|
+
import TableColumn from "./table-column.js"
|
|
2
|
+
import TableIndex from "./table-index.js"
|
|
3
|
+
import TableReference from "./table-reference.js"
|
|
147
4
|
|
|
148
5
|
export default class TableData {
|
|
149
6
|
_columns = []
|
|
7
|
+
_foreignKeys = []
|
|
150
8
|
_indexes = []
|
|
151
9
|
_references = []
|
|
152
10
|
|
|
@@ -167,12 +25,17 @@ export default class TableData {
|
|
|
167
25
|
}
|
|
168
26
|
}
|
|
169
27
|
|
|
170
|
-
addIndex(index) { this._indexes.push(index) }
|
|
171
28
|
getColumns() { return this._columns }
|
|
29
|
+
|
|
30
|
+
addForeignKey(foreignKey) { this._foreignKeys.push(foreignKey) }
|
|
31
|
+
getForeignKeys() { return this._foreignKeys }
|
|
32
|
+
|
|
33
|
+
addIndex(index) { this._indexes.push(index) }
|
|
34
|
+
getIndexes() { return this._indexes }
|
|
35
|
+
|
|
172
36
|
getName() { return this._name }
|
|
173
37
|
setName(newName) { this._name = newName }
|
|
174
38
|
getIfNotExists() { return this.args.ifNotExists }
|
|
175
|
-
getIndexes() { return this._indexes }
|
|
176
39
|
getReferences() { return this._references }
|
|
177
40
|
|
|
178
41
|
bigint(name, args = {}) { this.addColumn(name, Object.assign({isNewColumn: true, type: "bigint"}, args)) }
|
|
@@ -184,11 +47,10 @@ export default class TableData {
|
|
|
184
47
|
|
|
185
48
|
references(name, args = {}) {
|
|
186
49
|
const columnName = `${name}_id`
|
|
187
|
-
const indexName = `index_on_${this.getName()}_${columnName}`
|
|
188
50
|
const reference = new TableReference(name, args)
|
|
189
51
|
const columnArgs = Object.assign({isNewColumn: true, type: "bigint"}, args)
|
|
190
52
|
const column = new TableColumn(columnName, columnArgs)
|
|
191
|
-
const index = new TableIndex([column]
|
|
53
|
+
const index = new TableIndex([column])
|
|
192
54
|
|
|
193
55
|
this._columns.push(column)
|
|
194
56
|
this._indexes.push(index)
|