velocious 1.0.36 → 1.0.37
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/README.md +1 -0
- package/package.json +3 -1
- package/peak_flow.yml +22 -2
- package/spec/cli/commands/db/create-spec.js +6 -0
- package/spec/database/drivers/mysql/connection-spec.js +1 -1
- package/spec/database/record/create-spec.js +24 -0
- package/spec/database/record/update-spec.js +15 -0
- package/spec/database/record/validations-spec.js +28 -0
- package/spec/database/transactions-spec.js +36 -0
- package/spec/dummy/src/config/{configuration.sqlite.js → configuration.peakflow.pgsql.js} +11 -38
- package/spec/dummy/src/models/task.js +1 -0
- package/src/cli/commands/db/create.js +15 -10
- package/src/cli/commands/test.js +8 -0
- package/src/configuration.js +14 -0
- package/src/database/drivers/base.js +19 -2
- package/src/database/drivers/mssql/index.js +10 -1
- package/src/database/drivers/mssql/sql/create-database.js +1 -1
- package/src/database/drivers/mysql/index.js +2 -2
- package/src/database/drivers/pgsql/column.js +10 -0
- package/src/database/drivers/pgsql/foreign-key.js +13 -0
- package/src/database/drivers/pgsql/index.js +172 -0
- package/src/database/drivers/pgsql/options.js +18 -0
- package/src/database/drivers/pgsql/query-parser.js +4 -0
- package/src/database/drivers/pgsql/sql/create-database.js +37 -0
- package/src/database/drivers/pgsql/sql/create-index.js +4 -0
- package/src/database/drivers/pgsql/sql/create-table.js +4 -0
- package/src/database/drivers/pgsql/sql/delete.js +19 -0
- package/src/database/drivers/pgsql/sql/drop-table.js +4 -0
- package/src/database/drivers/pgsql/sql/insert.js +4 -0
- package/src/database/drivers/pgsql/sql/update.js +31 -0
- package/src/database/drivers/pgsql/table.js +62 -0
- package/src/database/drivers/sqlite/base.js +4 -0
- package/src/database/drivers/sqlite/column.js +10 -0
- package/src/database/migrator.js +1 -1
- package/src/database/query/create-database-base.js +1 -1
- package/src/database/query/create-table-base.js +16 -2
- package/src/database/query/index.js +10 -1
- package/src/database/query/insert-base.js +1 -1
- package/src/database/record/index.js +162 -18
- package/src/database/record/validators/base.js +2 -0
- package/src/database/record/validators/presence.js +13 -0
- package/src/database/record/validators/uniqueness.js +23 -0
- package/src/testing/test-runner.js +10 -0
- package/spec/dummy/src/config/configuration.mariadb.js +0 -97
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import Base from "../base.js"
|
|
2
|
+
import {Client, escapeLiteral} from "pg"
|
|
3
|
+
import CreateDatabase from "./sql/create-database.js"
|
|
4
|
+
import CreateIndex from "./sql/create-index.js"
|
|
5
|
+
import CreateTable from "./sql/create-table.js"
|
|
6
|
+
import Delete from "./sql/delete.js"
|
|
7
|
+
import {digg} from "diggerize"
|
|
8
|
+
import DropTable from "./sql/drop-table.js"
|
|
9
|
+
import Insert from "./sql/insert.js"
|
|
10
|
+
import Options from "./options.js"
|
|
11
|
+
import QueryParser from "./query-parser.js"
|
|
12
|
+
import Table from "./table.js"
|
|
13
|
+
import Update from "./sql/update.js"
|
|
14
|
+
|
|
15
|
+
export default class VelociousDatabaseDriversPgsql extends Base{
|
|
16
|
+
async connect() {
|
|
17
|
+
const client = new Client(this.connectArgs())
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
await client.connect()
|
|
21
|
+
} catch (error) {
|
|
22
|
+
// Re-throw to recover real stack trace
|
|
23
|
+
throw new Error(`Connect to Postgres server failed: ${error.message}`)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
this.connection = client
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
disconnect() {
|
|
30
|
+
this.connection.end()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
connectArgs() {
|
|
34
|
+
const args = this.getArgs()
|
|
35
|
+
const connectArgs = []
|
|
36
|
+
const forward = ["database", "host", "password", "port"]
|
|
37
|
+
|
|
38
|
+
for (const forwardValue of forward) {
|
|
39
|
+
if (forwardValue in args) connectArgs[forwardValue] = digg(args, forwardValue)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if ("username" in args) connectArgs["user"] = args["username"]
|
|
43
|
+
|
|
44
|
+
return connectArgs
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async close() {
|
|
48
|
+
await this.connection.end()
|
|
49
|
+
this.connection = undefined
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
createDatabaseSql(databaseName, args) {
|
|
53
|
+
const createArgs = Object.assign({databaseName, driver: this}, args)
|
|
54
|
+
const createDatabase = new CreateDatabase(createArgs)
|
|
55
|
+
|
|
56
|
+
return createDatabase.toSql()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
createIndexSql(indexData) {
|
|
60
|
+
const createArgs = Object.assign({driver: this}, indexData)
|
|
61
|
+
const createIndex = new CreateIndex(createArgs)
|
|
62
|
+
|
|
63
|
+
return createIndex.toSql()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
createTableSql(tableData) {
|
|
67
|
+
const createArgs = Object.assign({tableData, driver: this, indexInCreateTable: false})
|
|
68
|
+
const createTable = new CreateTable(createArgs)
|
|
69
|
+
|
|
70
|
+
return createTable.toSql()
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async disableForeignKeys() {
|
|
74
|
+
await this.query("SET FOREIGN_KEY_CHECKS = 0")
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async enableForeignKeys() {
|
|
78
|
+
await this.query("SET FOREIGN_KEY_CHECKS = 1")
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
dropTableSql(tableName, args = {}) {
|
|
82
|
+
const dropArgs = Object.assign({tableName, driver: this}, args)
|
|
83
|
+
const dropTable = new DropTable(dropArgs)
|
|
84
|
+
|
|
85
|
+
return dropTable.toSql()
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
getType = () => "pgsql"
|
|
89
|
+
primaryKeyType = () => "bigint"
|
|
90
|
+
|
|
91
|
+
async query(sql) {
|
|
92
|
+
let response
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
response = await this.connection.query(sql)
|
|
96
|
+
} catch (error) {
|
|
97
|
+
throw new Error(`Query failed: ${error.message} with SQL: ${sql}`)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return response.rows
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
queryToSql(query) {
|
|
104
|
+
return new QueryParser({query}).toSql()
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
shouldSetAutoIncrementWhenPrimaryKey = () => true
|
|
108
|
+
|
|
109
|
+
escape(value) {
|
|
110
|
+
if (!this.connection) throw new Error("Can't escape before connected")
|
|
111
|
+
if (typeof value === "number") return value
|
|
112
|
+
|
|
113
|
+
const escapedValueWithQuotes = this.connection.escapeLiteral(this._convertValue(value))
|
|
114
|
+
|
|
115
|
+
return escapedValueWithQuotes.slice(1, escapedValueWithQuotes.length - 1)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
quote(value) {
|
|
119
|
+
if (!this.connection) throw new Error("Can't escape before connected")
|
|
120
|
+
if (typeof value === "number") return value
|
|
121
|
+
|
|
122
|
+
return this.connection.escapeLiteral(this._convertValue(value))
|
|
123
|
+
}
|
|
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 * FROM information_schema.tables WHERE table_catalog = CURRENT_DATABASE() AND table_schema = 'public'")
|
|
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 lastInsertID() {
|
|
152
|
+
const result = await this.query("SELECT LASTVAL() AS last_insert_id")
|
|
153
|
+
|
|
154
|
+
return digg(result, 0, "last_insert_id")
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
options() {
|
|
158
|
+
if (!this._options) this._options = new Options({driver: this})
|
|
159
|
+
|
|
160
|
+
return this._options
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async startTransaction() {
|
|
164
|
+
return await this.query("START TRANSACTION")
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
updateSql({conditions, data, tableName}) {
|
|
168
|
+
const update = new Update({conditions, data, driver: this, tableName})
|
|
169
|
+
|
|
170
|
+
return update.toSql()
|
|
171
|
+
}
|
|
172
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import QueryParserOptions from "../../query-parser/options.js"
|
|
2
|
+
|
|
3
|
+
export default class VelociousDatabaseDriversPgsqlOptions 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
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import CreateDatabaseBase from "../../../query/create-database-base.js"
|
|
2
|
+
import {digs} from "diggerize"
|
|
3
|
+
|
|
4
|
+
export default class VelociousDatabaseConnectionDriversPgsqlSqlCreateDatabase extends CreateDatabaseBase {
|
|
5
|
+
toSql() {
|
|
6
|
+
const {databaseName} = this
|
|
7
|
+
const options = this.getOptions()
|
|
8
|
+
const sqls = []
|
|
9
|
+
|
|
10
|
+
if (this.ifNotExists) {
|
|
11
|
+
sqls.push("CREATE EXTENSION IF NOT EXISTS dblink")
|
|
12
|
+
|
|
13
|
+
const connectArgs = this._driver.connectArgs()
|
|
14
|
+
const {password, user} = digs(connectArgs, "password", "user")
|
|
15
|
+
const port = connectArgs.port || 5432
|
|
16
|
+
const sql = `
|
|
17
|
+
DO
|
|
18
|
+
$do$
|
|
19
|
+
BEGIN
|
|
20
|
+
IF EXISTS (SELECT FROM ${options.quoteTableName("pg_database")} WHERE ${options.quoteColumnName("datname")} = ${options.quote(databaseName)}) THEN
|
|
21
|
+
RAISE NOTICE 'Database already exists'; -- optional
|
|
22
|
+
ELSE
|
|
23
|
+
PERFORM dblink_connect('host=localhost port=' || ${port} || ' user=' || ${options.quote(user)} || ' password=' || ${options.quote(password)} || ' dbname=' || current_database());
|
|
24
|
+
PERFORM dblink_exec('CREATE DATABASE ' || ${options.quote(databaseName)});
|
|
25
|
+
END IF;
|
|
26
|
+
END
|
|
27
|
+
$do$;
|
|
28
|
+
`
|
|
29
|
+
|
|
30
|
+
sqls.push(sql)
|
|
31
|
+
} else {
|
|
32
|
+
sqls.push(`CREATE DATABASE ${options.quoteDatabaseName(databaseName)}`)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return sqls
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import DeleteBase from "../../../query/delete-base.js"
|
|
2
|
+
|
|
3
|
+
export default class VelociousDatabaseConnectionDriversPgsqlSqlDelete 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 VelociousDatabaseConnectionDriversPgsqlSqlUpdate 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,62 @@
|
|
|
1
|
+
import Column from "./column.js"
|
|
2
|
+
import ForeignKey from "./foreign-key.js"
|
|
3
|
+
|
|
4
|
+
export default class VelociousDatabaseDriversPgsqlTable {
|
|
5
|
+
constructor(driver, data) {
|
|
6
|
+
this.data = data
|
|
7
|
+
this.driver = driver
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async getColumns() {
|
|
11
|
+
const result = await this.driver.query(`SELECT * FROM information_schema.columns WHERE table_catalog = CURRENT_DATABASE() AND table_schema = 'public' AND table_name = '${this.getName()}'`)
|
|
12
|
+
const columns = []
|
|
13
|
+
|
|
14
|
+
for (const data of result) {
|
|
15
|
+
const column = new Column(this, data)
|
|
16
|
+
|
|
17
|
+
columns.push(column)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return columns
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async getForeignKeys() {
|
|
24
|
+
const sql = `
|
|
25
|
+
SELECT
|
|
26
|
+
tc.constraint_name,
|
|
27
|
+
tc.table_name,
|
|
28
|
+
kcu.column_name,
|
|
29
|
+
ccu.table_name AS foreign_table_name,
|
|
30
|
+
ccu.column_name AS foreign_column_name
|
|
31
|
+
|
|
32
|
+
FROM
|
|
33
|
+
information_schema.table_constraints AS tc
|
|
34
|
+
|
|
35
|
+
JOIN information_schema.key_column_usage AS kcu ON
|
|
36
|
+
tc.constraint_name = kcu.constraint_name
|
|
37
|
+
|
|
38
|
+
JOIN information_schema.constraint_column_usage AS ccu
|
|
39
|
+
ON ccu.constraint_name = tc.constraint_name
|
|
40
|
+
|
|
41
|
+
WHERE
|
|
42
|
+
constraint_type = 'FOREIGN KEY' AND
|
|
43
|
+
tc.table_catalog = CURRENT_DATABASE() AND
|
|
44
|
+
tc.table_name = ${this.driver.quote(this.getName())}
|
|
45
|
+
`
|
|
46
|
+
|
|
47
|
+
const foreignKeyRows = await this.driver.query(sql)
|
|
48
|
+
const foreignKeys = []
|
|
49
|
+
|
|
50
|
+
for (const foreignKeyRow of foreignKeyRows) {
|
|
51
|
+
const foreignKey = new ForeignKey(foreignKeyRow)
|
|
52
|
+
|
|
53
|
+
foreignKeys.push(foreignKey)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return foreignKeys
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
getName() {
|
|
60
|
+
return this.data.table_name
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -164,6 +164,8 @@ export default class VelociousDatabaseDriversSqliteBase extends Base {
|
|
|
164
164
|
shouldSetAutoIncrementWhenPrimaryKey = () => false
|
|
165
165
|
|
|
166
166
|
escape(value) {
|
|
167
|
+
value = this._convertValue(value)
|
|
168
|
+
|
|
167
169
|
const type = typeof value
|
|
168
170
|
|
|
169
171
|
if (type != "string") value = `${value}`
|
|
@@ -175,6 +177,8 @@ export default class VelociousDatabaseDriversSqliteBase extends Base {
|
|
|
175
177
|
}
|
|
176
178
|
|
|
177
179
|
quote(value) {
|
|
180
|
+
value = this._convertValue(value)
|
|
181
|
+
|
|
178
182
|
const type = typeof value
|
|
179
183
|
|
|
180
184
|
if (type == "number") return value
|
|
@@ -11,4 +11,14 @@ export default class VelociousDatabaseDriversSqliteColumn {
|
|
|
11
11
|
|
|
12
12
|
return this.column.name
|
|
13
13
|
}
|
|
14
|
+
|
|
15
|
+
getType() {
|
|
16
|
+
const match = this.column.type.match(/(.*)\((\d+)\)$/)
|
|
17
|
+
|
|
18
|
+
if (match) {
|
|
19
|
+
return match[1].toLowerCase()
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return this.column.type.toLowerCase()
|
|
23
|
+
}
|
|
14
24
|
}
|
package/src/database/migrator.js
CHANGED
|
@@ -214,7 +214,7 @@ export default class VelociousDatabaseMigrator {
|
|
|
214
214
|
const dateString = digg(migration, "date")
|
|
215
215
|
const existingSchemaMigrations = await db.newQuery()
|
|
216
216
|
.from("schema_migrations")
|
|
217
|
-
.where({version: dateString})
|
|
217
|
+
.where({version: `${dateString}`})
|
|
218
218
|
.results()
|
|
219
219
|
|
|
220
220
|
if (existingSchemaMigrations.length == 0) {
|
|
@@ -37,6 +37,10 @@ export default class VelociousDatabaseQueryCreateTableBase extends QueryBase {
|
|
|
37
37
|
let maxlength = column.getMaxLength()
|
|
38
38
|
let type = column.getType().toUpperCase()
|
|
39
39
|
|
|
40
|
+
if (type == "DATETIME" && databaseType == "pgsql") {
|
|
41
|
+
type = "TIMESTAMP"
|
|
42
|
+
}
|
|
43
|
+
|
|
40
44
|
if (type == "STRING") {
|
|
41
45
|
type = "VARCHAR"
|
|
42
46
|
maxlength ||= 255
|
|
@@ -50,6 +54,10 @@ export default class VelociousDatabaseQueryCreateTableBase extends QueryBase {
|
|
|
50
54
|
type = "INTEGER"
|
|
51
55
|
}
|
|
52
56
|
|
|
57
|
+
if (databaseType == "pgsql" && column.getAutoIncrement() && column.getPrimaryKey()) {
|
|
58
|
+
type = "SERIAL"
|
|
59
|
+
}
|
|
60
|
+
|
|
53
61
|
if (columnCount > 1) sql += ", "
|
|
54
62
|
|
|
55
63
|
sql += `${options.quoteColumnName(column.getName())} ${type}`
|
|
@@ -59,6 +67,12 @@ export default class VelociousDatabaseQueryCreateTableBase extends QueryBase {
|
|
|
59
67
|
if (column.getAutoIncrement() && driver.shouldSetAutoIncrementWhenPrimaryKey()) {
|
|
60
68
|
if (databaseType == "mssql") {
|
|
61
69
|
sql += " IDENTITY"
|
|
70
|
+
} else if (databaseType == "pgsql") {
|
|
71
|
+
if (column.getAutoIncrement() && column.getPrimaryKey()) {
|
|
72
|
+
// Do nothing
|
|
73
|
+
} else {
|
|
74
|
+
throw new Error("pgsql auto increment must be primary key")
|
|
75
|
+
}
|
|
62
76
|
} else {
|
|
63
77
|
sql += " AUTO_INCREMENT"
|
|
64
78
|
}
|
|
@@ -83,7 +97,7 @@ export default class VelociousDatabaseQueryCreateTableBase extends QueryBase {
|
|
|
83
97
|
throw new Error(`Unknown foreign key type given: ${column.getForeignKey()} (${typeof column.getForeignKey()})`)
|
|
84
98
|
}
|
|
85
99
|
|
|
86
|
-
sql += ` REFERENCES ${
|
|
100
|
+
sql += ` REFERENCES ${options.quoteTableName(foreignKeyTable)}(${options.quoteColumnName(foreignKeyColumn)})`
|
|
87
101
|
}
|
|
88
102
|
}
|
|
89
103
|
|
|
@@ -98,7 +112,7 @@ export default class VelociousDatabaseQueryCreateTableBase extends QueryBase {
|
|
|
98
112
|
sql += " INDEX"
|
|
99
113
|
|
|
100
114
|
if (index.getName()) {
|
|
101
|
-
sql += ` ${index.getName()}`
|
|
115
|
+
sql += ` ${options.quoteIndexName(index.getName())}`
|
|
102
116
|
}
|
|
103
117
|
|
|
104
118
|
sql += " ("
|
|
@@ -48,10 +48,19 @@ export default class VelociousDatabaseQuery {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
async count() {
|
|
51
|
+
// Generate count SQL
|
|
52
|
+
let sql = "COUNT(id)"
|
|
53
|
+
|
|
54
|
+
if (this.driver.getType() == "pgsql") sql += "::int"
|
|
55
|
+
|
|
56
|
+
sql += " AS count"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
// Clone query and execute count
|
|
51
60
|
const countQuery = this.clone()
|
|
52
61
|
|
|
53
62
|
countQuery._selects = []
|
|
54
|
-
countQuery.select(
|
|
63
|
+
countQuery.select(sql)
|
|
55
64
|
|
|
56
65
|
const results = await countQuery._executeQuery()
|
|
57
66
|
|
|
@@ -34,7 +34,7 @@ export default class VelociousDatabaseQueryInsertBase {
|
|
|
34
34
|
if (Object.keys(this.data).length <= 0) {
|
|
35
35
|
sql += lastInsertedSQL
|
|
36
36
|
}
|
|
37
|
-
} else if (driver.getType() == "mysql") {
|
|
37
|
+
} else if (driver.getType() == "mysql" || driver.getType() == "pgsql") {
|
|
38
38
|
lastInsertedSQL = ` RETURNING ${driver.quoteColumn(this.returnLastInsertedColumnName)} AS lastInsertID`
|
|
39
39
|
}
|
|
40
40
|
}
|