knex 0.95.13 → 1.0.1
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 +74 -3
- package/README.md +1 -1
- package/UPGRADING.md +7 -0
- package/lib/client.js +14 -1
- package/lib/constants.js +2 -0
- package/lib/dialects/better-sqlite3/index.js +72 -0
- package/lib/dialects/cockroachdb/crdb-querycompiler.js +87 -33
- package/lib/dialects/cockroachdb/crdb-tablecompiler.js +19 -0
- package/lib/dialects/cockroachdb/index.js +13 -0
- package/lib/dialects/mssql/index.js +0 -11
- package/lib/dialects/mssql/query/mssql-querycompiler.js +122 -64
- package/lib/dialects/mssql/schema/mssql-columncompiler.js +41 -6
- package/lib/dialects/mssql/schema/mssql-tablecompiler.js +24 -9
- package/lib/dialects/mssql/schema/mssql-viewcompiler.js +15 -1
- package/lib/dialects/mysql/index.js +3 -7
- package/lib/dialects/mysql/query/mysql-querycompiler.js +91 -5
- package/lib/dialects/mysql/schema/mysql-columncompiler.js +32 -5
- package/lib/dialects/mysql/schema/mysql-tablecompiler.js +28 -4
- package/lib/dialects/mysql2/index.js +7 -4
- package/lib/dialects/oracle/query/oracle-querycompiler.js +7 -6
- package/lib/dialects/oracle/schema/internal/trigger.js +1 -1
- package/lib/dialects/oracle/schema/oracle-columncompiler.js +10 -4
- package/lib/dialects/oracle/schema/oracle-tablecompiler.js +17 -6
- package/lib/dialects/oracledb/index.js +0 -4
- package/lib/dialects/oracledb/query/oracledb-querycompiler.js +104 -0
- package/lib/dialects/oracledb/schema/oracledb-columncompiler.js +23 -0
- package/lib/dialects/postgres/index.js +21 -6
- package/lib/dialects/postgres/query/pg-querybuilder.js +8 -0
- package/lib/dialects/postgres/query/pg-querycompiler.js +166 -5
- package/lib/dialects/postgres/schema/pg-columncompiler.js +24 -4
- package/lib/dialects/postgres/schema/pg-tablecompiler.js +55 -47
- package/lib/dialects/redshift/index.js +12 -0
- package/lib/dialects/redshift/query/redshift-querycompiler.js +62 -26
- package/lib/dialects/redshift/schema/redshift-columncompiler.js +2 -1
- package/lib/dialects/redshift/schema/redshift-tablecompiler.js +4 -1
- package/lib/dialects/sqlite3/index.js +18 -4
- package/lib/dialects/sqlite3/query/sqlite-querycompiler.js +85 -18
- package/lib/dialects/sqlite3/schema/ddl.js +274 -282
- package/lib/dialects/sqlite3/schema/internal/sqlite-ddl-operations.js +18 -8
- package/lib/dialects/sqlite3/schema/sqlite-columncompiler.js +20 -0
- package/lib/dialects/sqlite3/schema/sqlite-compiler.js +16 -12
- package/lib/dialects/sqlite3/schema/sqlite-tablecompiler.js +15 -5
- package/lib/dialects/sqlite3/schema/sqlite-viewcompiler.js +31 -2
- package/lib/execution/runner.js +37 -2
- package/lib/knex-builder/FunctionHelper.js +21 -0
- package/lib/migrations/common/MigrationsLoader.js +36 -0
- package/lib/migrations/migrate/MigrationGenerator.js +1 -1
- package/lib/migrations/migrate/Migrator.js +20 -23
- package/lib/migrations/migrate/migration-list-resolver.js +2 -5
- package/lib/migrations/migrate/{configuration-merger.js → migrator-configuration-merger.js} +2 -4
- package/lib/migrations/migrate/sources/fs-migrations.js +4 -29
- package/lib/migrations/migrate/stub/js.stub +8 -1
- package/lib/migrations/migrate/stub/knexfile-js.stub +3 -0
- package/lib/migrations/migrate/stub/knexfile-ts.stub +5 -2
- package/lib/migrations/migrate/table-creator.js +6 -5
- package/lib/migrations/seed/Seeder.js +25 -92
- package/lib/migrations/seed/seeder-configuration-merger.js +60 -0
- package/lib/migrations/seed/sources/fs-seeds.js +65 -0
- package/lib/migrations/seed/stub/js.stub +4 -1
- package/lib/migrations/util/import-file.js +0 -1
- package/lib/query/joinclause.js +24 -5
- package/lib/query/method-constants.js +37 -0
- package/lib/query/querybuilder.js +230 -5
- package/lib/query/querycompiler.js +269 -84
- package/lib/schema/columnbuilder.js +8 -0
- package/lib/schema/columncompiler.js +132 -5
- package/lib/schema/compiler.js +1 -0
- package/lib/schema/tablebuilder.js +41 -8
- package/lib/schema/tablecompiler.js +57 -0
- package/lib/schema/viewcompiler.js +13 -10
- package/package.json +35 -22
- package/scripts/docker-compose.yml +7 -7
- package/scripts/oracledb-install-driver-libs.sh +82 -0
- package/scripts/runkit-example.js +1 -1
- package/scripts/stress-test/docker-compose.yml +3 -3
- package/scripts/stress-test/knex-stress-test.js +1 -1
- package/scripts/stress-test/reconnect-test-mysql-based-drivers.js +1 -1
- package/types/index.d.ts +124 -20
|
@@ -315,10 +315,9 @@ class QueryCompiler_Oracle extends QueryCompiler {
|
|
|
315
315
|
query = query || '';
|
|
316
316
|
|
|
317
317
|
if (hasLimit && !offset) {
|
|
318
|
-
return `select * from (${query}) where rownum <= ${this.
|
|
319
|
-
limit,
|
|
320
|
-
|
|
321
|
-
this.bindingsHolder
|
|
318
|
+
return `select * from (${query}) where rownum <= ${this._getValueOrParameterFromAttribute(
|
|
319
|
+
'limit',
|
|
320
|
+
limit
|
|
322
321
|
)}`;
|
|
323
322
|
}
|
|
324
323
|
|
|
@@ -330,10 +329,12 @@ class QueryCompiler_Oracle extends QueryCompiler {
|
|
|
330
329
|
query +
|
|
331
330
|
') row_ ' +
|
|
332
331
|
'where rownum <= ' +
|
|
333
|
-
|
|
332
|
+
(this.single.skipBinding['offset']
|
|
333
|
+
? endRow
|
|
334
|
+
: this.client.parameter(endRow, this.builder, this.bindingsHolder)) +
|
|
334
335
|
') ' +
|
|
335
336
|
'where rownum_ > ' +
|
|
336
|
-
this.
|
|
337
|
+
this._getValueOrParameterFromAttribute('offset', offset)
|
|
337
338
|
);
|
|
338
339
|
}
|
|
339
340
|
}
|
|
@@ -64,7 +64,7 @@ const trigger = {
|
|
|
64
64
|
`PK_NAME VARCHAR(200); ` +
|
|
65
65
|
`BEGIN` +
|
|
66
66
|
` EXECUTE IMMEDIATE ('CREATE SEQUENCE ${schemaQuoted}${sequenceNameQuoted}');` +
|
|
67
|
-
` SELECT cols.column_name INTO PK_NAME` +
|
|
67
|
+
` SELECT cols.column_name INTO PK_NAME` + // TODO : support autoincrement on table with multiple primary keys
|
|
68
68
|
` FROM all_constraints cons, all_cons_columns cols` +
|
|
69
69
|
` WHERE cons.constraint_type = 'P'` +
|
|
70
70
|
` AND cons.constraint_name = cols.constraint_name` +
|
|
@@ -15,14 +15,20 @@ class ColumnCompiler_Oracle extends ColumnCompiler {
|
|
|
15
15
|
this.modifiers = ['defaultTo', 'checkIn', 'nullable', 'comment'];
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
increments({ primaryKey
|
|
18
|
+
increments(options = { primaryKey: true }) {
|
|
19
19
|
createAutoIncrementTriggerAndSequence(this);
|
|
20
|
-
return
|
|
20
|
+
return (
|
|
21
|
+
'integer not null' +
|
|
22
|
+
(this.tableCompiler._canBeAddPrimaryKey(options) ? ' primary key' : '')
|
|
23
|
+
);
|
|
21
24
|
}
|
|
22
25
|
|
|
23
|
-
bigincrements({ primaryKey
|
|
26
|
+
bigincrements(options = { primaryKey: true }) {
|
|
24
27
|
createAutoIncrementTriggerAndSequence(this);
|
|
25
|
-
return
|
|
28
|
+
return (
|
|
29
|
+
'number(20, 0) not null' +
|
|
30
|
+
(this.tableCompiler._canBeAddPrimaryKey(options) ? ' primary key' : '')
|
|
31
|
+
);
|
|
26
32
|
}
|
|
27
33
|
|
|
28
34
|
floating(precision) {
|
|
@@ -57,7 +57,7 @@ class TableCompiler_Oracle extends TableCompiler {
|
|
|
57
57
|
const columnsSql =
|
|
58
58
|
like && this.tableNameLike()
|
|
59
59
|
? ' as (select * from ' + this.tableNameLike() + ' where 0=1)'
|
|
60
|
-
: ' (' + columns.sql.join(', ') + ')';
|
|
60
|
+
: ' (' + columns.sql.join(', ') + this._addChecks() + ')';
|
|
61
61
|
const sql = `create table ${this.tableName()}${columnsSql}`;
|
|
62
62
|
|
|
63
63
|
this.pushQuery({
|
|
@@ -66,6 +66,9 @@ class TableCompiler_Oracle extends TableCompiler {
|
|
|
66
66
|
bindings: columns.bindings,
|
|
67
67
|
});
|
|
68
68
|
if (this.single.comment) this.comment(this.single.comment);
|
|
69
|
+
if (like) {
|
|
70
|
+
this.addColumns(columns, this.addColumnsPrefix);
|
|
71
|
+
}
|
|
69
72
|
}
|
|
70
73
|
|
|
71
74
|
// Compiles the comment on the table.
|
|
@@ -82,10 +85,6 @@ class TableCompiler_Oracle extends TableCompiler {
|
|
|
82
85
|
);
|
|
83
86
|
}
|
|
84
87
|
|
|
85
|
-
changeType() {
|
|
86
|
-
// alter table + table + ' modify ' + wrapped + '// type';
|
|
87
|
-
}
|
|
88
|
-
|
|
89
88
|
_indexCommand(type, tableName, columns) {
|
|
90
89
|
return this.formatter.wrap(
|
|
91
90
|
utils.generateCombinedName(this.client.logger, type, tableName, columns)
|
|
@@ -101,9 +100,21 @@ class TableCompiler_Oracle extends TableCompiler {
|
|
|
101
100
|
constraintName = constraintName
|
|
102
101
|
? this.formatter.wrap(constraintName)
|
|
103
102
|
: this.formatter.wrap(`${this.tableNameRaw}_pkey`);
|
|
103
|
+
const primaryCols = columns;
|
|
104
|
+
let incrementsCols = [];
|
|
105
|
+
if (this.grouped.columns) {
|
|
106
|
+
incrementsCols = this._getIncrementsColumnNames();
|
|
107
|
+
if (incrementsCols) {
|
|
108
|
+
incrementsCols.forEach((c) => {
|
|
109
|
+
if (!primaryCols.includes(c)) {
|
|
110
|
+
primaryCols.unshift(c);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
104
115
|
this.pushQuery(
|
|
105
116
|
`alter table ${this.tableName()} add constraint ${constraintName} primary key (${this.formatter.columnize(
|
|
106
|
-
|
|
117
|
+
primaryCols
|
|
107
118
|
)})${deferrable}`
|
|
108
119
|
);
|
|
109
120
|
}
|
|
@@ -4,7 +4,6 @@ const each = require('lodash/each');
|
|
|
4
4
|
const flatten = require('lodash/flatten');
|
|
5
5
|
const isEmpty = require('lodash/isEmpty');
|
|
6
6
|
const map = require('lodash/map');
|
|
7
|
-
const values = require('lodash/values');
|
|
8
7
|
|
|
9
8
|
const Formatter = require('../../formatter');
|
|
10
9
|
const QueryCompiler = require('./query/oracledb-querycompiler');
|
|
@@ -288,9 +287,6 @@ class Client_Oracledb extends Client_Oracle {
|
|
|
288
287
|
case 'update':
|
|
289
288
|
case 'counter':
|
|
290
289
|
if (obj.returning && !isEmpty(obj.returning)) {
|
|
291
|
-
if (obj.returning.length === 1 && obj.returning[0] !== '*') {
|
|
292
|
-
return flatten(map(response, values));
|
|
293
|
-
}
|
|
294
290
|
return response;
|
|
295
291
|
} else if (obj.rowsAffected !== undefined) {
|
|
296
292
|
return obj.rowsAffected;
|
|
@@ -6,6 +6,11 @@ const Oracle_Compiler = require('../../oracle/query/oracle-querycompiler');
|
|
|
6
6
|
const ReturningHelper = require('../utils').ReturningHelper;
|
|
7
7
|
const BlobHelper = require('../utils').BlobHelper;
|
|
8
8
|
const { isString } = require('../../../util/is');
|
|
9
|
+
const {
|
|
10
|
+
columnize: columnize_,
|
|
11
|
+
direction: direction_,
|
|
12
|
+
} = require('../../../formatter/wrappingFormatter');
|
|
13
|
+
const Raw = require('../../../raw');
|
|
9
14
|
|
|
10
15
|
class Oracledb_Compiler extends Oracle_Compiler {
|
|
11
16
|
// Compiles an "insert" query, allowing for multiple
|
|
@@ -312,6 +317,23 @@ class Oracledb_Compiler extends Oracle_Compiler {
|
|
|
312
317
|
return result;
|
|
313
318
|
}
|
|
314
319
|
|
|
320
|
+
_groupOrder(item, type) {
|
|
321
|
+
const column = super._formatGroupsItemValue(item.value);
|
|
322
|
+
const direction =
|
|
323
|
+
type === 'order' && item.type !== 'orderByRaw'
|
|
324
|
+
? ` ${direction_(
|
|
325
|
+
item.direction,
|
|
326
|
+
this.builder,
|
|
327
|
+
this.client,
|
|
328
|
+
this.bindingsHolder
|
|
329
|
+
)}`
|
|
330
|
+
: '';
|
|
331
|
+
if (item.nulls && !(item.value instanceof Raw)) {
|
|
332
|
+
return `${column}${direction ? direction : ''} nulls ${item.nulls}`;
|
|
333
|
+
}
|
|
334
|
+
return column + direction;
|
|
335
|
+
}
|
|
336
|
+
|
|
315
337
|
update() {
|
|
316
338
|
const self = this;
|
|
317
339
|
const sql = {};
|
|
@@ -387,6 +409,88 @@ class Oracledb_Compiler extends Oracle_Compiler {
|
|
|
387
409
|
|
|
388
410
|
return sql;
|
|
389
411
|
}
|
|
412
|
+
|
|
413
|
+
_jsonPathWrap(extraction) {
|
|
414
|
+
return `'${extraction.path || extraction[1]}'`;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Json functions
|
|
418
|
+
jsonExtract(params) {
|
|
419
|
+
return this._jsonExtract(
|
|
420
|
+
params.singleValue ? 'json_value' : 'json_query',
|
|
421
|
+
params
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
jsonSet(params) {
|
|
426
|
+
return `json_transform(${columnize_(
|
|
427
|
+
params.column,
|
|
428
|
+
this.builder,
|
|
429
|
+
this.client,
|
|
430
|
+
this.bindingsHolder
|
|
431
|
+
)}, set ${this.client.parameter(
|
|
432
|
+
params.path,
|
|
433
|
+
this.builder,
|
|
434
|
+
this.bindingsHolder
|
|
435
|
+
)} = ${this.client.parameter(
|
|
436
|
+
params.value,
|
|
437
|
+
this.builder,
|
|
438
|
+
this.bindingsHolder
|
|
439
|
+
)})`;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
jsonInsert(params) {
|
|
443
|
+
return `json_transform(${columnize_(
|
|
444
|
+
params.column,
|
|
445
|
+
this.builder,
|
|
446
|
+
this.client,
|
|
447
|
+
this.bindingsHolder
|
|
448
|
+
)}, insert ${this.client.parameter(
|
|
449
|
+
params.path,
|
|
450
|
+
this.builder,
|
|
451
|
+
this.bindingsHolder
|
|
452
|
+
)} = ${this.client.parameter(
|
|
453
|
+
params.value,
|
|
454
|
+
this.builder,
|
|
455
|
+
this.bindingsHolder
|
|
456
|
+
)})`;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
jsonRemove(params) {
|
|
460
|
+
const jsonCol = `json_transform(${columnize_(
|
|
461
|
+
params.column,
|
|
462
|
+
this.builder,
|
|
463
|
+
this.client,
|
|
464
|
+
this.bindingsHolder
|
|
465
|
+
)}, remove ${this.client.parameter(
|
|
466
|
+
params.path,
|
|
467
|
+
this.builder,
|
|
468
|
+
this.bindingsHolder
|
|
469
|
+
)})`;
|
|
470
|
+
return params.alias
|
|
471
|
+
? this.client.alias(jsonCol, this.formatter.wrap(params.alias))
|
|
472
|
+
: jsonCol;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
whereJsonPath(statement) {
|
|
476
|
+
return this._whereJsonPath('json_value', statement);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
whereJsonSupersetOf(statement) {
|
|
480
|
+
throw new Error(
|
|
481
|
+
'Json superset where clause not actually supported by Oracle'
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
whereJsonSubsetOf(statement) {
|
|
486
|
+
throw new Error(
|
|
487
|
+
'Json subset where clause not actually supported by Oracle'
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
onJsonPathEquals(clause) {
|
|
492
|
+
return this._onJsonPathEquals('json_value', clause);
|
|
493
|
+
}
|
|
390
494
|
}
|
|
391
495
|
|
|
392
496
|
module.exports = Oracledb_Compiler;
|
|
@@ -4,6 +4,8 @@ const { isObject } = require('../../../util/is');
|
|
|
4
4
|
class ColumnCompiler_Oracledb extends ColumnCompiler_Oracle {
|
|
5
5
|
constructor() {
|
|
6
6
|
super(...arguments);
|
|
7
|
+
this.modifiers = ['defaultTo', 'nullable', 'comment'];
|
|
8
|
+
this._addCheckModifiers();
|
|
7
9
|
}
|
|
8
10
|
|
|
9
11
|
datetime(withoutTz) {
|
|
@@ -25,8 +27,29 @@ class ColumnCompiler_Oracledb extends ColumnCompiler_Oracle {
|
|
|
25
27
|
}
|
|
26
28
|
return useTz ? 'timestamp with local time zone' : 'timestamp';
|
|
27
29
|
}
|
|
30
|
+
|
|
31
|
+
checkRegex(regex, constraintName) {
|
|
32
|
+
return this._check(
|
|
33
|
+
`REGEXP_LIKE(${this.formatter.wrap(
|
|
34
|
+
this.getColumnName()
|
|
35
|
+
)},${this.client._escapeBinding(regex)})`,
|
|
36
|
+
constraintName
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
json() {
|
|
41
|
+
return `varchar2(4000) check (${this.formatter.columnize(
|
|
42
|
+
this.getColumnName()
|
|
43
|
+
)} is json)`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
jsonb() {
|
|
47
|
+
return this.json();
|
|
48
|
+
}
|
|
28
49
|
}
|
|
29
50
|
|
|
30
51
|
ColumnCompiler_Oracledb.prototype.time = 'timestamp with local time zone';
|
|
52
|
+
ColumnCompiler_Oracledb.prototype.uuid = ({ useBinaryUuid = false } = {}) =>
|
|
53
|
+
useBinaryUuid ? 'raw(16)' : 'char(36)';
|
|
31
54
|
|
|
32
55
|
module.exports = ColumnCompiler_Oracledb;
|
|
@@ -7,6 +7,7 @@ const Client = require('../../client');
|
|
|
7
7
|
|
|
8
8
|
const Transaction = require('./execution/pg-transaction');
|
|
9
9
|
const QueryCompiler = require('./query/pg-querycompiler');
|
|
10
|
+
const QueryBuilder = require('./query/pg-querybuilder');
|
|
10
11
|
const ColumnCompiler = require('./schema/pg-columncompiler');
|
|
11
12
|
const TableCompiler = require('./schema/pg-tablecompiler');
|
|
12
13
|
const ViewCompiler = require('./schema/pg-viewcompiler');
|
|
@@ -30,6 +31,10 @@ class Client_PG extends Client {
|
|
|
30
31
|
return new Transaction(this, ...arguments);
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
queryBuilder() {
|
|
35
|
+
return new QueryBuilder(this);
|
|
36
|
+
}
|
|
37
|
+
|
|
33
38
|
queryCompiler(builder, formatter) {
|
|
34
39
|
return new QueryCompiler(this, builder, formatter);
|
|
35
40
|
}
|
|
@@ -241,12 +246,7 @@ class Client_PG extends Client {
|
|
|
241
246
|
const returns = [];
|
|
242
247
|
for (let i = 0, l = resp.rows.length; i < l; i++) {
|
|
243
248
|
const row = resp.rows[i];
|
|
244
|
-
|
|
245
|
-
returns[i] = row;
|
|
246
|
-
} else {
|
|
247
|
-
// Pluck the only column in the row.
|
|
248
|
-
returns[i] = row[Object.keys(row)[0]];
|
|
249
|
-
}
|
|
249
|
+
returns[i] = row;
|
|
250
250
|
}
|
|
251
251
|
return returns;
|
|
252
252
|
}
|
|
@@ -274,6 +274,21 @@ class Client_PG extends Client {
|
|
|
274
274
|
options: {},
|
|
275
275
|
});
|
|
276
276
|
}
|
|
277
|
+
|
|
278
|
+
toPathForJson(jsonPath) {
|
|
279
|
+
const PG_PATH_REGEX = /^{.*}$/;
|
|
280
|
+
if (jsonPath.match(PG_PATH_REGEX)) {
|
|
281
|
+
return jsonPath;
|
|
282
|
+
}
|
|
283
|
+
return (
|
|
284
|
+
'{' +
|
|
285
|
+
jsonPath
|
|
286
|
+
.replace(/^(\$\.)/, '') // remove the first dollar
|
|
287
|
+
.replace('.', ',')
|
|
288
|
+
.replace(/\[([0-9]+)]/, ',$1') + // transform [number] to ,number
|
|
289
|
+
'}'
|
|
290
|
+
);
|
|
291
|
+
}
|
|
277
292
|
}
|
|
278
293
|
|
|
279
294
|
Object.assign(Client_PG.prototype, {
|
|
@@ -4,7 +4,12 @@ const identity = require('lodash/identity');
|
|
|
4
4
|
const reduce = require('lodash/reduce');
|
|
5
5
|
|
|
6
6
|
const QueryCompiler = require('../../../query/querycompiler');
|
|
7
|
-
const {
|
|
7
|
+
const {
|
|
8
|
+
wrapString,
|
|
9
|
+
columnize: columnize_,
|
|
10
|
+
operator: operator_,
|
|
11
|
+
wrap: wrap_,
|
|
12
|
+
} = require('../../../formatter/wrappingFormatter');
|
|
8
13
|
|
|
9
14
|
class QueryCompiler_PG extends QueryCompiler {
|
|
10
15
|
constructor(client, builder, formatter) {
|
|
@@ -35,7 +40,7 @@ class QueryCompiler_PG extends QueryCompiler {
|
|
|
35
40
|
if (returning) sql += this._returning(returning);
|
|
36
41
|
|
|
37
42
|
return {
|
|
38
|
-
sql
|
|
43
|
+
sql,
|
|
39
44
|
returning,
|
|
40
45
|
};
|
|
41
46
|
}
|
|
@@ -57,9 +62,70 @@ class QueryCompiler_PG extends QueryCompiler {
|
|
|
57
62
|
};
|
|
58
63
|
}
|
|
59
64
|
|
|
60
|
-
|
|
65
|
+
using() {
|
|
66
|
+
const usingTables = this.single.using;
|
|
67
|
+
if (!usingTables) return;
|
|
68
|
+
let sql = 'using ';
|
|
69
|
+
if (Array.isArray(usingTables)) {
|
|
70
|
+
sql += usingTables
|
|
71
|
+
.map((table) => {
|
|
72
|
+
return this.formatter.wrap(table);
|
|
73
|
+
})
|
|
74
|
+
.join(',');
|
|
75
|
+
} else {
|
|
76
|
+
sql += this.formatter.wrap(usingTables);
|
|
77
|
+
}
|
|
78
|
+
return sql;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Compiles an `delete` query, allowing for a return value.
|
|
61
82
|
del() {
|
|
62
|
-
|
|
83
|
+
// Make sure tableName is processed by the formatter first.
|
|
84
|
+
const { tableName } = this;
|
|
85
|
+
const withSQL = this.with();
|
|
86
|
+
let wheres = this.where() || '';
|
|
87
|
+
let using = this.using() || '';
|
|
88
|
+
const joins = this.grouped.join;
|
|
89
|
+
|
|
90
|
+
const tableJoins = [];
|
|
91
|
+
if (Array.isArray(joins)) {
|
|
92
|
+
for (const join of joins) {
|
|
93
|
+
tableJoins.push(
|
|
94
|
+
wrap_(
|
|
95
|
+
this._joinTable(join),
|
|
96
|
+
undefined,
|
|
97
|
+
this.builder,
|
|
98
|
+
this.client,
|
|
99
|
+
this.bindingsHolder
|
|
100
|
+
)
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
const joinWheres = [];
|
|
104
|
+
for (const clause of join.clauses) {
|
|
105
|
+
joinWheres.push(
|
|
106
|
+
this.whereBasic({
|
|
107
|
+
column: clause.column,
|
|
108
|
+
operator: '=',
|
|
109
|
+
value: clause.value,
|
|
110
|
+
asColumn: true,
|
|
111
|
+
})
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
if (joinWheres.length > 0) {
|
|
115
|
+
wheres += (wheres ? ' and ' : '') + joinWheres.join(' ');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (tableJoins.length > 0) {
|
|
119
|
+
using += (using ? ',' : 'using ') + tableJoins.join(',');
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// With 'using' syntax, no tablename between DELETE and FROM.
|
|
124
|
+
const sql =
|
|
125
|
+
withSQL +
|
|
126
|
+
`delete from ${this.single.only ? 'only ' : ''}${tableName}` +
|
|
127
|
+
(using ? ` ${using}` : '') +
|
|
128
|
+
(wheres ? ` ${wheres}` : '');
|
|
63
129
|
const { returning } = this.single;
|
|
64
130
|
return {
|
|
65
131
|
sql: sql + this._returning(returning),
|
|
@@ -191,10 +257,14 @@ class QueryCompiler_PG extends QueryCompiler {
|
|
|
191
257
|
schema = this.client.customWrapIdentifier(schema, identity);
|
|
192
258
|
}
|
|
193
259
|
|
|
194
|
-
|
|
260
|
+
const sql =
|
|
195
261
|
'select * from information_schema.columns where table_name = ? and table_catalog = current_database()';
|
|
196
262
|
const bindings = [table];
|
|
197
263
|
|
|
264
|
+
return this._buildColumnInfoQuery(schema, sql, bindings, column);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
_buildColumnInfoQuery(schema, sql, bindings, column) {
|
|
198
268
|
if (schema) {
|
|
199
269
|
sql += ' and table_schema = ?';
|
|
200
270
|
bindings.push(schema);
|
|
@@ -227,6 +297,97 @@ class QueryCompiler_PG extends QueryCompiler {
|
|
|
227
297
|
distinctOn(value) {
|
|
228
298
|
return 'distinct on (' + this.formatter.columnize(value) + ') ';
|
|
229
299
|
}
|
|
300
|
+
|
|
301
|
+
// Json functions
|
|
302
|
+
jsonExtract(params) {
|
|
303
|
+
return this._jsonExtract('jsonb_path_query', params);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
jsonSet(params) {
|
|
307
|
+
return this._jsonSet(
|
|
308
|
+
'jsonb_set',
|
|
309
|
+
Object.assign({}, params, {
|
|
310
|
+
path: this.client.toPathForJson(params.path),
|
|
311
|
+
})
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
jsonInsert(params) {
|
|
316
|
+
return this._jsonSet(
|
|
317
|
+
'jsonb_insert',
|
|
318
|
+
Object.assign({}, params, {
|
|
319
|
+
path: this.client.toPathForJson(params.path),
|
|
320
|
+
})
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
jsonRemove(params) {
|
|
325
|
+
const jsonCol = `${columnize_(
|
|
326
|
+
params.column,
|
|
327
|
+
this.builder,
|
|
328
|
+
this.client,
|
|
329
|
+
this.bindingsHolder
|
|
330
|
+
)} #- ${this.client.parameter(
|
|
331
|
+
this.client.toPathForJson(params.path),
|
|
332
|
+
this.builder,
|
|
333
|
+
this.bindingsHolder
|
|
334
|
+
)}`;
|
|
335
|
+
return params.alias
|
|
336
|
+
? this.client.alias(jsonCol, this.formatter.wrap(params.alias))
|
|
337
|
+
: jsonCol;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
whereJsonPath(statement) {
|
|
341
|
+
let castValue = '';
|
|
342
|
+
if (parseInt(statement.value)) {
|
|
343
|
+
castValue = '::int';
|
|
344
|
+
} else if (parseFloat(statement.value)) {
|
|
345
|
+
castValue = '::float';
|
|
346
|
+
} else {
|
|
347
|
+
castValue = " #>> '{}'";
|
|
348
|
+
}
|
|
349
|
+
return `jsonb_path_query_first(${this._columnClause(
|
|
350
|
+
statement
|
|
351
|
+
)}, ${this.client.parameter(
|
|
352
|
+
statement.jsonPath,
|
|
353
|
+
this.builder,
|
|
354
|
+
this.bindingsHolder
|
|
355
|
+
)})${castValue} ${operator_(
|
|
356
|
+
statement.operator,
|
|
357
|
+
this.builder,
|
|
358
|
+
this.client,
|
|
359
|
+
this.bindingsHolder
|
|
360
|
+
)} ${this._jsonValueClause(statement)}`;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
whereJsonSupersetOf(statement) {
|
|
364
|
+
return this._not(
|
|
365
|
+
statement,
|
|
366
|
+
`${wrap_(
|
|
367
|
+
statement.column,
|
|
368
|
+
undefined,
|
|
369
|
+
this.builder,
|
|
370
|
+
this.client,
|
|
371
|
+
this.bindingsHolder
|
|
372
|
+
)} @> ${this._jsonValueClause(statement)}`
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
whereJsonSubsetOf(statement) {
|
|
377
|
+
return this._not(
|
|
378
|
+
statement,
|
|
379
|
+
`${columnize_(
|
|
380
|
+
statement.column,
|
|
381
|
+
this.builder,
|
|
382
|
+
this.client,
|
|
383
|
+
this.bindingsHolder
|
|
384
|
+
)} <@ ${this._jsonValueClause(statement)}`
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
onJsonPathEquals(clause) {
|
|
389
|
+
return this._onJsonPathEquals('jsonb_path_query_first', clause);
|
|
390
|
+
}
|
|
230
391
|
}
|
|
231
392
|
|
|
232
393
|
module.exports = QueryCompiler_PG;
|
|
@@ -10,6 +10,7 @@ class ColumnCompiler_PG extends ColumnCompiler {
|
|
|
10
10
|
constructor(client, tableCompiler, columnBuilder) {
|
|
11
11
|
super(client, tableCompiler, columnBuilder);
|
|
12
12
|
this.modifiers = ['nullable', 'defaultTo', 'comment'];
|
|
13
|
+
this._addCheckModifiers();
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
// Types
|
|
@@ -64,6 +65,15 @@ class ColumnCompiler_PG extends ColumnCompiler {
|
|
|
64
65
|
return jsonColumn(this.client, true);
|
|
65
66
|
}
|
|
66
67
|
|
|
68
|
+
checkRegex(regex, constraintName) {
|
|
69
|
+
return this._check(
|
|
70
|
+
`${this.formatter.wrap(
|
|
71
|
+
this.getColumnName()
|
|
72
|
+
)} ~ ${this.client._escapeBinding(regex)}`,
|
|
73
|
+
constraintName
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
67
77
|
datetime(withoutTz = false, precision) {
|
|
68
78
|
let useTz;
|
|
69
79
|
if (isObject(withoutTz)) {
|
|
@@ -100,12 +110,22 @@ class ColumnCompiler_PG extends ColumnCompiler {
|
|
|
100
110
|
);
|
|
101
111
|
}, comment);
|
|
102
112
|
}
|
|
113
|
+
|
|
114
|
+
increments(options = { primaryKey: true }) {
|
|
115
|
+
return (
|
|
116
|
+
'serial' +
|
|
117
|
+
(this.tableCompiler._canBeAddPrimaryKey(options) ? ' primary key' : '')
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
bigincrements(options = { primaryKey: true }) {
|
|
122
|
+
return (
|
|
123
|
+
'bigserial' +
|
|
124
|
+
(this.tableCompiler._canBeAddPrimaryKey(options) ? ' primary key' : '')
|
|
125
|
+
);
|
|
126
|
+
}
|
|
103
127
|
}
|
|
104
128
|
|
|
105
|
-
ColumnCompiler_PG.prototype.bigincrements = ({ primaryKey = true } = {}) =>
|
|
106
|
-
'bigserial' + (primaryKey ? ' primary key' : '');
|
|
107
|
-
ColumnCompiler_PG.prototype.increments = ({ primaryKey = true } = {}) =>
|
|
108
|
-
'serial' + (primaryKey ? ' primary key' : '');
|
|
109
129
|
ColumnCompiler_PG.prototype.bigint = 'bigint';
|
|
110
130
|
ColumnCompiler_PG.prototype.binary = 'bytea';
|
|
111
131
|
ColumnCompiler_PG.prototype.bool = 'boolean';
|