knex 0.20.6 → 0.20.10
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/CHANGELOG.md +62 -0
- package/README.md +1 -1
- package/bin/cli.js +37 -39
- package/bin/utils/cli-config-utils.js +1 -31
- package/lib/client.js +10 -5
- package/lib/dialects/mssql/query/compiler.js +19 -22
- package/lib/dialects/mysql/index.js +11 -21
- package/lib/dialects/mysql/query/compiler.js +19 -23
- package/lib/dialects/oracle/query/compiler.js +19 -23
- package/lib/dialects/oracledb/index.js +26 -15
- package/lib/dialects/oracledb/query/compiler.js +36 -38
- package/lib/dialects/oracledb/transaction.js +25 -21
- package/lib/dialects/postgres/query/compiler.js +20 -23
- package/lib/dialects/redshift/query/compiler.js +13 -16
- package/lib/dialects/sqlite3/query/compiler.js +24 -27
- package/lib/knex.js +4 -0
- package/lib/query/compiler.js +89 -92
- package/lib/query/string.js +1 -1
- package/lib/runner.js +11 -3
- package/lib/schema/compiler.js +19 -0
- package/lib/transaction.js +17 -9
- package/lib/util/parse-connection.js +3 -1
- package/lib/util/timeout.js +20 -0
- package/package.json +34 -29
- package/types/index.d.ts +12 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,67 @@
|
|
|
1
1
|
# Master (Unreleased)
|
|
2
2
|
|
|
3
|
+
# 0.20.10 - 13 February, 2020
|
|
4
|
+
|
|
5
|
+
### Bug fixes:
|
|
6
|
+
|
|
7
|
+
- Oracle: commit was a no-op causing race conditions #3668
|
|
8
|
+
- CLI: Knex calls process.chdir() before opening Knexfile #3661
|
|
9
|
+
- Fixed unresolved promise in cancelQuery() #3666
|
|
10
|
+
|
|
11
|
+
### Typings:
|
|
12
|
+
|
|
13
|
+
- `fn.now` takes optionally a precision argument. #3662
|
|
14
|
+
- PG: Include SSL in connection definition #3659
|
|
15
|
+
|
|
16
|
+
### Test / internal changes:
|
|
17
|
+
|
|
18
|
+
- replace Bluebird.timeout #3634
|
|
19
|
+
|
|
20
|
+
# 0.20.9 - 08 February, 2020
|
|
21
|
+
|
|
22
|
+
### Bug fixes:
|
|
23
|
+
|
|
24
|
+
- CLI: Improve Support for Liftoff's Preloaders - this should fix some cases like using TS for your migrations #3613
|
|
25
|
+
|
|
26
|
+
### Typings:
|
|
27
|
+
|
|
28
|
+
- MSSQL: Add `enableArithAbort` to `MsSqlConnectionConfig`
|
|
29
|
+
|
|
30
|
+
### Test / internal changes:
|
|
31
|
+
|
|
32
|
+
- Refactor more tests to use cli-testlab #3640
|
|
33
|
+
- Update QueryCompiler implementation to use classes #3647
|
|
34
|
+
|
|
35
|
+
# 0.20.8 - 14 January, 2020
|
|
36
|
+
|
|
37
|
+
### New features:
|
|
38
|
+
|
|
39
|
+
- CLI: Support ES6 modules via flag --esm #3616
|
|
40
|
+
|
|
41
|
+
### Bug fixes:
|
|
42
|
+
|
|
43
|
+
- CLI: Print help only when there are no arguments #3617
|
|
44
|
+
|
|
45
|
+
### Typings:
|
|
46
|
+
|
|
47
|
+
- Fix incorrect type of QueryBuilder.first('*') result #3621
|
|
48
|
+
|
|
49
|
+
# 0.20.7 - 07 January, 2020
|
|
50
|
+
|
|
51
|
+
### New features:
|
|
52
|
+
|
|
53
|
+
- Throw better error when trying to modify schema while using unsupported dialect #3609
|
|
54
|
+
|
|
55
|
+
### Bug fixes:
|
|
56
|
+
|
|
57
|
+
- Oracle: dispose connection on connection error #3611
|
|
58
|
+
- Oracle: fix not releasing connection from pool on disconnect #3605
|
|
59
|
+
- CLI: prevent warning with root command #3604
|
|
60
|
+
|
|
61
|
+
### Typings:
|
|
62
|
+
|
|
63
|
+
- Add create/drop schema methods to SchemaBuilder #3579
|
|
64
|
+
|
|
3
65
|
# 0.20.6 - 29 December, 2019
|
|
4
66
|
|
|
5
67
|
### Bug fixes:
|
package/README.md
CHANGED
package/bin/cli.js
CHANGED
|
@@ -12,7 +12,6 @@ const { promisify } = require('util');
|
|
|
12
12
|
const cliPkg = require('../package');
|
|
13
13
|
const {
|
|
14
14
|
mkConfigObj,
|
|
15
|
-
resolveKnexFilePath,
|
|
16
15
|
resolveEnvironmentConfig,
|
|
17
16
|
exit,
|
|
18
17
|
success,
|
|
@@ -29,6 +28,17 @@ const fsPromised = {
|
|
|
29
28
|
writeFile: promisify(fs.writeFile),
|
|
30
29
|
};
|
|
31
30
|
|
|
31
|
+
function openKnexfile(configPath) {
|
|
32
|
+
const config = require(configPath);
|
|
33
|
+
|
|
34
|
+
// FYI: By default, the extension for the migration files is inferred
|
|
35
|
+
// from the knexfile's extension. So, the following lines are in
|
|
36
|
+
// place for backwards compatibility purposes.
|
|
37
|
+
config.ext = config.ext || path.extname(configPath).replace('.', '');
|
|
38
|
+
|
|
39
|
+
return config;
|
|
40
|
+
}
|
|
41
|
+
|
|
32
42
|
function initKnex(env, opts) {
|
|
33
43
|
checkLocalModule(env);
|
|
34
44
|
if (process.cwd() !== env.cwd) {
|
|
@@ -39,37 +49,15 @@ function initKnex(env, opts) {
|
|
|
39
49
|
);
|
|
40
50
|
}
|
|
41
51
|
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
? require(configurationPath.path)
|
|
46
|
-
: undefined;
|
|
47
|
-
|
|
48
|
-
env.configuration = configuration || mkConfigObj(opts);
|
|
49
|
-
if (!env.configuration.ext && configurationPath) {
|
|
50
|
-
env.configuration.ext = configurationPath.extension;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
// If knexfile is specified
|
|
54
|
-
else {
|
|
55
|
-
const resolvedKnexfilePath = path.resolve(opts.knexfile);
|
|
56
|
-
const knexfileDir = path.dirname(resolvedKnexfilePath);
|
|
57
|
-
process.chdir(knexfileDir);
|
|
58
|
-
env.configuration = require(resolvedKnexfilePath);
|
|
59
|
-
|
|
60
|
-
if (!env.configuration) {
|
|
61
|
-
exit(
|
|
62
|
-
'Knexfile not found. Specify a path with --knexfile or pass --client and --connection params in commandline'
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (!env.configuration.ext) {
|
|
67
|
-
env.configuration.ext = path
|
|
68
|
-
.extname(resolvedKnexfilePath)
|
|
69
|
-
.replace('.', '');
|
|
70
|
-
}
|
|
52
|
+
if (opts.esm) {
|
|
53
|
+
// enable esm interop via 'esm' module
|
|
54
|
+
require = require('esm')(module);
|
|
71
55
|
}
|
|
72
56
|
|
|
57
|
+
env.configuration = env.configPath
|
|
58
|
+
? openKnexfile(env.configPath)
|
|
59
|
+
: mkConfigObj(opts);
|
|
60
|
+
|
|
73
61
|
const resolvedConfig = resolveEnvironmentConfig(opts, env.configuration);
|
|
74
62
|
const knex = require(env.modulePath);
|
|
75
63
|
return knex(resolvedConfig);
|
|
@@ -110,7 +98,8 @@ function invoke(env) {
|
|
|
110
98
|
.option(
|
|
111
99
|
'--env [name]',
|
|
112
100
|
'environment, default: process.env.NODE_ENV || development'
|
|
113
|
-
)
|
|
101
|
+
)
|
|
102
|
+
.option('--esm', 'Enable ESM interop.');
|
|
114
103
|
|
|
115
104
|
commander
|
|
116
105
|
.command('init')
|
|
@@ -341,12 +330,11 @@ function invoke(env) {
|
|
|
341
330
|
.catch(exit);
|
|
342
331
|
});
|
|
343
332
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
Promise.resolve(pending).then(() => {
|
|
333
|
+
if (!process.argv.slice(2).length) {
|
|
347
334
|
commander.outputHelp();
|
|
348
|
-
|
|
349
|
-
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
commander.parse(process.argv);
|
|
350
338
|
}
|
|
351
339
|
|
|
352
340
|
const cli = new Liftoff({
|
|
@@ -364,11 +352,21 @@ cli.on('requireFail', function(name) {
|
|
|
364
352
|
console.log(color.red('Failed to load external module'), color.magenta(name));
|
|
365
353
|
});
|
|
366
354
|
|
|
355
|
+
// FYI: The handling for the `--cwd` and `--knexfile` arguments is a bit strange,
|
|
356
|
+
// but we decided to retain the behavior for backwards-compatibility. In
|
|
357
|
+
// particular: if `--knexfile` is a relative path, then it will be resolved
|
|
358
|
+
// relative to `--cwd` instead of the shell's CWD.
|
|
359
|
+
//
|
|
360
|
+
// So, the easiest way to replicate this behavior is to have the CLI change
|
|
361
|
+
// its CWD to `--cwd` immediately before initializing everything else. This
|
|
362
|
+
// ensures that Liftoff will then resolve the path to `--knexfile` correctly.
|
|
363
|
+
if (argv.cwd) {
|
|
364
|
+
process.chdir(argv.cwd);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
367
|
cli.launch(
|
|
368
368
|
{
|
|
369
|
-
|
|
370
|
-
knexfile: argv.knexfile,
|
|
371
|
-
knexpath: argv.knexpath,
|
|
369
|
+
configPath: argv.knexfile,
|
|
372
370
|
require: argv.require,
|
|
373
371
|
completion: argv.completion,
|
|
374
372
|
},
|
|
@@ -8,9 +8,8 @@ const argv = require('getopts')(process.argv.slice(2));
|
|
|
8
8
|
|
|
9
9
|
function mkConfigObj(opts) {
|
|
10
10
|
if (!opts.client) {
|
|
11
|
-
const path = resolveDefaultKnexfilePath();
|
|
12
11
|
throw new Error(
|
|
13
|
-
`No
|
|
12
|
+
`No configuration file found and no commandline connection parameters passed`
|
|
14
13
|
);
|
|
15
14
|
}
|
|
16
15
|
|
|
@@ -31,34 +30,6 @@ function mkConfigObj(opts) {
|
|
|
31
30
|
};
|
|
32
31
|
}
|
|
33
32
|
|
|
34
|
-
function resolveKnexFilePath() {
|
|
35
|
-
const jsPath = resolveDefaultKnexfilePath('js');
|
|
36
|
-
if (fs.existsSync(jsPath)) {
|
|
37
|
-
return {
|
|
38
|
-
path: jsPath,
|
|
39
|
-
extension: 'js',
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const tsPath = resolveDefaultKnexfilePath('ts');
|
|
44
|
-
if (fs.existsSync(tsPath)) {
|
|
45
|
-
return {
|
|
46
|
-
path: tsPath,
|
|
47
|
-
extension: 'ts',
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
console.warn(
|
|
52
|
-
`Failed to find configuration at default location of ${resolveDefaultKnexfilePath(
|
|
53
|
-
'js'
|
|
54
|
-
)}`
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function resolveDefaultKnexfilePath(extension) {
|
|
59
|
-
return process.cwd() + `/knexfile.${extension}`;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
33
|
function resolveEnvironmentConfig(opts, allConfigs) {
|
|
63
34
|
const environment = opts.env || process.env.NODE_ENV || 'development';
|
|
64
35
|
const result = allConfigs[environment] || allConfigs;
|
|
@@ -156,7 +127,6 @@ function getStubPath(configKey, env, opts) {
|
|
|
156
127
|
|
|
157
128
|
module.exports = {
|
|
158
129
|
mkConfigObj,
|
|
159
|
-
resolveKnexFilePath,
|
|
160
130
|
resolveEnvironmentConfig,
|
|
161
131
|
exit,
|
|
162
132
|
success,
|
package/lib/client.js
CHANGED
|
@@ -25,6 +25,7 @@ const { makeEscape } = require('./query/string');
|
|
|
25
25
|
const { uniqueId, cloneDeep, defaults } = require('lodash');
|
|
26
26
|
|
|
27
27
|
const Logger = require('./logger');
|
|
28
|
+
const { KnexTimeoutError } = require('./util/timeout');
|
|
28
29
|
|
|
29
30
|
const debug = require('debug')('knex:client');
|
|
30
31
|
const _debugQuery = require('debug')('knex:query');
|
|
@@ -344,11 +345,15 @@ Object.assign(Client.prototype, {
|
|
|
344
345
|
debug('acquired connection from pool: %s', connection.__knexUid);
|
|
345
346
|
return connection;
|
|
346
347
|
})
|
|
347
|
-
.catch(
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
348
|
+
.catch((error) => {
|
|
349
|
+
let convertedError = error;
|
|
350
|
+
if (error instanceof TimeoutError) {
|
|
351
|
+
convertedError = new KnexTimeoutError(
|
|
352
|
+
'Knex: Timeout acquiring a connection. The pool is probably full. ' +
|
|
353
|
+
'Are you missing a .transacting(trx) call?'
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
throw convertedError;
|
|
352
357
|
});
|
|
353
358
|
} catch (e) {
|
|
354
359
|
return Bluebird.reject(e);
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
// MSSQL Query Compiler
|
|
2
2
|
// ------
|
|
3
|
-
const inherits = require('inherits');
|
|
4
3
|
const QueryCompiler = require('../../../query/compiler');
|
|
5
4
|
|
|
6
5
|
const { isEmpty, compact, identity } = require('lodash');
|
|
7
6
|
|
|
8
|
-
function QueryCompiler_MSSQL(client, builder) {
|
|
9
|
-
QueryCompiler.call(this, client, builder);
|
|
10
|
-
}
|
|
11
|
-
inherits(QueryCompiler_MSSQL, QueryCompiler);
|
|
12
|
-
|
|
13
7
|
const components = [
|
|
14
8
|
'columns',
|
|
15
9
|
'join',
|
|
@@ -23,14 +17,17 @@ const components = [
|
|
|
23
17
|
'offset',
|
|
24
18
|
];
|
|
25
19
|
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
class QueryCompiler_MSSQL extends QueryCompiler {
|
|
21
|
+
constructor(client, builder) {
|
|
22
|
+
super(client, builder);
|
|
23
|
+
this._emptyInsertValue = 'default values';
|
|
24
|
+
}
|
|
28
25
|
|
|
29
26
|
select() {
|
|
30
27
|
const sql = this.with();
|
|
31
28
|
const statements = components.map((component) => this[component](this));
|
|
32
29
|
return sql + compact(statements).join(' ');
|
|
33
|
-
}
|
|
30
|
+
}
|
|
34
31
|
|
|
35
32
|
// Compiles an "insert" query, allowing for multiple
|
|
36
33
|
// inserts using a single query statement.
|
|
@@ -79,7 +76,7 @@ Object.assign(QueryCompiler_MSSQL.prototype, {
|
|
|
79
76
|
sql,
|
|
80
77
|
returning,
|
|
81
78
|
};
|
|
82
|
-
}
|
|
79
|
+
}
|
|
83
80
|
|
|
84
81
|
// Compiles an `update` query, allowing for a return value.
|
|
85
82
|
update() {
|
|
@@ -103,7 +100,7 @@ Object.assign(QueryCompiler_MSSQL.prototype, {
|
|
|
103
100
|
(!returning ? this._returning('rowcount', '@@rowcount') : ''),
|
|
104
101
|
returning: returning || '@@rowcount',
|
|
105
102
|
};
|
|
106
|
-
}
|
|
103
|
+
}
|
|
107
104
|
|
|
108
105
|
// Compiles a `delete` query.
|
|
109
106
|
del() {
|
|
@@ -121,7 +118,7 @@ Object.assign(QueryCompiler_MSSQL.prototype, {
|
|
|
121
118
|
(!returning ? this._returning('rowcount', '@@rowcount') : ''),
|
|
122
119
|
returning: returning || '@@rowcount',
|
|
123
120
|
};
|
|
124
|
-
}
|
|
121
|
+
}
|
|
125
122
|
|
|
126
123
|
// Compiles the columns in the query, specifying if an item was distinct.
|
|
127
124
|
columns() {
|
|
@@ -156,7 +153,7 @@ Object.assign(QueryCompiler_MSSQL.prototype, {
|
|
|
156
153
|
sql.join(', ') +
|
|
157
154
|
(this.tableName ? ` from ${this.tableName}` : '')
|
|
158
155
|
);
|
|
159
|
-
}
|
|
156
|
+
}
|
|
160
157
|
|
|
161
158
|
_returning(method, value) {
|
|
162
159
|
switch (method) {
|
|
@@ -172,23 +169,23 @@ Object.assign(QueryCompiler_MSSQL.prototype, {
|
|
|
172
169
|
case 'rowcount':
|
|
173
170
|
return value ? ';select @@rowcount' : '';
|
|
174
171
|
}
|
|
175
|
-
}
|
|
172
|
+
}
|
|
176
173
|
|
|
177
174
|
// Compiles a `truncate` query.
|
|
178
175
|
truncate() {
|
|
179
176
|
return `truncate table ${this.tableName}`;
|
|
180
|
-
}
|
|
177
|
+
}
|
|
181
178
|
|
|
182
179
|
forUpdate() {
|
|
183
180
|
// this doesn't work exacltly as it should, one should also mention index while locking
|
|
184
181
|
// https://stackoverflow.com/a/9818448/360060
|
|
185
182
|
return 'with (UPDLOCK)';
|
|
186
|
-
}
|
|
183
|
+
}
|
|
187
184
|
|
|
188
185
|
forShare() {
|
|
189
186
|
// http://www.sqlteam.com/article/introduction-to-locking-in-sql-server
|
|
190
187
|
return 'with (HOLDLOCK)';
|
|
191
|
-
}
|
|
188
|
+
}
|
|
192
189
|
|
|
193
190
|
// Compiles a `columnInfo` query.
|
|
194
191
|
columnInfo() {
|
|
@@ -230,18 +227,18 @@ Object.assign(QueryCompiler_MSSQL.prototype, {
|
|
|
230
227
|
return (column && out[column]) || out;
|
|
231
228
|
},
|
|
232
229
|
};
|
|
233
|
-
}
|
|
230
|
+
}
|
|
234
231
|
|
|
235
232
|
top() {
|
|
236
233
|
const noLimit = !this.single.limit && this.single.limit !== 0;
|
|
237
234
|
const noOffset = !this.single.offset;
|
|
238
235
|
if (noLimit || !noOffset) return '';
|
|
239
236
|
return `top (${this.formatter.parameter(this.single.limit)})`;
|
|
240
|
-
}
|
|
237
|
+
}
|
|
241
238
|
|
|
242
239
|
limit() {
|
|
243
240
|
return '';
|
|
244
|
-
}
|
|
241
|
+
}
|
|
245
242
|
|
|
246
243
|
offset() {
|
|
247
244
|
const noLimit = !this.single.limit && this.single.limit !== 0;
|
|
@@ -256,8 +253,8 @@ Object.assign(QueryCompiler_MSSQL.prototype, {
|
|
|
256
253
|
)} rows only`;
|
|
257
254
|
}
|
|
258
255
|
return offset;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
261
258
|
|
|
262
259
|
// Set the QueryBuilder & QueryCompiler on the client object,
|
|
263
260
|
// in case anyone wants to modify things to suit their own purposes.
|
|
@@ -170,28 +170,18 @@ Object.assign(Client_MySQL.prototype, {
|
|
|
170
170
|
|
|
171
171
|
canCancelQuery: true,
|
|
172
172
|
|
|
173
|
-
cancelQuery(connectionToKill) {
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
.timeout(100)
|
|
182
|
-
.then((conn) =>
|
|
183
|
-
this.query(conn, {
|
|
184
|
-
method: 'raw',
|
|
185
|
-
sql: 'KILL QUERY ?',
|
|
186
|
-
bindings: [connectionToKill.threadId],
|
|
187
|
-
options: {},
|
|
188
|
-
})
|
|
189
|
-
)
|
|
190
|
-
.finally(() => {
|
|
191
|
-
// NOT returning this promise because we want to release the connection
|
|
192
|
-
// in a non-blocking fashion
|
|
193
|
-
acquiringConn.then((conn) => this.releaseConnection(conn));
|
|
173
|
+
async cancelQuery(connectionToKill) {
|
|
174
|
+
const conn = await this.acquireConnection();
|
|
175
|
+
try {
|
|
176
|
+
return await this.query(conn, {
|
|
177
|
+
method: 'raw',
|
|
178
|
+
sql: 'KILL QUERY ?',
|
|
179
|
+
bindings: [connectionToKill.threadId],
|
|
180
|
+
options: {},
|
|
194
181
|
});
|
|
182
|
+
} finally {
|
|
183
|
+
await this.releaseConnection(conn);
|
|
184
|
+
}
|
|
195
185
|
},
|
|
196
186
|
});
|
|
197
187
|
|
|
@@ -1,26 +1,22 @@
|
|
|
1
1
|
// MySQL Query Compiler
|
|
2
2
|
// ------
|
|
3
|
-
const inherits = require('inherits');
|
|
4
3
|
const QueryCompiler = require('../../../query/compiler');
|
|
5
4
|
|
|
6
5
|
const { identity } = require('lodash');
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
class QueryCompiler_MySQL extends QueryCompiler {
|
|
8
|
+
constructor(client, builder) {
|
|
9
|
+
super(client, builder);
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
const { returning } = this.single;
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
if (returning) {
|
|
14
|
+
this.client.logger.warn(
|
|
15
|
+
'.returning() is not supported by mysql and will not have any effect.'
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
this._emptyInsertValue = '() values ()';
|
|
17
19
|
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
inherits(QueryCompiler_MySQL, QueryCompiler);
|
|
21
|
-
|
|
22
|
-
Object.assign(QueryCompiler_MySQL.prototype, {
|
|
23
|
-
_emptyInsertValue: '() values ()',
|
|
24
20
|
|
|
25
21
|
// Update method, including joins, wheres, order & limits.
|
|
26
22
|
update() {
|
|
@@ -38,25 +34,25 @@ Object.assign(QueryCompiler_MySQL.prototype, {
|
|
|
38
34
|
(order ? ` ${order}` : '') +
|
|
39
35
|
(limit ? ` ${limit}` : '')
|
|
40
36
|
);
|
|
41
|
-
}
|
|
37
|
+
}
|
|
42
38
|
|
|
43
39
|
forUpdate() {
|
|
44
40
|
return 'for update';
|
|
45
|
-
}
|
|
41
|
+
}
|
|
46
42
|
|
|
47
43
|
forShare() {
|
|
48
44
|
return 'lock in share mode';
|
|
49
|
-
}
|
|
45
|
+
}
|
|
50
46
|
|
|
51
47
|
// Only supported on MySQL 8.0+
|
|
52
48
|
skipLocked() {
|
|
53
49
|
return 'skip locked';
|
|
54
|
-
}
|
|
50
|
+
}
|
|
55
51
|
|
|
56
52
|
// Supported on MySQL 8.0+ and MariaDB 10.3.0+
|
|
57
53
|
noWait() {
|
|
58
54
|
return 'nowait';
|
|
59
|
-
}
|
|
55
|
+
}
|
|
60
56
|
|
|
61
57
|
// Compiles a `columnInfo` query.
|
|
62
58
|
columnInfo() {
|
|
@@ -72,7 +68,7 @@ Object.assign(QueryCompiler_MySQL.prototype, {
|
|
|
72
68
|
'select * from information_schema.columns where table_name = ? and table_schema = ?',
|
|
73
69
|
bindings: [table, this.client.database()],
|
|
74
70
|
output(resp) {
|
|
75
|
-
const out = resp.reduce(function(columns, val) {
|
|
71
|
+
const out = resp.reduce(function (columns, val) {
|
|
76
72
|
columns[val.COLUMN_NAME] = {
|
|
77
73
|
defaultValue: val.COLUMN_DEFAULT,
|
|
78
74
|
type: val.DATA_TYPE,
|
|
@@ -84,7 +80,7 @@ Object.assign(QueryCompiler_MySQL.prototype, {
|
|
|
84
80
|
return (column && out[column]) || out;
|
|
85
81
|
},
|
|
86
82
|
};
|
|
87
|
-
}
|
|
83
|
+
}
|
|
88
84
|
|
|
89
85
|
limit() {
|
|
90
86
|
const noLimit = !this.single.limit && this.single.limit !== 0;
|
|
@@ -97,8 +93,8 @@ Object.assign(QueryCompiler_MySQL.prototype, {
|
|
|
97
93
|
? '18446744073709551615'
|
|
98
94
|
: this.formatter.parameter(this.single.limit);
|
|
99
95
|
return `limit ${limit}`;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
102
98
|
|
|
103
99
|
// Set the QueryBuilder & QueryCompiler on the client object,
|
|
104
100
|
// in case anyone wants to modify things to suit their own purposes.
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
// Oracle Query Builder & Compiler
|
|
4
4
|
// ------
|
|
5
5
|
const {
|
|
6
|
-
assign,
|
|
7
6
|
isPlainObject,
|
|
8
7
|
isEmpty,
|
|
9
8
|
isString,
|
|
@@ -12,7 +11,6 @@ const {
|
|
|
12
11
|
compact,
|
|
13
12
|
identity,
|
|
14
13
|
} = require('lodash');
|
|
15
|
-
const inherits = require('inherits');
|
|
16
14
|
const QueryCompiler = require('../../../query/compiler');
|
|
17
15
|
const { ReturningHelper } = require('../utils');
|
|
18
16
|
|
|
@@ -33,13 +31,16 @@ const components = [
|
|
|
33
31
|
// Set the "Formatter" to use for the queries,
|
|
34
32
|
// ensuring that all parameterized values (even across sub-queries)
|
|
35
33
|
// are properly built into the same query.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
class QueryCompiler_Oracle extends QueryCompiler {
|
|
35
|
+
constructor(client, builder) {
|
|
36
|
+
super(client, builder);
|
|
39
37
|
|
|
40
|
-
|
|
38
|
+
// Compiles the `select` statement, or nested sub-selects
|
|
39
|
+
// by calling each of the component compilers, trimming out
|
|
40
|
+
// the empties, and returning a generated query string.
|
|
41
|
+
this.first = this.select;
|
|
42
|
+
}
|
|
41
43
|
|
|
42
|
-
assign(QueryCompiler_Oracle.prototype, {
|
|
43
44
|
// Compiles an "insert" query, allowing for multiple
|
|
44
45
|
// inserts using a single query statement.
|
|
45
46
|
insert() {
|
|
@@ -167,7 +168,7 @@ assign(QueryCompiler_Oracle.prototype, {
|
|
|
167
168
|
}
|
|
168
169
|
|
|
169
170
|
return sql;
|
|
170
|
-
}
|
|
171
|
+
}
|
|
171
172
|
|
|
172
173
|
// Update method, including joins, wheres, order & limits.
|
|
173
174
|
update() {
|
|
@@ -190,16 +191,16 @@ assign(QueryCompiler_Oracle.prototype, {
|
|
|
190
191
|
}
|
|
191
192
|
|
|
192
193
|
return this._addReturningToSqlAndConvert(sql, returning, this.tableName);
|
|
193
|
-
}
|
|
194
|
+
}
|
|
194
195
|
|
|
195
196
|
// Compiles a `truncate` query.
|
|
196
197
|
truncate() {
|
|
197
198
|
return `truncate table ${this.tableName}`;
|
|
198
|
-
}
|
|
199
|
+
}
|
|
199
200
|
|
|
200
201
|
forUpdate() {
|
|
201
202
|
return 'for update';
|
|
202
|
-
}
|
|
203
|
+
}
|
|
203
204
|
|
|
204
205
|
forShare() {
|
|
205
206
|
// lock for share is not directly supported by oracle
|
|
@@ -208,7 +209,7 @@ assign(QueryCompiler_Oracle.prototype, {
|
|
|
208
209
|
'lock for share is not supported by oracle dialect'
|
|
209
210
|
);
|
|
210
211
|
return '';
|
|
211
|
-
}
|
|
212
|
+
}
|
|
212
213
|
|
|
213
214
|
// Compiles a `columnInfo` query.
|
|
214
215
|
columnInfo() {
|
|
@@ -247,7 +248,7 @@ assign(QueryCompiler_Oracle.prototype, {
|
|
|
247
248
|
return (column && out[column]) || out;
|
|
248
249
|
},
|
|
249
250
|
};
|
|
250
|
-
}
|
|
251
|
+
}
|
|
251
252
|
|
|
252
253
|
select() {
|
|
253
254
|
let query = this.with();
|
|
@@ -256,11 +257,11 @@ assign(QueryCompiler_Oracle.prototype, {
|
|
|
256
257
|
});
|
|
257
258
|
query += compact(statements).join(' ');
|
|
258
259
|
return this._surroundQueryWithLimitAndOffset(query);
|
|
259
|
-
}
|
|
260
|
+
}
|
|
260
261
|
|
|
261
262
|
aggregate(stmt) {
|
|
262
263
|
return this._aggregate(stmt, { aliasSeparator: ' ' });
|
|
263
|
-
}
|
|
264
|
+
}
|
|
264
265
|
|
|
265
266
|
// for single commands only
|
|
266
267
|
_addReturningToSqlAndConvert(sql, returning, tableName) {
|
|
@@ -284,7 +285,7 @@ assign(QueryCompiler_Oracle.prototype, {
|
|
|
284
285
|
res.outParams = [returningHelper];
|
|
285
286
|
res.returning = returning;
|
|
286
287
|
return res;
|
|
287
|
-
}
|
|
288
|
+
}
|
|
288
289
|
|
|
289
290
|
_surroundQueryWithLimitAndOffset(query) {
|
|
290
291
|
let { limit } = this.single;
|
|
@@ -314,12 +315,7 @@ assign(QueryCompiler_Oracle.prototype, {
|
|
|
314
315
|
'where rownum_ > ' +
|
|
315
316
|
this.formatter.parameter(offset)
|
|
316
317
|
);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
// Compiles the `select` statement, or nested sub-selects
|
|
321
|
-
// by calling each of the component compilers, trimming out
|
|
322
|
-
// the empties, and returning a generated query string.
|
|
323
|
-
QueryCompiler_Oracle.prototype.first = QueryCompiler_Oracle.prototype.select;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
324
320
|
|
|
325
321
|
module.exports = QueryCompiler_Oracle;
|