velocious 1.0.97 → 1.0.99
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/eslint.config.js +1 -0
- package/package.json +2 -1
- package/spec/database/connection/drivers/mysql/query-parser-spec.js +4 -4
- package/spec/http-server/post-spec.js +2 -0
- package/src/application.js +27 -9
- package/src/configuration-resolver.js +29 -10
- package/src/configuration-types.js +44 -0
- package/src/configuration.js +63 -33
- package/src/database/drivers/base-column.js +6 -1
- package/src/database/drivers/base-columns-index.js +11 -1
- package/src/database/drivers/base-foreign-key.js +45 -0
- package/src/database/drivers/base-table.js +24 -2
- package/src/database/drivers/base.js +211 -39
- package/src/database/drivers/mssql/index.js +1 -3
- package/src/database/drivers/sqlite/sql/alter-table.js +4 -2
- package/src/database/handler.js +5 -0
- package/src/database/migration/index.js +79 -20
- package/src/database/migrator/files-finder.js +21 -22
- package/src/database/migrator/types.js +29 -0
- package/src/database/migrator.js +98 -59
- package/src/database/pool/async-tracked-multi-connection.js +42 -7
- package/src/database/pool/base-methods-forward.js +37 -0
- package/src/database/pool/base.js +79 -46
- package/src/database/pool/single-multi-use.js +18 -3
- package/src/database/query/alter-table-base.js +4 -4
- package/src/database/query/base.js +9 -2
- package/src/database/query/create-database-base.js +8 -0
- package/src/database/query/create-index-base.js +20 -5
- package/src/database/query/create-table-base.js +28 -9
- package/src/database/query/from-base.js +17 -0
- package/src/database/query/from-plain.js +8 -3
- package/src/database/query/from-table.js +8 -3
- package/src/database/query/index.js +43 -32
- package/src/database/query/join-base.js +28 -1
- package/src/database/query/join-object.js +67 -0
- package/src/database/query/join-plain.js +6 -1
- package/src/database/query/order-base.js +18 -0
- package/src/database/query/order-plain.js +8 -2
- package/src/database/query/select-base.js +15 -0
- package/src/database/query/select-plain.js +6 -1
- package/src/database/query/select-table-and-column.js +8 -2
- package/src/database/query/where-base.js +23 -1
- package/src/database/query/where-hash.js +15 -0
- package/src/database/query/where-plain.js +6 -0
- package/src/database/query-parser/base-query-parser.js +8 -2
- package/src/database/query-parser/from-parser.js +2 -0
- package/src/database/query-parser/joins-parser.js +10 -45
- package/src/database/query-parser/select-parser.js +2 -0
- package/src/database/record/index.js +1 -1
- package/src/database/table-data/index.js +39 -121
- package/src/database/table-data/table-column.js +54 -25
- package/src/database/table-data/table-foreign-key.js +5 -3
- package/src/database/table-data/table-index.js +12 -6
- package/src/database/table-data/table-reference.js +2 -0
- package/src/database/use-database.js +4 -2
- package/src/environment-handlers/base.js +41 -8
- package/src/environment-handlers/node/cli/commands/destroy/migration.js +3 -0
- package/src/environment-handlers/node/cli/commands/generate/migration.js +3 -0
- package/src/environment-handlers/node/cli/commands/generate/model.js +3 -0
- package/src/environment-handlers/node/cli/commands/init.js +3 -0
- package/src/environment-handlers/node.js +59 -28
- package/src/http-client/header.js +6 -0
- package/src/http-client/request.js +31 -5
- package/src/http-client/response.js +31 -7
- package/src/http-server/client/index.js +24 -4
- package/src/http-server/client/request-buffer/form-data-part.js +11 -0
- package/src/http-server/client/request-buffer/header.js +6 -0
- package/src/http-server/client/request-buffer/index.js +91 -13
- package/src/http-server/client/request-parser.js +26 -0
- package/src/http-server/client/request-runner.js +15 -3
- package/src/http-server/client/request.js +17 -0
- package/src/http-server/client/response.js +41 -1
- package/src/http-server/index.js +32 -4
- package/src/http-server/server-client.js +33 -2
- package/src/http-server/worker-handler/index.js +42 -9
- package/src/http-server/worker-handler/worker-script.js +2 -0
- package/src/http-server/worker-handler/worker-thread.js +34 -6
- package/src/logger.js +21 -15
- package/src/routes/app-routes.js +1 -1
- package/src/testing/test-files-finder.js +8 -4
- package/src/testing/test-runner.js +76 -24
- package/src/utils/backtrace-cleaner.js +6 -4
- package/src/utils/ensure-error.js +13 -0
- package/src/utils/file-exists.js +3 -1
- package/src/utils/rest-args-error.js +2 -0
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import restArgsError from "../../utils/rest-args-error.js"
|
|
2
4
|
|
|
3
5
|
export default class VelociousDatabaseQueryBase {
|
|
6
|
+
/**
|
|
7
|
+
* @param {object} args
|
|
8
|
+
* @param {import("../drivers/base.js").default} args.driver
|
|
9
|
+
* @param {import("../query-parser/options.js").default} [args.options]
|
|
10
|
+
*/
|
|
4
11
|
constructor({driver, options, ...restArgs}) {
|
|
5
12
|
restArgsError(restArgs)
|
|
6
13
|
|
|
@@ -33,7 +40,7 @@ export default class VelociousDatabaseQueryBase {
|
|
|
33
40
|
* @interface
|
|
34
41
|
* @returns {string[]}
|
|
35
42
|
*/
|
|
36
|
-
|
|
37
|
-
throw new Error("'
|
|
43
|
+
toSqls() {
|
|
44
|
+
throw new Error("'toSqls' wasn't implemented")
|
|
38
45
|
}
|
|
39
46
|
}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import QueryBase from "./base.js"
|
|
2
4
|
|
|
3
5
|
export default class VelociousDatabaseQueryCreateDatabaseBase extends QueryBase {
|
|
6
|
+
/**
|
|
7
|
+
* @param {object} args
|
|
8
|
+
* @param {import("../drivers/base.js").default} args.driver
|
|
9
|
+
* @param {string} args.databaseName
|
|
10
|
+
* @param {boolean} [args.ifNotExists]
|
|
11
|
+
*/
|
|
4
12
|
constructor({driver, databaseName, ifNotExists}) {
|
|
5
13
|
super({driver})
|
|
6
14
|
this.databaseName = databaseName
|
|
@@ -1,6 +1,21 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import QueryBase from "./base.js"
|
|
2
4
|
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {object} CreateIndexBaseArgsType
|
|
7
|
+
* @property {Array<string | import("./../table-data/table-column.js").default>} columns
|
|
8
|
+
* @property {import("../drivers/base.js").default} driver
|
|
9
|
+
* @property {boolean} [ifNotExists]
|
|
10
|
+
* @property {string} [name]
|
|
11
|
+
* @property {boolean} [unique]
|
|
12
|
+
* @property {string} tableName
|
|
13
|
+
*/
|
|
14
|
+
|
|
3
15
|
export default class VelociousDatabaseQueryCreateIndexBase extends QueryBase {
|
|
16
|
+
/**
|
|
17
|
+
* @param {CreateIndexBaseArgsType} args
|
|
18
|
+
*/
|
|
4
19
|
constructor({columns, driver, ifNotExists, name, unique, tableName}) {
|
|
5
20
|
super({driver})
|
|
6
21
|
this.columns = columns
|
|
@@ -17,7 +32,7 @@ export default class VelociousDatabaseQueryCreateIndexBase extends QueryBase {
|
|
|
17
32
|
if (databaseType == "sqlite") indexName += `${this.tableName}_`
|
|
18
33
|
|
|
19
34
|
for (const columnIndex in this.columns) {
|
|
20
|
-
if (columnIndex > 0) indexName += "_and_"
|
|
35
|
+
if (typeof columnIndex == "number" && columnIndex > 0) indexName += "_and_"
|
|
21
36
|
|
|
22
37
|
const column = this.columns[columnIndex]
|
|
23
38
|
let columnName
|
|
@@ -35,9 +50,9 @@ export default class VelociousDatabaseQueryCreateIndexBase extends QueryBase {
|
|
|
35
50
|
}
|
|
36
51
|
|
|
37
52
|
/**
|
|
38
|
-
* @returns {string}
|
|
53
|
+
* @returns {string[]}
|
|
39
54
|
*/
|
|
40
|
-
|
|
55
|
+
toSqls() {
|
|
41
56
|
const databaseType = this.getDriver().getType()
|
|
42
57
|
const indexName = this.name || this.generateIndexName()
|
|
43
58
|
const options = this.getOptions()
|
|
@@ -69,7 +84,7 @@ export default class VelociousDatabaseQueryCreateIndexBase extends QueryBase {
|
|
|
69
84
|
sql += ` ON ${options.quoteTableName(tableName)} (`
|
|
70
85
|
|
|
71
86
|
for (const columnIndex in this.columns) {
|
|
72
|
-
if (columnIndex > 0) sql += ", "
|
|
87
|
+
if (typeof columnIndex == "number" && columnIndex > 0) sql += ", "
|
|
73
88
|
|
|
74
89
|
const column = this.columns[columnIndex]
|
|
75
90
|
let columnName
|
|
@@ -89,6 +104,6 @@ export default class VelociousDatabaseQueryCreateIndexBase extends QueryBase {
|
|
|
89
104
|
sql += " END"
|
|
90
105
|
}
|
|
91
106
|
|
|
92
|
-
return sql
|
|
107
|
+
return [sql]
|
|
93
108
|
}
|
|
94
109
|
}
|
|
@@ -1,10 +1,19 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import CreateIndexBase from "./create-index-base.js"
|
|
2
|
-
import {digs} from "diggerize"
|
|
3
4
|
import QueryBase from "./base.js"
|
|
4
5
|
import restArgsError from "../../utils/rest-args-error.js"
|
|
5
6
|
import TableData from "../table-data/index.js"
|
|
7
|
+
import TableColumn from "../table-data/table-column.js"
|
|
6
8
|
|
|
7
9
|
export default class VelociousDatabaseQueryCreateTableBase extends QueryBase {
|
|
10
|
+
/**
|
|
11
|
+
* @param {object} args
|
|
12
|
+
* @param {import("../drivers/base.js").default} args.driver
|
|
13
|
+
* @param {boolean} args.ifNotExists
|
|
14
|
+
* @param {boolean} args.indexInCreateTable
|
|
15
|
+
* @param {TableData} args.tableData
|
|
16
|
+
*/
|
|
8
17
|
constructor({driver, ifNotExists, indexInCreateTable = true, tableData}) {
|
|
9
18
|
if (!(tableData instanceof TableData)) throw new Error("Invalid table data was given")
|
|
10
19
|
|
|
@@ -21,7 +30,7 @@ export default class VelociousDatabaseQueryCreateTableBase extends QueryBase {
|
|
|
21
30
|
const databaseType = this.getDatabaseType()
|
|
22
31
|
const driver = this.getDriver()
|
|
23
32
|
const options = this.getOptions()
|
|
24
|
-
const {tableData} =
|
|
33
|
+
const {tableData} = this
|
|
25
34
|
const sqls = []
|
|
26
35
|
const ifNotExists = this.ifNotExists || tableData.getIfNotExists()
|
|
27
36
|
let sql = ""
|
|
@@ -65,7 +74,13 @@ export default class VelociousDatabaseQueryCreateTableBase extends QueryBase {
|
|
|
65
74
|
index.getColumns().forEach((column, columnIndex) => {
|
|
66
75
|
if (columnIndex > 0) sql += ", "
|
|
67
76
|
|
|
68
|
-
|
|
77
|
+
if (column instanceof TableColumn) {
|
|
78
|
+
sql += driver.quoteColumn(column.getName())
|
|
79
|
+
} else if (typeof column == "string") {
|
|
80
|
+
sql += driver.quoteColumn(column)
|
|
81
|
+
} else {
|
|
82
|
+
throw new Error(`Unknown column type: ${typeof column}`)
|
|
83
|
+
}
|
|
69
84
|
})
|
|
70
85
|
|
|
71
86
|
sql += ")"
|
|
@@ -83,7 +98,7 @@ export default class VelociousDatabaseQueryCreateTableBase extends QueryBase {
|
|
|
83
98
|
|
|
84
99
|
sql += ","
|
|
85
100
|
|
|
86
|
-
const {unique, ...restIndexArgs} = column.
|
|
101
|
+
const {unique, ...restIndexArgs} = column.getIndexArgs()
|
|
87
102
|
|
|
88
103
|
restArgsError(restIndexArgs)
|
|
89
104
|
|
|
@@ -113,16 +128,18 @@ export default class VelociousDatabaseQueryCreateTableBase extends QueryBase {
|
|
|
113
128
|
tableName: tableData.getName(),
|
|
114
129
|
unique: index.getUnique()
|
|
115
130
|
}
|
|
116
|
-
const
|
|
131
|
+
const createIndexSQLs = new CreateIndexBase(createIndexArgs).toSqls()
|
|
117
132
|
|
|
118
|
-
|
|
133
|
+
for (const createIndexSQL of createIndexSQLs) {
|
|
134
|
+
sqls.push(createIndexSQL)
|
|
135
|
+
}
|
|
119
136
|
}
|
|
120
137
|
|
|
121
138
|
// Create indexes for all columns with the index argument
|
|
122
139
|
for (const column of tableData.getColumns()) {
|
|
123
140
|
if (!column.getIndex()) continue
|
|
124
141
|
|
|
125
|
-
const {unique, ...restIndexArgs} = column.
|
|
142
|
+
const {unique, ...restIndexArgs} = column.getIndexArgs()
|
|
126
143
|
|
|
127
144
|
restArgsError(restIndexArgs)
|
|
128
145
|
|
|
@@ -139,9 +156,11 @@ export default class VelociousDatabaseQueryCreateTableBase extends QueryBase {
|
|
|
139
156
|
tableName: tableData.getName(),
|
|
140
157
|
unique
|
|
141
158
|
}
|
|
142
|
-
const
|
|
159
|
+
const createIndexSQLs = new CreateIndexBase(createIndexArgs).toSqls()
|
|
143
160
|
|
|
144
|
-
|
|
161
|
+
for (const createIndexSQL of createIndexSQLs) {
|
|
162
|
+
sqls.push(createIndexSQL)
|
|
163
|
+
}
|
|
145
164
|
}
|
|
146
165
|
}
|
|
147
166
|
|
|
@@ -1,8 +1,25 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import Query from "./index.js"
|
|
4
|
+
|
|
1
5
|
export default class VelociousDatabaseQueryFromBase {
|
|
6
|
+
/** @type {Query | null} */
|
|
7
|
+
query = null
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {import("./index.js").default} query
|
|
11
|
+
* @returns {void}
|
|
12
|
+
*/
|
|
13
|
+
setQuery(query) {
|
|
14
|
+
this.query = query
|
|
15
|
+
}
|
|
16
|
+
|
|
2
17
|
/**
|
|
3
18
|
* @returns {import("../query-parser/options.js").default}
|
|
4
19
|
*/
|
|
5
20
|
getOptions() {
|
|
21
|
+
if (!this.query) throw new Error("'query' hasn't been set")
|
|
22
|
+
|
|
6
23
|
return this.query.getOptions()
|
|
7
24
|
}
|
|
8
25
|
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import FromBase from "./from-base.js"
|
|
2
4
|
|
|
3
5
|
export default class VelociousDatabaseQueryFromPlain extends FromBase {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
+
/**
|
|
7
|
+
* @param {string} plain
|
|
8
|
+
*/
|
|
9
|
+
constructor(plain) {
|
|
10
|
+
super()
|
|
6
11
|
this.plain = plain
|
|
7
12
|
}
|
|
8
13
|
|
|
9
|
-
toSql() { return this.plain }
|
|
14
|
+
toSql() { return [this.plain] }
|
|
10
15
|
}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import FromBase from "./from-base.js"
|
|
2
4
|
|
|
3
5
|
export default class VelociousDatabaseQueryFromTable extends FromBase {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
+
/**
|
|
7
|
+
* @param {string} tableName
|
|
8
|
+
*/
|
|
9
|
+
constructor(tableName) {
|
|
10
|
+
super()
|
|
6
11
|
this.tableName = tableName
|
|
7
12
|
}
|
|
8
13
|
|
|
9
14
|
toSql() {
|
|
10
|
-
return this.getOptions().quoteTableName(this.tableName)
|
|
15
|
+
return [this.getOptions().quoteTableName(this.tableName)]
|
|
11
16
|
}
|
|
12
17
|
}
|
|
@@ -1,18 +1,23 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import FromPlain from "./from-plain.js"
|
|
2
4
|
import {incorporate} from "incorporator"
|
|
3
5
|
import * as inflection from "inflection"
|
|
6
|
+
import {isPlainObject} from "is-plain-object"
|
|
7
|
+
import JoinObject from "./join-object.js"
|
|
4
8
|
import JoinPlain from "./join-plain.js"
|
|
5
9
|
import {Logger} from "../../logger.js"
|
|
6
10
|
import OrderPlain from "./order-plain.js"
|
|
7
11
|
import Preloader from "./preloader.js"
|
|
8
12
|
import RecordNotFoundError from "../record/record-not-found-error.js"
|
|
13
|
+
import SelectBase from "./select-base.js"
|
|
9
14
|
import SelectPlain from "./select-plain.js"
|
|
10
15
|
import WhereHash from "./where-hash.js"
|
|
11
16
|
import WherePlain from "./where-plain.js"
|
|
12
17
|
import restArgsError from "../../utils/rest-args-error.js"
|
|
13
18
|
|
|
14
19
|
/**
|
|
15
|
-
* @typedef {
|
|
20
|
+
* @typedef {{[key: string]: boolean | NestedPreloadRecord }} NestedPreloadRecord
|
|
16
21
|
*/
|
|
17
22
|
|
|
18
23
|
/**
|
|
@@ -27,11 +32,11 @@ export default class VelociousDatabaseQuery {
|
|
|
27
32
|
* @param {Array<import("./join-base.js").default>} [args.joins]
|
|
28
33
|
* @param {import("../handler.js").default} args.handler
|
|
29
34
|
* @param {number | null} [args.limit]
|
|
30
|
-
* @param {typeof import("../record/index.js").default} args.modelClass
|
|
35
|
+
* @param {typeof import("../record/index.js").default} [args.modelClass]
|
|
31
36
|
* @param {number | null} [args.offset]
|
|
32
37
|
* @param {Array<import("./order-base.js").default>} [args.orders]
|
|
33
38
|
* @param {number | null} [args.page]
|
|
34
|
-
* @param {number} args.perPage
|
|
39
|
+
* @param {number} [args.perPage]
|
|
35
40
|
* @param {NestedPreloadRecord} [args.preload]
|
|
36
41
|
* @param {Array<import("./select-base.js").default>} [args.selects]
|
|
37
42
|
* @param {Array<import("./where-base.js").default>} [args.wheres]
|
|
@@ -73,6 +78,8 @@ export default class VelociousDatabaseQuery {
|
|
|
73
78
|
this._perPage = perPage
|
|
74
79
|
this._preload = preload
|
|
75
80
|
this._selects = selects
|
|
81
|
+
|
|
82
|
+
/** @type {import("./where-base.js").default[]} */
|
|
76
83
|
this._wheres = wheres
|
|
77
84
|
}
|
|
78
85
|
|
|
@@ -118,7 +125,7 @@ export default class VelociousDatabaseQuery {
|
|
|
118
125
|
countQuery._selects = []
|
|
119
126
|
countQuery.select(sql)
|
|
120
127
|
|
|
121
|
-
const results = await countQuery._executeQuery()
|
|
128
|
+
const results = /** @type {{ count: number }[]} */ (await countQuery._executeQuery())
|
|
122
129
|
|
|
123
130
|
|
|
124
131
|
// The query isn't grouped and a single result has been given
|
|
@@ -142,8 +149,7 @@ export default class VelociousDatabaseQuery {
|
|
|
142
149
|
}
|
|
143
150
|
|
|
144
151
|
/**
|
|
145
|
-
* @
|
|
146
|
-
* @returns {T[]}
|
|
152
|
+
* @returns {import("./from-base.js").default[]}
|
|
147
153
|
*/
|
|
148
154
|
getFroms() {
|
|
149
155
|
return this._froms
|
|
@@ -182,6 +188,7 @@ export default class VelociousDatabaseQuery {
|
|
|
182
188
|
* @returns {Promise<import("../record/index.js").default>}
|
|
183
189
|
*/
|
|
184
190
|
async find(recordId) {
|
|
191
|
+
/** @type {{[key: string]: number | string}} */
|
|
185
192
|
const conditions = {}
|
|
186
193
|
|
|
187
194
|
conditions[this.modelClass.primaryKey()] = recordId
|
|
@@ -197,10 +204,11 @@ export default class VelociousDatabaseQuery {
|
|
|
197
204
|
}
|
|
198
205
|
|
|
199
206
|
/**
|
|
200
|
-
* @param {
|
|
207
|
+
* @param {{[key: string]: any}} conditions
|
|
201
208
|
* @returns {Promise<import("../record/index.js").default|null>}
|
|
202
209
|
*/
|
|
203
210
|
async findBy(conditions) {
|
|
211
|
+
/** @type {{[key: string]: number | string}} */
|
|
204
212
|
const newConditions = {}
|
|
205
213
|
|
|
206
214
|
for (const key in conditions) {
|
|
@@ -213,11 +221,12 @@ export default class VelociousDatabaseQuery {
|
|
|
213
221
|
}
|
|
214
222
|
|
|
215
223
|
/**
|
|
216
|
-
* @param {
|
|
224
|
+
* @param {{[key: string]: any}} conditions
|
|
225
|
+
* @param {function() : void} callback
|
|
217
226
|
* @returns {Promise<import("../record/index.js").default>}
|
|
218
227
|
*/
|
|
219
|
-
async findOrCreateBy(
|
|
220
|
-
const record = await this.findOrInitializeBy(
|
|
228
|
+
async findOrCreateBy(conditions, callback) {
|
|
229
|
+
const record = await this.findOrInitializeBy(conditions, callback)
|
|
221
230
|
|
|
222
231
|
if (record.isNewRecord()) {
|
|
223
232
|
await record.save()
|
|
@@ -227,10 +236,11 @@ export default class VelociousDatabaseQuery {
|
|
|
227
236
|
}
|
|
228
237
|
|
|
229
238
|
/**
|
|
230
|
-
* @param {
|
|
239
|
+
* @param {{[key: string]: any}} conditions
|
|
231
240
|
* @returns {Promise<import("../record/index.js").default>}
|
|
232
241
|
*/
|
|
233
242
|
async findByOrFail(conditions) {
|
|
243
|
+
/** @type {{[key: string]: number | string}} */
|
|
234
244
|
const newConditions = {}
|
|
235
245
|
|
|
236
246
|
for (const key in conditions) {
|
|
@@ -250,7 +260,7 @@ export default class VelociousDatabaseQuery {
|
|
|
250
260
|
|
|
251
261
|
/**
|
|
252
262
|
* @param {object} conditions
|
|
253
|
-
* @param {function() : void} callback
|
|
263
|
+
* @param {function(import("../record/index.js").default) : void} callback
|
|
254
264
|
* @returns {Promise<import("../record/index.js").default>}
|
|
255
265
|
*/
|
|
256
266
|
async findOrInitializeBy(conditions, callback) {
|
|
@@ -282,9 +292,7 @@ export default class VelociousDatabaseQuery {
|
|
|
282
292
|
* @returns {this}
|
|
283
293
|
*/
|
|
284
294
|
from(from) {
|
|
285
|
-
if (typeof from == "string") from = new FromPlain(
|
|
286
|
-
|
|
287
|
-
from.query = this
|
|
295
|
+
if (typeof from == "string") from = new FromPlain(from)
|
|
288
296
|
|
|
289
297
|
this._froms.push(from)
|
|
290
298
|
return this
|
|
@@ -300,19 +308,18 @@ export default class VelociousDatabaseQuery {
|
|
|
300
308
|
}
|
|
301
309
|
|
|
302
310
|
/**
|
|
303
|
-
* @param {string|
|
|
311
|
+
* @param {string|{[key: string]: any}} join
|
|
304
312
|
* @returns {this}
|
|
305
313
|
*/
|
|
306
314
|
joins(join) {
|
|
307
315
|
if (typeof join == "string") {
|
|
308
|
-
|
|
309
|
-
} else if (
|
|
310
|
-
|
|
316
|
+
this._joins.push(new JoinPlain(join))
|
|
317
|
+
} else if (isPlainObject(join)) {
|
|
318
|
+
this._joins.push(new JoinObject(join))
|
|
311
319
|
} else {
|
|
312
320
|
throw new Error(`Unknown type of join: ${typeof join}`)
|
|
313
321
|
}
|
|
314
322
|
|
|
315
|
-
this._joins.push(join)
|
|
316
323
|
return this
|
|
317
324
|
}
|
|
318
325
|
|
|
@@ -350,11 +357,14 @@ export default class VelociousDatabaseQuery {
|
|
|
350
357
|
* @returns {this}
|
|
351
358
|
*/
|
|
352
359
|
order(order) {
|
|
353
|
-
if (typeof order == "
|
|
354
|
-
|
|
355
|
-
order
|
|
360
|
+
if (typeof order == "string") {
|
|
361
|
+
this._orders.push(new OrderPlain(this, order))
|
|
362
|
+
} else if (typeof order == "number") {
|
|
363
|
+
this._orders.push(new OrderPlain(this, `${order}`))
|
|
364
|
+
} else {
|
|
365
|
+
throw new Error(`Unknown order type: ${typeof order}`)
|
|
366
|
+
}
|
|
356
367
|
|
|
357
|
-
this._orders.push(order)
|
|
358
368
|
return this
|
|
359
369
|
}
|
|
360
370
|
|
|
@@ -425,11 +435,14 @@ export default class VelociousDatabaseQuery {
|
|
|
425
435
|
return this
|
|
426
436
|
}
|
|
427
437
|
|
|
428
|
-
if (typeof select == "string")
|
|
429
|
-
|
|
430
|
-
select
|
|
438
|
+
if (typeof select == "string") {
|
|
439
|
+
this._selects.push(new SelectPlain(select))
|
|
440
|
+
} else if (select instanceof SelectBase) {
|
|
441
|
+
this._selects.push(select)
|
|
442
|
+
} else {
|
|
443
|
+
throw new Error(`Invalid select type: ${typeof select}`)
|
|
444
|
+
}
|
|
431
445
|
|
|
432
|
-
this._selects.push(select)
|
|
433
446
|
return this
|
|
434
447
|
}
|
|
435
448
|
|
|
@@ -492,15 +505,13 @@ export default class VelociousDatabaseQuery {
|
|
|
492
505
|
*/
|
|
493
506
|
where(where) {
|
|
494
507
|
if (typeof where == "string") {
|
|
495
|
-
|
|
508
|
+
this._wheres.push(new WherePlain(this, where))
|
|
496
509
|
} else if (typeof where == "object" && (where.constructor.name == "object" || where.constructor.name == "Object")) {
|
|
497
|
-
|
|
510
|
+
this._wheres.push(new WhereHash(this, where))
|
|
498
511
|
} else {
|
|
499
512
|
throw new Error(`Invalid type of where: ${typeof where} (${where.constructor.name})`)
|
|
500
513
|
}
|
|
501
514
|
|
|
502
|
-
this._wheres.push(where)
|
|
503
|
-
|
|
504
515
|
return this
|
|
505
516
|
}
|
|
506
517
|
}
|
|
@@ -1,9 +1,36 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
export default class VelociousDatabaseQueryJoinBase {
|
|
4
|
+
pretty = false
|
|
5
|
+
|
|
2
6
|
/**
|
|
3
7
|
* @returns {import("../query-parser/options.js").default}
|
|
4
8
|
*/
|
|
5
9
|
getOptions() {
|
|
6
|
-
return this.
|
|
10
|
+
return this.getQuery().driver.options()
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @returns {import("./index.js").default}
|
|
15
|
+
*/
|
|
16
|
+
getQuery() {
|
|
17
|
+
if (!this.query) throw new Error("'query' hasn't been set")
|
|
18
|
+
|
|
19
|
+
return this.query
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param {boolean} value
|
|
24
|
+
*/
|
|
25
|
+
setPretty(value) {
|
|
26
|
+
this.pretty = value
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @param {import("./index.js").default} query
|
|
31
|
+
*/
|
|
32
|
+
setQuery(query) {
|
|
33
|
+
this.query = query
|
|
7
34
|
}
|
|
8
35
|
|
|
9
36
|
toSql() {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import JoinBase from "./join-base.js"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {{[key: string]: boolean | JoinObject}} JoinObject
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export default class VelociousDatabaseQueryJoinObject extends JoinBase {
|
|
10
|
+
/**
|
|
11
|
+
* @param {JoinObject} object
|
|
12
|
+
*/
|
|
13
|
+
constructor(object) {
|
|
14
|
+
super()
|
|
15
|
+
this.object = object
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
toSql() {
|
|
19
|
+
const modelClass = this.getQuery().modelClass
|
|
20
|
+
|
|
21
|
+
return this.joinObject(this.object, modelClass, "", 0)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {JoinObject} join
|
|
26
|
+
* @param {typeof import("../record/index.js").default} modelClass
|
|
27
|
+
* @param {string} sql
|
|
28
|
+
* @param {number} joinsCount
|
|
29
|
+
* @returns {string}
|
|
30
|
+
*/
|
|
31
|
+
joinObject(join, modelClass, sql, joinsCount) {
|
|
32
|
+
const pretty = this.pretty
|
|
33
|
+
const conn = this.getQuery().driver
|
|
34
|
+
|
|
35
|
+
for (const joinKey in join) {
|
|
36
|
+
const joinValue = join[joinKey]
|
|
37
|
+
const relationship = modelClass.getRelationshipByName(joinKey)
|
|
38
|
+
const targetModelClass = relationship.getTargetModelClass()
|
|
39
|
+
|
|
40
|
+
if (joinsCount > 0) {
|
|
41
|
+
if (pretty) {
|
|
42
|
+
sql += "\n\n"
|
|
43
|
+
} else {
|
|
44
|
+
sql += " "
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
sql += `LEFT JOIN ${conn.quoteTable(targetModelClass.tableName())} ON `
|
|
49
|
+
|
|
50
|
+
if (relationship.getType() == "belongsTo") {
|
|
51
|
+
sql += `${conn.quoteTable(targetModelClass.tableName())}.${conn.quoteColumn(relationship.getPrimaryKey())} = `
|
|
52
|
+
sql += `${conn.quoteTable(modelClass.tableName())}.${conn.quoteColumn(relationship.getForeignKey())}`
|
|
53
|
+
} else if (relationship.getType() == "hasMany" || relationship.getType() == "hasOne") {
|
|
54
|
+
sql += `${conn.quoteTable(targetModelClass.tableName())}.${conn.quoteColumn(relationship.getForeignKey())} = `
|
|
55
|
+
sql += `${conn.quoteTable(modelClass.tableName())}.${conn.quoteColumn(relationship.getPrimaryKey())}`
|
|
56
|
+
} else {
|
|
57
|
+
throw new Error(`Unknown relationship type: ${relationship.getType()}`)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (typeof joinValue == "object") {
|
|
61
|
+
sql = this.joinObject(joinValue, targetModelClass, sql, joinsCount + 1)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return sql
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
export default class VelociousDatabaseQueryOrderBase {
|
|
4
|
+
/**
|
|
5
|
+
* @param {import("./index.js").default} query
|
|
6
|
+
*/
|
|
7
|
+
constructor(query) {
|
|
8
|
+
this.query = query
|
|
9
|
+
}
|
|
10
|
+
|
|
2
11
|
/**
|
|
3
12
|
* @returns {import("../query-parser/options.js").default}
|
|
4
13
|
*/
|
|
@@ -6,6 +15,15 @@ export default class VelociousDatabaseQueryOrderBase {
|
|
|
6
15
|
return this.query.driver.options()
|
|
7
16
|
}
|
|
8
17
|
|
|
18
|
+
/**
|
|
19
|
+
* @interface
|
|
20
|
+
* @param {boolean} _reverseOrder
|
|
21
|
+
* @returns {void}
|
|
22
|
+
*/
|
|
23
|
+
setReverseOrder(_reverseOrder) { // eslint-disable-line no-unused-vars
|
|
24
|
+
throw new Error("setReverseOrder not implemented")
|
|
25
|
+
}
|
|
26
|
+
|
|
9
27
|
toSql() {
|
|
10
28
|
throw new Error("'toSql' wasn't implemented")
|
|
11
29
|
}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import OrderBase from "./order-base.js"
|
|
2
4
|
|
|
3
5
|
export default class VelociousDatabaseQueryOrderPlain extends OrderBase {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
+
/**
|
|
7
|
+
* @param {import("./index.js").default} query
|
|
8
|
+
* @param {string} plain
|
|
9
|
+
*/
|
|
10
|
+
constructor(query, plain) {
|
|
11
|
+
super(query)
|
|
6
12
|
this.plain = plain
|
|
7
13
|
this.reverseOrder = false
|
|
8
14
|
}
|
|
@@ -1,11 +1,26 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
export default class VelociousDatabaseQuerySelectBase {
|
|
2
4
|
/**
|
|
3
5
|
* @returns {import("../query-parser/options.js").default}
|
|
4
6
|
*/
|
|
5
7
|
getOptions() {
|
|
8
|
+
if (!this.query) throw new Error("'query' hasn't been set")
|
|
9
|
+
|
|
6
10
|
return this.query.driver.options()
|
|
7
11
|
}
|
|
8
12
|
|
|
13
|
+
/**
|
|
14
|
+
* @param {import("./index.js").default} query
|
|
15
|
+
*/
|
|
16
|
+
setQuery(query) {
|
|
17
|
+
this.query = query
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @interface
|
|
22
|
+
* @returns {string}
|
|
23
|
+
*/
|
|
9
24
|
toSql() {
|
|
10
25
|
throw new Error("'toSql' wasn't implemented")
|
|
11
26
|
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import SelectBase from "./select-base.js"
|
|
2
4
|
|
|
3
5
|
export default class VelociousDatabaseQuerySelectPlain extends SelectBase {
|
|
4
|
-
|
|
6
|
+
/**
|
|
7
|
+
* @param {string} plain
|
|
8
|
+
*/
|
|
9
|
+
constructor(plain) {
|
|
5
10
|
super()
|
|
6
11
|
this.plain = plain
|
|
7
12
|
}
|