knex 1.0.2 → 1.0.5
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 +65 -0
- package/README.md +6 -6
- package/bin/cli.js +16 -11
- package/bin/utils/cli-config-utils.js +33 -7
- package/bin/utils/migrationsLister.js +3 -3
- package/lib/client.js +4 -1
- package/lib/dialects/cockroachdb/crdb-querycompiler.js +2 -2
- package/lib/dialects/mysql/schema/mysql-tablecompiler.js +41 -6
- package/lib/dialects/oracledb/query/oracledb-querycompiler.js +2 -2
- package/lib/dialects/postgres/query/pg-querycompiler.js +3 -3
- package/lib/dialects/sqlite3/index.js +2 -0
- package/lib/migrations/seed/stub/js.stub +7 -10
- package/lib/migrations/util/is-module-type.js +6 -11
- package/lib/query/method-constants.js +8 -2
- package/lib/query/querybuilder.js +19 -3
- package/lib/query/querycompiler.js +55 -5
- package/package.json +13 -11
- package/types/index.d.ts +96 -117
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,70 @@
|
|
|
1
1
|
# Master (Unreleased)
|
|
2
2
|
|
|
3
|
+
# 1.0.5 - 05 March, 2022
|
|
4
|
+
|
|
5
|
+
### New features:
|
|
6
|
+
|
|
7
|
+
- Override knexfile options with CLI options #4047
|
|
8
|
+
|
|
9
|
+
### Bug fixes:
|
|
10
|
+
|
|
11
|
+
- Stringify json value in update #5063
|
|
12
|
+
- Fix isModuleType() for yarn #4447
|
|
13
|
+
- Wrapped Unions Fixes #5072
|
|
14
|
+
- SQLite: Fix @vscode-sqlite3 error message #5081
|
|
15
|
+
- CLI: Fix completed migration listing #5060
|
|
16
|
+
|
|
17
|
+
### Typings:
|
|
18
|
+
|
|
19
|
+
- Make default generic parameters of `Knex` match the generic parameter types of `knex` #5021
|
|
20
|
+
- Update knex types for TS 4.7 #5095
|
|
21
|
+
|
|
22
|
+
# 1.0.4 - 13 March, 2022
|
|
23
|
+
|
|
24
|
+
### New features:
|
|
25
|
+
|
|
26
|
+
- Add whereLike functions #5044
|
|
27
|
+
|
|
28
|
+
### Bug fixes:
|
|
29
|
+
|
|
30
|
+
- Fix orWhereJsonPath clause #5022
|
|
31
|
+
- Subquery in on clause missing parenthesis #5049
|
|
32
|
+
- Rework Union Wrapping #5030
|
|
33
|
+
- Oracle: Fix batch inserts with DEFAULT values with OracleDB #2592 #5037
|
|
34
|
+
|
|
35
|
+
### Typings:
|
|
36
|
+
|
|
37
|
+
- Fix types for "returning" methods #5031
|
|
38
|
+
- createTableLike callback should be optional #5055
|
|
39
|
+
|
|
40
|
+
### Documentation:
|
|
41
|
+
|
|
42
|
+
- Website URL changed to https://knex.github.io/documentation/
|
|
43
|
+
|
|
44
|
+
# 1.0.3 - 11 February, 2022
|
|
45
|
+
|
|
46
|
+
### Bug fixes:
|
|
47
|
+
|
|
48
|
+
- Fix error message for missing migration files #4937
|
|
49
|
+
- Add withMaterialized and withNotMaterialized to method-constants #5009
|
|
50
|
+
- PostgreSQL: Fix whereJsonPath queries #5011
|
|
51
|
+
- PostgreSQL: Fix delete joins #5016
|
|
52
|
+
- CockroachDB: Fix whereJsonPath queries #5011
|
|
53
|
+
- MySQL: Create primary keys in same statement #5017
|
|
54
|
+
|
|
55
|
+
### Typings:
|
|
56
|
+
|
|
57
|
+
- Fix type definition for getMigration in MigrationSource #4998
|
|
58
|
+
- Fix argument type of alter method #4996
|
|
59
|
+
|
|
60
|
+
### Improvements:
|
|
61
|
+
|
|
62
|
+
- Use async / await syntax in seeds as default #5005
|
|
63
|
+
|
|
64
|
+
### Documentation:
|
|
65
|
+
|
|
66
|
+
- Add Firebird dialect to ECOSYSTEM.md #5003
|
|
67
|
+
|
|
3
68
|
# 1.0.2 - 02 February, 2022
|
|
4
69
|
|
|
5
70
|
### New features:
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# [knex.js](
|
|
1
|
+
# [knex.js](https://knex.github.io/documentation/)
|
|
2
2
|
|
|
3
3
|
[](https://npmjs.org/package/knex)
|
|
4
4
|
[](https://npmjs.org/package/knex)
|
|
@@ -13,15 +13,15 @@
|
|
|
13
13
|
A batteries-included, multi-dialect (PostgreSQL, MySQL, CockroachDB, MSSQL, SQLite3, Oracle (including Oracle Wallet Authentication)) query builder for
|
|
14
14
|
Node.js, featuring:
|
|
15
15
|
|
|
16
|
-
- [transactions](https://
|
|
17
|
-
- [connection pooling](https://
|
|
18
|
-
- [streaming queries](https://
|
|
19
|
-
- both a [promise](https://
|
|
16
|
+
- [transactions](https://knex.github.io/documentation/#Transactions)
|
|
17
|
+
- [connection pooling](https://knex.github.io/documentation/#Installation-pooling)
|
|
18
|
+
- [streaming queries](https://knex.github.io/documentation/#Interfaces-Streams)
|
|
19
|
+
- both a [promise](https://knex.github.io/documentation/#Interfaces-Promises) and [callback](https://knex.github.io/documentation/#Interfaces-Callbacks) API
|
|
20
20
|
- a [thorough test suite](https://github.com/knex/knex/actions)
|
|
21
21
|
|
|
22
22
|
Node.js versions 12+ are supported.
|
|
23
23
|
|
|
24
|
-
* Take a look at the [full documentation](https://
|
|
24
|
+
* Take a look at the [full documentation](https://knex.github.io/documentation) to get started!
|
|
25
25
|
* Browse the [list of plugins and tools](https://github.com/knex/knex/blob/master/ECOSYSTEM.md) built for knex
|
|
26
26
|
* Check out our [recipes wiki](https://github.com/knex/knex/wiki/Recipes) to search for solutions to some specific problems
|
|
27
27
|
* In case of upgrading from an older version, see [migration guide](https://github.com/knex/knex/blob/master/UPGRADING.md)
|
package/bin/cli.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
const rechoir = require('rechoir');
|
|
3
|
+
const merge = require('lodash/merge');
|
|
3
4
|
const interpret = require('interpret');
|
|
4
5
|
const resolveFrom = require('resolve-from');
|
|
5
6
|
const path = require('path');
|
|
@@ -9,6 +10,7 @@ const color = require('colorette');
|
|
|
9
10
|
const argv = require('getopts')(process.argv.slice(2));
|
|
10
11
|
const cliPkg = require('../package');
|
|
11
12
|
const {
|
|
13
|
+
parseConfigObj,
|
|
12
14
|
mkConfigObj,
|
|
13
15
|
resolveEnvironmentConfig,
|
|
14
16
|
exit,
|
|
@@ -59,8 +61,17 @@ async function initKnex(env, opts) {
|
|
|
59
61
|
env.configuration,
|
|
60
62
|
env.configPath
|
|
61
63
|
);
|
|
64
|
+
|
|
65
|
+
const optionsConfig = parseConfigObj(opts);
|
|
66
|
+
const config = merge(resolvedConfig, optionsConfig);
|
|
67
|
+
|
|
68
|
+
// Migrations directory gets defaulted if it is undefined.
|
|
69
|
+
if (!env.configPath && !config.migrations.directory) {
|
|
70
|
+
config.migrations.directory = null;
|
|
71
|
+
}
|
|
72
|
+
|
|
62
73
|
const knex = require(env.modulePath);
|
|
63
|
-
return knex(
|
|
74
|
+
return knex(config);
|
|
64
75
|
}
|
|
65
76
|
|
|
66
77
|
function invoke() {
|
|
@@ -138,16 +149,10 @@ function invoke() {
|
|
|
138
149
|
.option('--knexfile [path]', 'Specify the knexfile path.')
|
|
139
150
|
.option('--knexpath [path]', 'Specify the path to knex instance.')
|
|
140
151
|
.option('--cwd [path]', 'Specify the working directory.')
|
|
141
|
-
.option('--client [name]', 'Set DB client
|
|
142
|
-
.option('--connection [address]', 'Set DB connection
|
|
143
|
-
.option(
|
|
144
|
-
|
|
145
|
-
'Set migrations directory without a knexfile.'
|
|
146
|
-
)
|
|
147
|
-
.option(
|
|
148
|
-
'--migrations-table-name [path]',
|
|
149
|
-
'Set migrations table name without a knexfile.'
|
|
150
|
-
)
|
|
152
|
+
.option('--client [name]', 'Set DB client.')
|
|
153
|
+
.option('--connection [address]', 'Set DB connection.')
|
|
154
|
+
.option('--migrations-directory [path]', 'Set migrations directory.')
|
|
155
|
+
.option('--migrations-table-name [path]', 'Set migrations table name.')
|
|
151
156
|
.option(
|
|
152
157
|
'--env [name]',
|
|
153
158
|
'environment, default: process.env.NODE_ENV || development'
|
|
@@ -1,12 +1,39 @@
|
|
|
1
1
|
const { DEFAULT_EXT, DEFAULT_TABLE_NAME } = require('./constants');
|
|
2
2
|
const { resolveClientNameWithAliases } = require('../../lib/util/helpers');
|
|
3
|
-
const fs = require('fs');
|
|
4
3
|
const path = require('path');
|
|
5
4
|
const escalade = require('escalade/sync');
|
|
6
5
|
const tildify = require('tildify');
|
|
7
6
|
const color = require('colorette');
|
|
8
7
|
const argv = require('getopts')(process.argv.slice(2));
|
|
9
8
|
|
|
9
|
+
function findCaseInsensitiveProperty(propertyName, object) {
|
|
10
|
+
return Object.keys(object).find(
|
|
11
|
+
(key) => key.toLowerCase() === propertyName.toLowerCase()
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function parseConfigObj(opts) {
|
|
16
|
+
const config = { migrations: {} };
|
|
17
|
+
|
|
18
|
+
if (opts.client) {
|
|
19
|
+
config.client = opts.client;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (opts.connection) {
|
|
23
|
+
config.connection = opts.connection;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (opts.migrationsDirectory) {
|
|
27
|
+
config.migrations.directory = opts.migrationsDirectory;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (opts.migrationsTableName) {
|
|
31
|
+
config.migrations.tableName = opts.migrationsTableName;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return config;
|
|
35
|
+
}
|
|
36
|
+
|
|
10
37
|
function mkConfigObj(opts) {
|
|
11
38
|
if (!opts.client) {
|
|
12
39
|
throw new Error(
|
|
@@ -17,16 +44,14 @@ function mkConfigObj(opts) {
|
|
|
17
44
|
const envName = opts.env || process.env.NODE_ENV || 'development';
|
|
18
45
|
const resolvedClientName = resolveClientNameWithAliases(opts.client);
|
|
19
46
|
const useNullAsDefault = resolvedClientName === 'sqlite3';
|
|
47
|
+
const parsedConfig = parseConfigObj(opts);
|
|
48
|
+
|
|
20
49
|
return {
|
|
21
50
|
ext: DEFAULT_EXT,
|
|
22
51
|
[envName]: {
|
|
52
|
+
...parsedConfig,
|
|
23
53
|
useNullAsDefault,
|
|
24
|
-
|
|
25
|
-
connection: opts.connection,
|
|
26
|
-
migrations: {
|
|
27
|
-
directory: opts.migrationsDirectory,
|
|
28
|
-
tableName: opts.migrationsTableName || DEFAULT_TABLE_NAME,
|
|
29
|
-
},
|
|
54
|
+
tableName: parsedConfig.tableName || DEFAULT_TABLE_NAME,
|
|
30
55
|
},
|
|
31
56
|
};
|
|
32
57
|
}
|
|
@@ -174,6 +199,7 @@ function findUpConfig(cwd, name, extensions) {
|
|
|
174
199
|
}
|
|
175
200
|
|
|
176
201
|
module.exports = {
|
|
202
|
+
parseConfigObj,
|
|
177
203
|
mkConfigObj,
|
|
178
204
|
resolveEnvironmentConfig,
|
|
179
205
|
exit,
|
|
@@ -6,7 +6,7 @@ function listMigrations(completed, newMigrations) {
|
|
|
6
6
|
let message = '';
|
|
7
7
|
|
|
8
8
|
if (completed.length === 0) {
|
|
9
|
-
message += color.red('No Completed Migration files Found
|
|
9
|
+
message += color.red('No Completed Migration files Found.\n');
|
|
10
10
|
} else {
|
|
11
11
|
message = color.green(
|
|
12
12
|
`Found ${completed.length} Completed Migration file/files.\n`
|
|
@@ -14,7 +14,7 @@ function listMigrations(completed, newMigrations) {
|
|
|
14
14
|
|
|
15
15
|
for (let i = 0; i < completed.length; i++) {
|
|
16
16
|
const file = completed[i];
|
|
17
|
-
message += color.cyan(`${file}
|
|
17
|
+
message += color.cyan(`${file.name}\n`);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -27,7 +27,7 @@ function listMigrations(completed, newMigrations) {
|
|
|
27
27
|
|
|
28
28
|
for (let i = 0; i < newMigrations.length; i++) {
|
|
29
29
|
const file = newMigrations[i];
|
|
30
|
-
message += color.cyan(`${file.file}
|
|
30
|
+
message += color.cyan(`${file.file}\n`);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
|
package/lib/client.js
CHANGED
|
@@ -189,7 +189,10 @@ class Client extends EventEmitter {
|
|
|
189
189
|
try {
|
|
190
190
|
this.driver = this._driver();
|
|
191
191
|
} catch (e) {
|
|
192
|
-
const
|
|
192
|
+
const driverName = this.aliasDriverName
|
|
193
|
+
? this.aliasDriverName
|
|
194
|
+
: this.driverName;
|
|
195
|
+
const message = `Knex: run\n$ npm install ${driverName} --save`;
|
|
193
196
|
this.logger.error(`${message}\n${e.message}\n${e.stack}`);
|
|
194
197
|
throw new Error(`${message}\n${e.message}`);
|
|
195
198
|
}
|
|
@@ -35,9 +35,9 @@ class QueryCompiler_CRDB extends QueryCompiler_PG {
|
|
|
35
35
|
|
|
36
36
|
whereJsonPath(statement) {
|
|
37
37
|
let castValue = '';
|
|
38
|
-
if (parseInt(statement.value)) {
|
|
38
|
+
if (!isNaN(statement.value) && parseInt(statement.value)) {
|
|
39
39
|
castValue = '::int';
|
|
40
|
-
} else if (parseFloat(statement.value)) {
|
|
40
|
+
} else if (!isNaN(statement.value) && parseFloat(statement.value)) {
|
|
41
41
|
castValue = '::float';
|
|
42
42
|
} else {
|
|
43
43
|
castValue = " #>> '{}'";
|
|
@@ -19,7 +19,12 @@ class TableCompiler_MySQL extends TableCompiler {
|
|
|
19
19
|
: 'create table ';
|
|
20
20
|
const { client } = this;
|
|
21
21
|
let conn = {};
|
|
22
|
-
|
|
22
|
+
let columnsSql = ' (' + columns.sql.join(', ');
|
|
23
|
+
|
|
24
|
+
columnsSql += this.primaryKeys() || '';
|
|
25
|
+
columnsSql += this._addChecks();
|
|
26
|
+
columnsSql += ')';
|
|
27
|
+
|
|
23
28
|
let sql =
|
|
24
29
|
createStatement +
|
|
25
30
|
this.tableName() +
|
|
@@ -135,6 +140,34 @@ class TableCompiler_MySQL extends TableCompiler {
|
|
|
135
140
|
});
|
|
136
141
|
}
|
|
137
142
|
|
|
143
|
+
primaryKeys() {
|
|
144
|
+
const pks = (this.grouped.alterTable || []).filter(
|
|
145
|
+
(k) => k.method === 'primary'
|
|
146
|
+
);
|
|
147
|
+
if (pks.length > 0 && pks[0].args.length > 0) {
|
|
148
|
+
const columns = pks[0].args[0];
|
|
149
|
+
let constraintName = pks[0].args[1] || '';
|
|
150
|
+
if (constraintName) {
|
|
151
|
+
constraintName = ' constraint ' + this.formatter.wrap(constraintName);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (this.grouped.columns) {
|
|
155
|
+
const incrementsCols = this._getIncrementsColumnNames();
|
|
156
|
+
if (incrementsCols.length) {
|
|
157
|
+
incrementsCols.forEach((c) => {
|
|
158
|
+
if (!columns.includes(c)) {
|
|
159
|
+
columns.unshift(c);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return `,${constraintName} primary key (${this.formatter.columnize(
|
|
166
|
+
columns
|
|
167
|
+
)})`;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
138
171
|
getFKRefs(runner) {
|
|
139
172
|
const bindingsHolder = {
|
|
140
173
|
bindings: [],
|
|
@@ -269,11 +302,13 @@ class TableCompiler_MySQL extends TableCompiler {
|
|
|
269
302
|
});
|
|
270
303
|
}
|
|
271
304
|
}
|
|
272
|
-
this.
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
305
|
+
if (this.method !== 'create' && this.method !== 'createIfNot') {
|
|
306
|
+
this.pushQuery(
|
|
307
|
+
`alter table ${this.tableName()} add primary key ${constraintName}(${this.formatter.columnize(
|
|
308
|
+
primaryCols
|
|
309
|
+
)})`
|
|
310
|
+
);
|
|
311
|
+
}
|
|
277
312
|
if (incrementsCols.length) {
|
|
278
313
|
this.pushQuery(
|
|
279
314
|
`alter table ${this.tableName()} modify column ${this.formatter.columnize(
|
|
@@ -156,8 +156,8 @@ class Oracledb_Compiler extends Oracle_Compiler {
|
|
|
156
156
|
// later position binding will only convert the ? params
|
|
157
157
|
subSql = self.formatter.client.positionBindings(subSql);
|
|
158
158
|
const parameterizedValuesWithoutDefaultAndBlob = parameterizedValues
|
|
159
|
-
.replace(
|
|
160
|
-
.replace(
|
|
159
|
+
.replace(/DEFAULT, /g, '')
|
|
160
|
+
.replace(/, DEFAULT/g, '')
|
|
161
161
|
.replace('EMPTY_BLOB(), ', '')
|
|
162
162
|
.replace(', EMPTY_BLOB()', '');
|
|
163
163
|
return (
|
|
@@ -112,7 +112,7 @@ class QueryCompiler_PG extends QueryCompiler {
|
|
|
112
112
|
);
|
|
113
113
|
}
|
|
114
114
|
if (joinWheres.length > 0) {
|
|
115
|
-
wheres += (wheres ? ' and ' : '') + joinWheres.join(' ');
|
|
115
|
+
wheres += (wheres ? ' and ' : 'where ') + joinWheres.join(' and ');
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
if (tableJoins.length > 0) {
|
|
@@ -341,9 +341,9 @@ class QueryCompiler_PG extends QueryCompiler {
|
|
|
341
341
|
|
|
342
342
|
whereJsonPath(statement) {
|
|
343
343
|
let castValue = '';
|
|
344
|
-
if (parseInt(statement.value)) {
|
|
344
|
+
if (!isNaN(statement.value) && parseInt(statement.value)) {
|
|
345
345
|
castValue = '::int';
|
|
346
|
-
} else if (parseFloat(statement.value)) {
|
|
346
|
+
} else if (!isNaN(statement.value) && parseFloat(statement.value)) {
|
|
347
347
|
castValue = '::float';
|
|
348
348
|
} else {
|
|
349
349
|
castValue = " #>> '{}'";
|
|
@@ -232,6 +232,8 @@ Object.assign(Client_SQLite3.prototype, {
|
|
|
232
232
|
dialect: 'sqlite3',
|
|
233
233
|
|
|
234
234
|
driverName: 'sqlite3',
|
|
235
|
+
// SqlLite3 driver package name is different from driver name.
|
|
236
|
+
aliasDriverName: '@vscode/sqlite3',
|
|
235
237
|
});
|
|
236
238
|
|
|
237
239
|
module.exports = Client_SQLite3;
|
|
@@ -2,15 +2,12 @@
|
|
|
2
2
|
* @param { import("knex").Knex } knex
|
|
3
3
|
* @returns { Promise<void> }
|
|
4
4
|
*/
|
|
5
|
-
exports.seed = function(knex) {
|
|
5
|
+
exports.seed = async function(knex) {
|
|
6
6
|
// Deletes ALL existing entries
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
{id: 3, colName: 'rowValue3'}
|
|
14
|
-
]);
|
|
15
|
-
});
|
|
7
|
+
await knex('table_name').del()
|
|
8
|
+
await knex('table_name').insert([
|
|
9
|
+
{id: 1, colName: 'rowValue1'},
|
|
10
|
+
{id: 2, colName: 'rowValue2'},
|
|
11
|
+
{id: 3, colName: 'rowValue3'}
|
|
12
|
+
]);
|
|
16
13
|
};
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
const
|
|
1
|
+
const getPackageType = require('get-package-type');
|
|
2
2
|
|
|
3
3
|
module.exports = async function isModuleType(filepath) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
await
|
|
8
|
-
|
|
9
|
-
if (packageJson.type === 'module') {
|
|
10
|
-
return true;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
return process.env.npm_package_type === 'module' || filepath.endsWith('.mjs');
|
|
4
|
+
return (
|
|
5
|
+
filepath.endsWith('.mjs') ||
|
|
6
|
+
(!filepath.endsWith('.cjs') &&
|
|
7
|
+
(await getPackageType(filepath)) === 'module')
|
|
8
|
+
);
|
|
14
9
|
};
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
module.exports = [
|
|
4
4
|
'with',
|
|
5
5
|
'withRecursive',
|
|
6
|
+
'withMaterialized',
|
|
7
|
+
'withNotMaterialized',
|
|
6
8
|
'select',
|
|
7
9
|
'as',
|
|
8
10
|
'columns',
|
|
@@ -25,12 +27,16 @@ module.exports = [
|
|
|
25
27
|
'fullOuterJoin',
|
|
26
28
|
'crossJoin',
|
|
27
29
|
'where',
|
|
28
|
-
'whereLike',
|
|
29
|
-
'whereILike',
|
|
30
30
|
'andWhere',
|
|
31
31
|
'orWhere',
|
|
32
32
|
'whereNot',
|
|
33
33
|
'orWhereNot',
|
|
34
|
+
'whereLike',
|
|
35
|
+
'andWhereLike',
|
|
36
|
+
'orWhereLike',
|
|
37
|
+
'whereILike',
|
|
38
|
+
'andWhereILike',
|
|
39
|
+
'orWhereILike',
|
|
34
40
|
'whereRaw',
|
|
35
41
|
'whereWrapped',
|
|
36
42
|
'havingWrapped',
|
|
@@ -691,11 +691,21 @@ class Builder extends EventEmitter {
|
|
|
691
691
|
return this._whereLike('whereLike', column, value);
|
|
692
692
|
}
|
|
693
693
|
|
|
694
|
+
// Adds a `or where like` clause to the query.
|
|
695
|
+
orWhereLike(column, value) {
|
|
696
|
+
return this._bool('or')._whereLike('whereLike', column, value);
|
|
697
|
+
}
|
|
698
|
+
|
|
694
699
|
// Adds a `where ilike` clause to the query.
|
|
695
700
|
whereILike(column, value) {
|
|
696
701
|
return this._whereLike('whereILike', column, value);
|
|
697
702
|
}
|
|
698
703
|
|
|
704
|
+
// Adds a `or where ilike` clause to the query.
|
|
705
|
+
orWhereILike(column, value) {
|
|
706
|
+
return this._bool('or')._whereLike('whereILike', column, value);
|
|
707
|
+
}
|
|
708
|
+
|
|
699
709
|
// Adds a `group by` clause to the query.
|
|
700
710
|
groupBy(item) {
|
|
701
711
|
if (item && item.isRawInstance) {
|
|
@@ -1226,7 +1236,11 @@ class Builder extends EventEmitter {
|
|
|
1226
1236
|
const obj = this._single.update || {};
|
|
1227
1237
|
this._method = 'update';
|
|
1228
1238
|
if (isString(values)) {
|
|
1229
|
-
|
|
1239
|
+
if (isPlainObject(returning)) {
|
|
1240
|
+
obj[values] = JSON.stringify(returning);
|
|
1241
|
+
} else {
|
|
1242
|
+
obj[values] = returning;
|
|
1243
|
+
}
|
|
1230
1244
|
if (arguments.length > 2) {
|
|
1231
1245
|
ret = arguments[2];
|
|
1232
1246
|
}
|
|
@@ -1505,8 +1519,8 @@ class Builder extends EventEmitter {
|
|
|
1505
1519
|
return this;
|
|
1506
1520
|
}
|
|
1507
1521
|
|
|
1508
|
-
orWhereJsonPath(column, operator, value) {
|
|
1509
|
-
return this._bool('or').whereJsonPath(column, operator, value);
|
|
1522
|
+
orWhereJsonPath(column, path, operator, value) {
|
|
1523
|
+
return this._bool('or').whereJsonPath(column, path, operator, value);
|
|
1510
1524
|
}
|
|
1511
1525
|
|
|
1512
1526
|
// Json superset wheres
|
|
@@ -1725,6 +1739,8 @@ Builder.prototype.andWhereNotBetween = Builder.prototype.whereNotBetween;
|
|
|
1725
1739
|
Builder.prototype.andWhereJsonObject = Builder.prototype.whereJsonObject;
|
|
1726
1740
|
Builder.prototype.andWhereNotJsonObject = Builder.prototype.whereJsonObject;
|
|
1727
1741
|
Builder.prototype.andWhereJsonPath = Builder.prototype.whereJsonPath;
|
|
1742
|
+
Builder.prototype.andWhereLike = Builder.prototype.whereLike;
|
|
1743
|
+
Builder.prototype.andWhereILike = Builder.prototype.whereILike;
|
|
1728
1744
|
Builder.prototype.andHaving = Builder.prototype.having;
|
|
1729
1745
|
Builder.prototype.andHavingIn = Builder.prototype.havingIn;
|
|
1730
1746
|
Builder.prototype.andHavingNotIn = Builder.prototype.havingNotIn;
|
|
@@ -124,8 +124,54 @@ class QueryCompiler {
|
|
|
124
124
|
select() {
|
|
125
125
|
let sql = this.with();
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
|
|
127
|
+
let unionStatement = '';
|
|
128
|
+
|
|
129
|
+
const firstStatements = [];
|
|
130
|
+
const endStatements = [];
|
|
131
|
+
|
|
132
|
+
components.forEach((component) => {
|
|
133
|
+
const statement = this[component](this);
|
|
134
|
+
// We store the 'union' statement to append it at the end.
|
|
135
|
+
// We still need to call the component sequentially because of
|
|
136
|
+
// order of bindings.
|
|
137
|
+
switch (component) {
|
|
138
|
+
case 'union':
|
|
139
|
+
unionStatement = statement;
|
|
140
|
+
break;
|
|
141
|
+
case 'columns':
|
|
142
|
+
case 'join':
|
|
143
|
+
case 'where':
|
|
144
|
+
firstStatements.push(statement);
|
|
145
|
+
break;
|
|
146
|
+
default:
|
|
147
|
+
endStatements.push(statement);
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Check if we need to wrap the main query.
|
|
153
|
+
// We need to wrap main query if one of union have wrap options to true
|
|
154
|
+
// to avoid error syntax (in PostgreSQL for example).
|
|
155
|
+
const wrapMainQuery =
|
|
156
|
+
this.grouped.union &&
|
|
157
|
+
this.grouped.union.map((u) => u.wrap).some((u) => u);
|
|
158
|
+
|
|
159
|
+
if (this.onlyUnions()) {
|
|
160
|
+
const statements = compact(firstStatements.concat(endStatements)).join(
|
|
161
|
+
' '
|
|
162
|
+
);
|
|
163
|
+
sql += unionStatement + (statements ? ' ' + statements : '');
|
|
164
|
+
} else {
|
|
165
|
+
const allStatements =
|
|
166
|
+
(wrapMainQuery ? '(' : '') +
|
|
167
|
+
compact(firstStatements).join(' ') +
|
|
168
|
+
(wrapMainQuery ? ')' : '');
|
|
169
|
+
const endStat = compact(endStatements).join(' ');
|
|
170
|
+
sql +=
|
|
171
|
+
allStatements +
|
|
172
|
+
(unionStatement ? ' ' + unionStatement : '') +
|
|
173
|
+
(endStat ? ' ' + endStat : endStat);
|
|
174
|
+
}
|
|
129
175
|
return sql;
|
|
130
176
|
}
|
|
131
177
|
|
|
@@ -706,9 +752,10 @@ class QueryCompiler {
|
|
|
706
752
|
this.bindingsHolder
|
|
707
753
|
);
|
|
708
754
|
if (statement) {
|
|
709
|
-
|
|
755
|
+
const wrap = union.wrap;
|
|
756
|
+
if (wrap) sql += '(';
|
|
710
757
|
sql += statement;
|
|
711
|
-
if (
|
|
758
|
+
if (wrap) sql += ')';
|
|
712
759
|
}
|
|
713
760
|
}
|
|
714
761
|
return sql;
|
|
@@ -842,6 +889,7 @@ class QueryCompiler {
|
|
|
842
889
|
}
|
|
843
890
|
|
|
844
891
|
onBasic(clause) {
|
|
892
|
+
const toWrap = clause.value instanceof QueryBuilder;
|
|
845
893
|
return (
|
|
846
894
|
wrap_(
|
|
847
895
|
clause.column,
|
|
@@ -858,13 +906,15 @@ class QueryCompiler {
|
|
|
858
906
|
this.bindingsHolder
|
|
859
907
|
) +
|
|
860
908
|
' ' +
|
|
909
|
+
(toWrap ? '(' : '') +
|
|
861
910
|
wrap_(
|
|
862
911
|
clause.value,
|
|
863
912
|
undefined,
|
|
864
913
|
this.builder,
|
|
865
914
|
this.client,
|
|
866
915
|
this.bindingsHolder
|
|
867
|
-
)
|
|
916
|
+
) +
|
|
917
|
+
(toWrap ? ')' : '')
|
|
868
918
|
);
|
|
869
919
|
}
|
|
870
920
|
|