knex 0.95.14 → 1.0.2
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 +90 -1
- 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 +92 -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-compiler.js +3 -4
- package/lib/dialects/mssql/schema/mssql-tablecompiler.js +24 -9
- package/lib/dialects/mssql/schema/mssql-viewcompiler.js +15 -1
- package/lib/dialects/mysql/query/mysql-querycompiler.js +93 -5
- package/lib/dialects/mysql/schema/mysql-columncompiler.js +32 -5
- package/lib/dialects/mysql/schema/mysql-tablecompiler.js +33 -6
- 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 +89 -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 +38 -0
- package/lib/dialects/postgres/query/pg-querycompiler.js +172 -9
- package/lib/dialects/postgres/schema/pg-columncompiler.js +24 -4
- package/lib/dialects/postgres/schema/pg-tablecompiler.js +63 -46
- 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 +23 -4
- package/lib/dialects/sqlite3/query/sqlite-querybuilder.js +33 -0
- package/lib/dialects/sqlite3/query/sqlite-querycompiler.js +87 -22
- 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 +36 -0
- package/lib/migrations/common/MigrationsLoader.js +36 -0
- package/lib/migrations/migrate/MigrationGenerator.js +1 -1
- package/lib/migrations/migrate/Migrator.js +22 -24
- 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 +292 -53
- package/lib/query/querycompiler.js +309 -85
- package/lib/schema/columnbuilder.js +14 -1
- 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 +61 -4
- package/lib/schema/viewcompiler.js +13 -10
- package/package.json +37 -27
- 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 +133 -21
|
@@ -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';
|
|
@@ -44,12 +44,16 @@ class TableCompiler_PG extends TableCompiler {
|
|
|
44
44
|
const createStatement = ifNot
|
|
45
45
|
? 'create table if not exists '
|
|
46
46
|
: 'create table ';
|
|
47
|
-
const columnsSql = ' (' + columns.sql.join(', ') + ')';
|
|
47
|
+
const columnsSql = ' (' + columns.sql.join(', ') + this._addChecks() + ')';
|
|
48
48
|
let sql =
|
|
49
49
|
createStatement +
|
|
50
50
|
this.tableName() +
|
|
51
51
|
(like && this.tableNameLike()
|
|
52
|
-
? ' (like ' +
|
|
52
|
+
? ' (like ' +
|
|
53
|
+
this.tableNameLike() +
|
|
54
|
+
' including all' +
|
|
55
|
+
(columns.sql.length ? ', ' + columns.sql.join(', ') : '') +
|
|
56
|
+
')'
|
|
53
57
|
: columnsSql);
|
|
54
58
|
if (this.single.inherits)
|
|
55
59
|
sql += ` inherits (${this.formatter.wrap(this.single.inherits)})`;
|
|
@@ -65,55 +69,68 @@ class TableCompiler_PG extends TableCompiler {
|
|
|
65
69
|
if (prefix === this.alterColumnsPrefix) {
|
|
66
70
|
// alter columns
|
|
67
71
|
for (const col of colCompilers) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
col.getColumnName(),
|
|
76
|
-
col.columnBuilder.queryContext()
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
// To alter enum columns they must be cast to text first
|
|
80
|
-
const isEnum = col.type === 'enu';
|
|
72
|
+
this._addColumn(col);
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
// base class implementation for normal add
|
|
76
|
+
super.addColumns(columns, prefix);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
81
79
|
|
|
80
|
+
_addColumn(col) {
|
|
81
|
+
const quotedTableName = this.tableName();
|
|
82
|
+
const type = col.getColumnType();
|
|
83
|
+
// We'd prefer to call this.formatter.wrapAsIdentifier here instead, however the context passed to
|
|
84
|
+
// `this` instance is not that of the column, but of the table. Thus, we unfortunately have to call
|
|
85
|
+
// `wrapIdentifier` here as well (it is already called once on the initial column operation) to give
|
|
86
|
+
// our `alter` operation the correct `queryContext`. Refer to issue #2606 and PR #2612.
|
|
87
|
+
const colName = this.client.wrapIdentifier(
|
|
88
|
+
col.getColumnName(),
|
|
89
|
+
col.columnBuilder.queryContext()
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
// To alter enum columns they must be cast to text first
|
|
93
|
+
const isEnum = col.type === 'enu';
|
|
94
|
+
this.pushQuery({
|
|
95
|
+
sql: `alter table ${quotedTableName} alter column ${colName} drop default`,
|
|
96
|
+
bindings: [],
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const alterNullable = col.columnBuilder.alterNullable;
|
|
100
|
+
if (alterNullable) {
|
|
101
|
+
this.pushQuery({
|
|
102
|
+
sql: `alter table ${quotedTableName} alter column ${colName} drop not null`,
|
|
103
|
+
bindings: [],
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const alterType = col.columnBuilder.alterType;
|
|
108
|
+
if (alterType) {
|
|
109
|
+
this.pushQuery({
|
|
110
|
+
sql: `alter table ${quotedTableName} alter column ${colName} type ${type} using (${colName}${
|
|
111
|
+
isEnum ? '::text::' : '::'
|
|
112
|
+
}${type})`,
|
|
113
|
+
bindings: [],
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const defaultTo = col.modified['defaultTo'];
|
|
118
|
+
if (defaultTo) {
|
|
119
|
+
const modifier = col.defaultTo.apply(col, defaultTo);
|
|
120
|
+
this.pushQuery({
|
|
121
|
+
sql: `alter table ${quotedTableName} alter column ${colName} set ${modifier}`,
|
|
122
|
+
bindings: [],
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (alterNullable) {
|
|
127
|
+
const nullable = col.modified['nullable'];
|
|
128
|
+
if (nullable && nullable[0] === false) {
|
|
82
129
|
this.pushQuery({
|
|
83
|
-
sql: `alter table ${quotedTableName} alter column ${colName}
|
|
84
|
-
bindings: [],
|
|
85
|
-
});
|
|
86
|
-
this.pushQuery({
|
|
87
|
-
sql: `alter table ${quotedTableName} alter column ${colName} drop not null`,
|
|
88
|
-
bindings: [],
|
|
89
|
-
});
|
|
90
|
-
this.pushQuery({
|
|
91
|
-
sql: `alter table ${quotedTableName} alter column ${colName} type ${type} using (${colName}${
|
|
92
|
-
isEnum ? '::text::' : '::'
|
|
93
|
-
}${type})`,
|
|
130
|
+
sql: `alter table ${quotedTableName} alter column ${colName} set not null`,
|
|
94
131
|
bindings: [],
|
|
95
132
|
});
|
|
96
|
-
|
|
97
|
-
const defaultTo = col.modified['defaultTo'];
|
|
98
|
-
if (defaultTo) {
|
|
99
|
-
const modifier = col.defaultTo.apply(col, defaultTo);
|
|
100
|
-
this.pushQuery({
|
|
101
|
-
sql: `alter table ${quotedTableName} alter column ${colName} set ${modifier}`,
|
|
102
|
-
bindings: [],
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const nullable = col.modified['nullable'];
|
|
107
|
-
if (nullable && nullable[0] === false) {
|
|
108
|
-
this.pushQuery({
|
|
109
|
-
sql: `alter table ${quotedTableName} alter column ${colName} set not null`,
|
|
110
|
-
bindings: [],
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
133
|
}
|
|
114
|
-
} else {
|
|
115
|
-
// base class implementation for normal add
|
|
116
|
-
super.addColumns(columns, prefix);
|
|
117
134
|
}
|
|
118
135
|
}
|
|
119
136
|
|
|
@@ -63,6 +63,18 @@ class Client_Redshift extends Client_PG {
|
|
|
63
63
|
}
|
|
64
64
|
return resp;
|
|
65
65
|
}
|
|
66
|
+
|
|
67
|
+
toPathForJson(jsonPath, builder, bindingsHolder) {
|
|
68
|
+
return jsonPath
|
|
69
|
+
.replace(/^(\$\.)/, '') // remove the first dollar
|
|
70
|
+
.split('.')
|
|
71
|
+
.map(
|
|
72
|
+
function (v) {
|
|
73
|
+
return this.parameter(v, builder, bindingsHolder);
|
|
74
|
+
}.bind(this)
|
|
75
|
+
)
|
|
76
|
+
.join(', ');
|
|
77
|
+
}
|
|
66
78
|
}
|
|
67
79
|
|
|
68
80
|
Object.assign(Client_Redshift.prototype, {
|
|
@@ -4,7 +4,9 @@ const QueryCompiler = require('../../../query/querycompiler');
|
|
|
4
4
|
const QueryCompiler_PG = require('../../postgres/query/pg-querycompiler');
|
|
5
5
|
|
|
6
6
|
const identity = require('lodash/identity');
|
|
7
|
-
const
|
|
7
|
+
const {
|
|
8
|
+
columnize: columnize_,
|
|
9
|
+
} = require('../../../formatter/wrappingFormatter');
|
|
8
10
|
|
|
9
11
|
class QueryCompiler_Redshift extends QueryCompiler_PG {
|
|
10
12
|
truncate() {
|
|
@@ -87,40 +89,74 @@ class QueryCompiler_Redshift extends QueryCompiler_PG {
|
|
|
87
89
|
schema = this.client.customWrapIdentifier(schema, identity);
|
|
88
90
|
}
|
|
89
91
|
|
|
90
|
-
|
|
92
|
+
const sql =
|
|
91
93
|
'select * from information_schema.columns where table_name = ? and table_catalog = ?';
|
|
92
94
|
const bindings = [
|
|
93
95
|
table.toLowerCase(),
|
|
94
96
|
this.client.database().toLowerCase(),
|
|
95
97
|
];
|
|
96
98
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
return this._buildColumnInfoQuery(schema, sql, bindings, column);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
jsonExtract(params) {
|
|
103
|
+
let extractions;
|
|
104
|
+
if (Array.isArray(params.column)) {
|
|
105
|
+
extractions = params.column;
|
|
100
106
|
} else {
|
|
101
|
-
|
|
107
|
+
extractions = [params];
|
|
102
108
|
}
|
|
109
|
+
return extractions
|
|
110
|
+
.map((extraction) => {
|
|
111
|
+
const jsonCol = `json_extract_path_text(${columnize_(
|
|
112
|
+
extraction.column || extraction[0],
|
|
113
|
+
this.builder,
|
|
114
|
+
this.client,
|
|
115
|
+
this.bindingsHolder
|
|
116
|
+
)}, ${this.client.toPathForJson(
|
|
117
|
+
params.path || extraction[1],
|
|
118
|
+
this.builder,
|
|
119
|
+
this.bindingsHolder
|
|
120
|
+
)})`;
|
|
121
|
+
const alias = extraction.alias || extraction[2];
|
|
122
|
+
return alias
|
|
123
|
+
? this.client.alias(jsonCol, this.formatter.wrap(alias))
|
|
124
|
+
: jsonCol;
|
|
125
|
+
})
|
|
126
|
+
.join(', ');
|
|
127
|
+
}
|
|
103
128
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
129
|
+
jsonSet(params) {
|
|
130
|
+
throw new Error('Json set is not supported by Redshift');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
jsonInsert(params) {
|
|
134
|
+
throw new Error('Json insert is not supported by Redshift');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
jsonRemove(params) {
|
|
138
|
+
throw new Error('Json remove is not supported by Redshift');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
whereJsonPath(statement) {
|
|
142
|
+
return this._whereJsonPath(
|
|
143
|
+
'json_extract_path_text',
|
|
144
|
+
Object.assign({}, statement, {
|
|
145
|
+
path: this.client.toPathForJson(statement.path),
|
|
146
|
+
})
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
whereJsonSupersetOf(statement) {
|
|
151
|
+
throw new Error('Json superset is not supported by Redshift');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
whereJsonSubsetOf(statement) {
|
|
155
|
+
throw new Error('Json subset is not supported by Redshift');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
onJsonPathEquals(clause) {
|
|
159
|
+
return this._onJsonPathEquals('json_extract_path_text', clause);
|
|
124
160
|
}
|
|
125
161
|
}
|
|
126
162
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// -------
|
|
3
3
|
|
|
4
4
|
const ColumnCompiler_PG = require('../../postgres/schema/pg-columncompiler');
|
|
5
|
+
const ColumnCompiler = require('../../../schema/columncompiler');
|
|
5
6
|
|
|
6
7
|
class ColumnCompiler_Redshift extends ColumnCompiler_PG {
|
|
7
8
|
constructor() {
|
|
@@ -54,7 +55,7 @@ ColumnCompiler_Redshift.prototype.mediumblob = 'varchar(16777218)';
|
|
|
54
55
|
ColumnCompiler_Redshift.prototype.set = 'text';
|
|
55
56
|
ColumnCompiler_Redshift.prototype.text = 'varchar(max)';
|
|
56
57
|
ColumnCompiler_Redshift.prototype.tinyblob = 'varchar(256)';
|
|
57
|
-
ColumnCompiler_Redshift.prototype.uuid =
|
|
58
|
+
ColumnCompiler_Redshift.prototype.uuid = ColumnCompiler.prototype.uuid;
|
|
58
59
|
ColumnCompiler_Redshift.prototype.varbinary = 'varchar(max)';
|
|
59
60
|
ColumnCompiler_Redshift.prototype.bigint = 'bigint';
|
|
60
61
|
ColumnCompiler_Redshift.prototype.bool = 'boolean';
|
|
@@ -30,7 +30,7 @@ class TableCompiler_Redshift extends TableCompiler_PG {
|
|
|
30
30
|
const createStatement = ifNot
|
|
31
31
|
? 'create table if not exists '
|
|
32
32
|
: 'create table ';
|
|
33
|
-
const columnsSql = ' (' + columns.sql.join(', ') + ')';
|
|
33
|
+
const columnsSql = ' (' + columns.sql.join(', ') + this._addChecks() + ')';
|
|
34
34
|
let sql =
|
|
35
35
|
createStatement +
|
|
36
36
|
this.tableName() +
|
|
@@ -45,6 +45,9 @@ class TableCompiler_Redshift extends TableCompiler_PG {
|
|
|
45
45
|
});
|
|
46
46
|
const hasComment = has(this.single, 'comment');
|
|
47
47
|
if (hasComment) this.comment(this.single.comment);
|
|
48
|
+
if (like) {
|
|
49
|
+
this.addColumns(columns, this.addColumnsPrefix);
|
|
50
|
+
}
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
primary(columns, constraintName) {
|
|
@@ -15,6 +15,7 @@ const TableCompiler = require('./schema/sqlite-tablecompiler');
|
|
|
15
15
|
const ViewCompiler = require('./schema/sqlite-viewcompiler');
|
|
16
16
|
const SQLite3_DDL = require('./schema/ddl');
|
|
17
17
|
const Formatter = require('../../formatter');
|
|
18
|
+
const QueryBuilder = require('./query/sqlite-querybuilder');
|
|
18
19
|
|
|
19
20
|
class Client_SQLite3 extends Client {
|
|
20
21
|
constructor(config) {
|
|
@@ -29,7 +30,7 @@ class Client_SQLite3 extends Client {
|
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
_driver() {
|
|
32
|
-
return require('sqlite3');
|
|
33
|
+
return require('@vscode/sqlite3');
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
schemaCompiler() {
|
|
@@ -44,6 +45,10 @@ class Client_SQLite3 extends Client {
|
|
|
44
45
|
return new SqliteQueryCompiler(this, builder, formatter);
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
queryBuilder() {
|
|
49
|
+
return new QueryBuilder(this);
|
|
50
|
+
}
|
|
51
|
+
|
|
47
52
|
viewCompiler(builder, formatter) {
|
|
48
53
|
return new ViewCompiler(this, builder, formatter);
|
|
49
54
|
}
|
|
@@ -132,6 +137,7 @@ class Client_SQLite3 extends Client {
|
|
|
132
137
|
// We need the context here, as it contains
|
|
133
138
|
// the "this.lastID" or "this.changes"
|
|
134
139
|
obj.context = this;
|
|
140
|
+
|
|
135
141
|
return resolver(obj);
|
|
136
142
|
});
|
|
137
143
|
});
|
|
@@ -144,6 +150,7 @@ class Client_SQLite3 extends Client {
|
|
|
144
150
|
return new Promise(function (resolver, rejecter) {
|
|
145
151
|
stream.on('error', rejecter);
|
|
146
152
|
stream.on('end', resolver);
|
|
153
|
+
|
|
147
154
|
return client
|
|
148
155
|
._query(connection, obj)
|
|
149
156
|
.then((obj) => obj.response)
|
|
@@ -160,7 +167,7 @@ class Client_SQLite3 extends Client {
|
|
|
160
167
|
// Ensures the response is returned in the same format as other clients.
|
|
161
168
|
processResponse(obj, runner) {
|
|
162
169
|
const ctx = obj.context;
|
|
163
|
-
const { response } = obj;
|
|
170
|
+
const { response, returning } = obj;
|
|
164
171
|
if (obj.output) return obj.output.call(runner, response);
|
|
165
172
|
switch (obj.method) {
|
|
166
173
|
case 'select':
|
|
@@ -169,14 +176,26 @@ class Client_SQLite3 extends Client {
|
|
|
169
176
|
return response[0];
|
|
170
177
|
case 'pluck':
|
|
171
178
|
return map(response, obj.pluck);
|
|
172
|
-
case 'insert':
|
|
179
|
+
case 'insert': {
|
|
180
|
+
if (returning) {
|
|
181
|
+
if (response) {
|
|
182
|
+
return response;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ToDo Implement after https://github.com/microsoft/vscode-node-sqlite3/issues/15 is resolved
|
|
186
|
+
this.logger.warn(
|
|
187
|
+
'node-sqlite3 does not currently support RETURNING clause'
|
|
188
|
+
);
|
|
189
|
+
}
|
|
173
190
|
return [ctx.lastID];
|
|
191
|
+
}
|
|
174
192
|
case 'del':
|
|
175
193
|
case 'update':
|
|
176
194
|
case 'counter':
|
|
177
195
|
return ctx.changes;
|
|
178
|
-
default:
|
|
196
|
+
default: {
|
|
179
197
|
return response;
|
|
198
|
+
}
|
|
180
199
|
}
|
|
181
200
|
}
|
|
182
201
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const QueryBuilder = require('../../../query/querybuilder.js');
|
|
2
|
+
|
|
3
|
+
module.exports = class QueryBuilder_SQLite3 extends QueryBuilder {
|
|
4
|
+
withMaterialized(alias, statementOrColumnList, nothingOrStatement) {
|
|
5
|
+
this._validateWithArgs(
|
|
6
|
+
alias,
|
|
7
|
+
statementOrColumnList,
|
|
8
|
+
nothingOrStatement,
|
|
9
|
+
'with'
|
|
10
|
+
);
|
|
11
|
+
return this.withWrapped(
|
|
12
|
+
alias,
|
|
13
|
+
statementOrColumnList,
|
|
14
|
+
nothingOrStatement,
|
|
15
|
+
true
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
withNotMaterialized(alias, statementOrColumnList, nothingOrStatement) {
|
|
20
|
+
this._validateWithArgs(
|
|
21
|
+
alias,
|
|
22
|
+
statementOrColumnList,
|
|
23
|
+
nothingOrStatement,
|
|
24
|
+
'with'
|
|
25
|
+
);
|
|
26
|
+
return this.withWrapped(
|
|
27
|
+
alias,
|
|
28
|
+
statementOrColumnList,
|
|
29
|
+
nothingOrStatement,
|
|
30
|
+
false
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
@@ -9,7 +9,10 @@ const reduce = require('lodash/reduce');
|
|
|
9
9
|
const QueryCompiler = require('../../../query/querycompiler');
|
|
10
10
|
const noop = require('../../../util/noop');
|
|
11
11
|
const { isString } = require('../../../util/is');
|
|
12
|
-
const {
|
|
12
|
+
const {
|
|
13
|
+
wrapString,
|
|
14
|
+
columnize: columnize_,
|
|
15
|
+
} = require('../../../formatter/wrappingFormatter');
|
|
13
16
|
|
|
14
17
|
const emptyStr = constant('');
|
|
15
18
|
|
|
@@ -17,14 +20,6 @@ class QueryCompiler_SQLite3 extends QueryCompiler {
|
|
|
17
20
|
constructor(client, builder, formatter) {
|
|
18
21
|
super(client, builder, formatter);
|
|
19
22
|
|
|
20
|
-
const { returning } = this.single;
|
|
21
|
-
|
|
22
|
-
if (returning) {
|
|
23
|
-
this.client.logger.warn(
|
|
24
|
-
'.returning() is not supported by sqlite3 and will not have any effect.'
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
23
|
// The locks are not applicable in SQLite3
|
|
29
24
|
this.forShare = emptyStr;
|
|
30
25
|
this.forKeyShare = emptyStr;
|
|
@@ -47,20 +42,28 @@ class QueryCompiler_SQLite3 extends QueryCompiler {
|
|
|
47
42
|
insertValues[0] &&
|
|
48
43
|
isEmpty(insertValues[0])
|
|
49
44
|
) {
|
|
50
|
-
return
|
|
45
|
+
return {
|
|
46
|
+
sql: sql + this._emptyInsertValue,
|
|
47
|
+
};
|
|
51
48
|
}
|
|
52
49
|
} else if (typeof insertValues === 'object' && isEmpty(insertValues)) {
|
|
53
|
-
return
|
|
50
|
+
return {
|
|
51
|
+
sql: sql + this._emptyInsertValue,
|
|
52
|
+
};
|
|
54
53
|
}
|
|
55
54
|
|
|
56
55
|
const insertData = this._prepInsert(insertValues);
|
|
57
56
|
|
|
58
57
|
if (isString(insertData)) {
|
|
59
|
-
return
|
|
58
|
+
return {
|
|
59
|
+
sql: sql + insertData,
|
|
60
|
+
};
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
if (insertData.columns.length === 0) {
|
|
63
|
-
return
|
|
64
|
+
return {
|
|
65
|
+
sql: '',
|
|
66
|
+
};
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
sql += `(${this.formatter.columnize(insertData.columns)})`;
|
|
@@ -96,7 +99,15 @@ class QueryCompiler_SQLite3 extends QueryCompiler {
|
|
|
96
99
|
if (wheres) sql += ` ${wheres}`;
|
|
97
100
|
}
|
|
98
101
|
|
|
99
|
-
|
|
102
|
+
const { returning } = this.single;
|
|
103
|
+
if (returning) {
|
|
104
|
+
sql += this._returning(returning);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
sql,
|
|
109
|
+
returning,
|
|
110
|
+
};
|
|
100
111
|
}
|
|
101
112
|
|
|
102
113
|
const blocks = [];
|
|
@@ -129,20 +140,24 @@ class QueryCompiler_SQLite3 extends QueryCompiler {
|
|
|
129
140
|
' where true' + this._merge(merge.updates, onConflict, insertValues);
|
|
130
141
|
}
|
|
131
142
|
|
|
132
|
-
|
|
143
|
+
const { returning } = this.single;
|
|
144
|
+
if (returning) sql += this._returning(returning);
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
sql,
|
|
148
|
+
returning,
|
|
149
|
+
};
|
|
133
150
|
}
|
|
134
151
|
|
|
135
152
|
_ignore(columns) {
|
|
136
153
|
if (columns === true) {
|
|
137
154
|
return ' on conflict do nothing';
|
|
138
155
|
}
|
|
139
|
-
return ` on conflict
|
|
156
|
+
return ` on conflict ${this._onConflictClause(columns)} do nothing`;
|
|
140
157
|
}
|
|
141
158
|
|
|
142
159
|
_merge(updates, columns, insert) {
|
|
143
|
-
let sql = ` on conflict
|
|
144
|
-
columns
|
|
145
|
-
)}) do update set `;
|
|
160
|
+
let sql = ` on conflict ${this._onConflictClause(columns)} do update set `;
|
|
146
161
|
if (updates && Array.isArray(updates)) {
|
|
147
162
|
sql += updates
|
|
148
163
|
.map((column) =>
|
|
@@ -185,6 +200,10 @@ class QueryCompiler_SQLite3 extends QueryCompiler {
|
|
|
185
200
|
}
|
|
186
201
|
}
|
|
187
202
|
|
|
203
|
+
_returning(value) {
|
|
204
|
+
return value ? ` returning ${this.formatter.columnize(value)}` : '';
|
|
205
|
+
}
|
|
206
|
+
|
|
188
207
|
// Compile a truncate table statement into SQL.
|
|
189
208
|
truncate() {
|
|
190
209
|
const { table } = this.single;
|
|
@@ -241,11 +260,57 @@ class QueryCompiler_SQLite3 extends QueryCompiler {
|
|
|
241
260
|
|
|
242
261
|
// Workaround for offset only,
|
|
243
262
|
// see http://stackoverflow.com/questions/10491492/sqllite-with-skip-offset-only-not-limit
|
|
244
|
-
|
|
245
|
-
|
|
263
|
+
this.single.limit = noLimit ? -1 : this.single.limit;
|
|
264
|
+
return `limit ${this._getValueOrParameterFromAttribute('limit')}`;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Json functions
|
|
268
|
+
jsonExtract(params) {
|
|
269
|
+
return this._jsonExtract('json_extract', params);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
jsonSet(params) {
|
|
273
|
+
return this._jsonSet('json_set', params);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
jsonInsert(params) {
|
|
277
|
+
return this._jsonSet('json_insert', params);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
jsonRemove(params) {
|
|
281
|
+
const jsonCol = `json_remove(${columnize_(
|
|
282
|
+
params.column,
|
|
283
|
+
this.builder,
|
|
284
|
+
this.client,
|
|
285
|
+
this.bindingsHolder
|
|
286
|
+
)},${this.client.parameter(
|
|
287
|
+
params.path,
|
|
246
288
|
this.builder,
|
|
247
289
|
this.bindingsHolder
|
|
248
|
-
)}`;
|
|
290
|
+
)})`;
|
|
291
|
+
return params.alias
|
|
292
|
+
? this.client.alias(jsonCol, this.formatter.wrap(params.alias))
|
|
293
|
+
: jsonCol;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
whereJsonPath(statement) {
|
|
297
|
+
return this._whereJsonPath('json_extract', statement);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
whereJsonSupersetOf(statement) {
|
|
301
|
+
throw new Error(
|
|
302
|
+
'Json superset where clause not actually supported by SQLite'
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
whereJsonSubsetOf(statement) {
|
|
307
|
+
throw new Error(
|
|
308
|
+
'Json subset where clause not actually supported by SQLite'
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
onJsonPathEquals(clause) {
|
|
313
|
+
return this._onJsonPathEquals('json_extract', clause);
|
|
249
314
|
}
|
|
250
315
|
}
|
|
251
316
|
|