knex 2.3.0 → 2.4.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 +25 -0
- package/CONTRIBUTING.md +194 -194
- package/LICENSE +22 -22
- package/README.md +148 -148
- package/UPGRADING.md +233 -233
- package/bin/cli.js +472 -472
- package/bin/utils/cli-config-utils.js +210 -210
- package/bin/utils/constants.js +7 -7
- package/bin/utils/migrationsLister.js +37 -37
- package/knex.js +23 -23
- package/lib/builder-interface-augmenter.js +120 -120
- package/lib/client.js +475 -470
- package/lib/constants.js +61 -61
- package/lib/dialects/better-sqlite3/index.js +72 -72
- package/lib/dialects/cockroachdb/crdb-columncompiler.js +14 -14
- package/lib/dialects/cockroachdb/crdb-querybuilder.js +11 -11
- package/lib/dialects/cockroachdb/crdb-querycompiler.js +122 -122
- package/lib/dialects/cockroachdb/crdb-tablecompiler.js +37 -37
- package/lib/dialects/cockroachdb/crdb-viewcompiler.js +15 -15
- package/lib/dialects/cockroachdb/index.js +86 -86
- package/lib/dialects/mssql/index.js +495 -495
- package/lib/dialects/mssql/mssql-formatter.js +34 -34
- package/lib/dialects/mssql/query/mssql-querycompiler.js +600 -600
- package/lib/dialects/mssql/schema/mssql-columncompiler.js +185 -185
- package/lib/dialects/mssql/schema/mssql-compiler.js +91 -91
- package/lib/dialects/mssql/schema/mssql-tablecompiler.js +378 -372
- package/lib/dialects/mssql/schema/mssql-viewcompiler.js +55 -55
- package/lib/dialects/mssql/transaction.js +176 -176
- package/lib/dialects/mysql/index.js +201 -201
- package/lib/dialects/mysql/query/mysql-querycompiler.js +274 -248
- package/lib/dialects/mysql/schema/mysql-columncompiler.js +193 -193
- package/lib/dialects/mysql/schema/mysql-compiler.js +60 -60
- package/lib/dialects/mysql/schema/mysql-tablecompiler.js +381 -381
- package/lib/dialects/mysql/schema/mysql-viewbuilder.js +21 -21
- package/lib/dialects/mysql/schema/mysql-viewcompiler.js +15 -15
- package/lib/dialects/mysql/transaction.js +46 -46
- package/lib/dialects/mysql2/index.js +33 -33
- package/lib/dialects/mysql2/transaction.js +44 -44
- package/lib/dialects/oracle/DEAD_CODE.md +5 -5
- package/lib/dialects/oracle/index.js +92 -92
- package/lib/dialects/oracle/query/oracle-querycompiler.js +342 -342
- package/lib/dialects/oracle/schema/internal/incrementUtils.js +20 -20
- package/lib/dialects/oracle/schema/internal/trigger.js +135 -135
- package/lib/dialects/oracle/schema/oracle-columnbuilder.js +17 -17
- package/lib/dialects/oracle/schema/oracle-columncompiler.js +126 -126
- package/lib/dialects/oracle/schema/oracle-compiler.js +122 -122
- package/lib/dialects/oracle/schema/oracle-tablecompiler.js +190 -190
- package/lib/dialects/oracle/utils.js +87 -87
- package/lib/dialects/oracledb/index.js +327 -327
- package/lib/dialects/oracledb/query/oracledb-querycompiler.js +481 -481
- package/lib/dialects/oracledb/schema/oracledb-columncompiler.js +55 -55
- package/lib/dialects/oracledb/schema/oracledb-tablecompiler.js +19 -19
- package/lib/dialects/oracledb/schema/oracledb-viewbuilder.js +13 -13
- package/lib/dialects/oracledb/schema/oracledb-viewcompiler.js +19 -19
- package/lib/dialects/oracledb/transaction.js +98 -98
- package/lib/dialects/oracledb/utils.js +208 -208
- package/lib/dialects/pgnative/index.js +60 -60
- package/lib/dialects/postgres/execution/pg-transaction.js +12 -12
- package/lib/dialects/postgres/index.js +358 -358
- package/lib/dialects/postgres/query/pg-querybuilder.js +38 -38
- package/lib/dialects/postgres/query/pg-querycompiler.js +395 -395
- package/lib/dialects/postgres/schema/pg-columncompiler.js +156 -156
- package/lib/dialects/postgres/schema/pg-compiler.js +136 -136
- package/lib/dialects/postgres/schema/pg-tablecompiler.js +299 -275
- package/lib/dialects/postgres/schema/pg-viewbuilder.js +21 -21
- package/lib/dialects/postgres/schema/pg-viewcompiler.js +35 -35
- package/lib/dialects/redshift/index.js +86 -86
- package/lib/dialects/redshift/query/redshift-querycompiler.js +163 -163
- package/lib/dialects/redshift/schema/redshift-columnbuilder.js +22 -22
- package/lib/dialects/redshift/schema/redshift-columncompiler.js +67 -67
- package/lib/dialects/redshift/schema/redshift-compiler.js +14 -14
- package/lib/dialects/redshift/schema/redshift-tablecompiler.js +122 -122
- package/lib/dialects/redshift/schema/redshift-viewcompiler.js +11 -11
- package/lib/dialects/redshift/transaction.js +25 -25
- package/lib/dialects/sqlite3/execution/sqlite-transaction.js +18 -18
- package/lib/dialects/sqlite3/index.js +250 -250
- package/lib/dialects/sqlite3/query/sqlite-querybuilder.js +33 -33
- package/lib/dialects/sqlite3/query/sqlite-querycompiler.js +334 -334
- package/lib/dialects/sqlite3/schema/ddl.js +400 -400
- package/lib/dialects/sqlite3/schema/internal/compiler.js +327 -327
- package/lib/dialects/sqlite3/schema/internal/parser-combinator.js +161 -161
- package/lib/dialects/sqlite3/schema/internal/parser.js +638 -638
- package/lib/dialects/sqlite3/schema/internal/sqlite-ddl-operations.js +41 -41
- package/lib/dialects/sqlite3/schema/internal/tokenizer.js +38 -38
- package/lib/dialects/sqlite3/schema/internal/utils.js +12 -12
- package/lib/dialects/sqlite3/schema/sqlite-columncompiler.js +50 -50
- package/lib/dialects/sqlite3/schema/sqlite-compiler.js +80 -80
- package/lib/dialects/sqlite3/schema/sqlite-tablecompiler.js +347 -341
- package/lib/dialects/sqlite3/schema/sqlite-viewcompiler.js +40 -40
- package/lib/execution/batch-insert.js +51 -51
- package/lib/execution/internal/delay.js +6 -6
- package/lib/execution/internal/ensure-connection-callback.js +41 -41
- package/lib/execution/internal/query-executioner.js +62 -58
- package/lib/execution/runner.js +307 -307
- package/lib/execution/transaction.js +401 -401
- package/lib/formatter/formatterUtils.js +42 -42
- package/lib/formatter/rawFormatter.js +84 -84
- package/lib/formatter/wrappingFormatter.js +250 -250
- package/lib/formatter.js +25 -25
- package/lib/index.js +3 -3
- package/lib/knex-builder/FunctionHelper.js +54 -54
- package/lib/knex-builder/Knex.js +59 -59
- package/lib/knex-builder/internal/config-resolver.js +57 -57
- package/lib/knex-builder/internal/parse-connection.js +87 -87
- package/lib/knex-builder/make-knex.js +340 -340
- package/lib/logger.js +76 -76
- package/lib/migrations/common/MigrationsLoader.js +36 -36
- package/lib/migrations/migrate/MigrationGenerator.js +82 -82
- package/lib/migrations/migrate/Migrator.js +598 -598
- package/lib/migrations/migrate/migrate-stub.js +17 -17
- package/lib/migrations/migrate/migration-list-resolver.js +33 -33
- package/lib/migrations/migrate/migrator-configuration-merger.js +58 -58
- package/lib/migrations/migrate/sources/fs-migrations.js +74 -74
- package/lib/migrations/migrate/stub/cjs.stub +15 -15
- package/lib/migrations/migrate/stub/coffee.stub +13 -13
- package/lib/migrations/migrate/stub/eg.stub +14 -14
- package/lib/migrations/migrate/stub/js-schema.stub +22 -22
- package/lib/migrations/migrate/stub/js.stub +22 -22
- package/lib/migrations/migrate/stub/knexfile-coffee.stub +34 -34
- package/lib/migrations/migrate/stub/knexfile-eg.stub +43 -43
- package/lib/migrations/migrate/stub/knexfile-js.stub +47 -47
- package/lib/migrations/migrate/stub/knexfile-ls.stub +35 -35
- package/lib/migrations/migrate/stub/knexfile-ts.stub +47 -47
- package/lib/migrations/migrate/stub/ls.stub +14 -14
- package/lib/migrations/migrate/stub/mjs.stub +23 -15
- package/lib/migrations/migrate/stub/ts-schema.stub +21 -21
- package/lib/migrations/migrate/stub/ts.stub +21 -21
- package/lib/migrations/migrate/table-creator.js +77 -77
- package/lib/migrations/migrate/table-resolver.js +27 -27
- package/lib/migrations/seed/Seeder.js +137 -137
- package/lib/migrations/seed/seed-stub.js +13 -13
- package/lib/migrations/seed/seeder-configuration-merger.js +60 -60
- package/lib/migrations/seed/sources/fs-seeds.js +65 -65
- package/lib/migrations/seed/stub/coffee.stub +9 -9
- package/lib/migrations/seed/stub/eg.stub +11 -11
- package/lib/migrations/seed/stub/js.stub +13 -13
- package/lib/migrations/seed/stub/ls.stub +11 -11
- package/lib/migrations/seed/stub/mjs.stub +12 -12
- package/lib/migrations/seed/stub/ts.stub +13 -13
- package/lib/migrations/util/fs.js +86 -86
- package/lib/migrations/util/import-file.js +12 -12
- package/lib/migrations/util/is-module-type.js +9 -9
- package/lib/migrations/util/template.js +52 -52
- package/lib/migrations/util/timestamp.js +14 -14
- package/lib/query/analytic.js +52 -52
- package/lib/query/constants.js +15 -15
- package/lib/query/joinclause.js +270 -270
- package/lib/query/method-constants.js +135 -135
- package/lib/query/querybuilder.js +1794 -1800
- package/lib/query/querycompiler.js +1580 -1580
- package/lib/raw.js +139 -139
- package/lib/ref.js +39 -39
- package/lib/schema/builder.js +114 -114
- package/lib/schema/columnbuilder.js +145 -145
- package/lib/schema/columncompiler.js +307 -307
- package/lib/schema/compiler.js +187 -187
- package/lib/schema/internal/helpers.js +55 -55
- package/lib/schema/tablebuilder.js +375 -375
- package/lib/schema/tablecompiler.js +433 -433
- package/lib/schema/viewbuilder.js +93 -93
- package/lib/schema/viewcompiler.js +138 -138
- package/lib/util/finally-mixin.js +13 -13
- package/lib/util/helpers.js +95 -95
- package/lib/util/is.js +32 -32
- package/lib/util/nanoid.js +40 -40
- package/lib/util/noop.js +1 -1
- package/lib/util/save-async-stack.js +14 -14
- package/lib/util/string.js +190 -190
- package/lib/util/timeout.js +29 -29
- package/package.json +4 -4
- package/scripts/build.js +125 -125
- package/scripts/clean.js +29 -29
- package/scripts/docker-compose.yml +152 -152
- package/scripts/next-release-howto.md +24 -24
- package/scripts/oracledb-install-driver-libs.sh +82 -82
- package/scripts/release.sh +34 -34
- package/scripts/runkit-example.js +34 -34
- package/scripts/stress-test/README.txt +18 -18
- package/scripts/stress-test/docker-compose.yml +57 -57
- package/scripts/stress-test/knex-stress-test.js +208 -208
- package/scripts/stress-test/mysql2-random-hanging-every-now-and-then.js +145 -145
- package/scripts/stress-test/mysql2-sudden-exit-without-error.js +100 -100
- package/scripts/stress-test/reconnect-test-mysql-based-drivers.js +184 -184
- package/scripts/update_gitignore_for_tsc_output.js +86 -85
- package/types/index.d.ts +3233 -3230
- package/types/result.d.ts +27 -27
- package/types/tables.d.ts +4 -4
|
@@ -1,327 +1,327 @@
|
|
|
1
|
-
// Oracledb Client
|
|
2
|
-
// -------
|
|
3
|
-
const each = require('lodash/each');
|
|
4
|
-
const flatten = require('lodash/flatten');
|
|
5
|
-
const isEmpty = require('lodash/isEmpty');
|
|
6
|
-
const map = require('lodash/map');
|
|
7
|
-
|
|
8
|
-
const Formatter = require('../../formatter');
|
|
9
|
-
const QueryCompiler = require('./query/oracledb-querycompiler');
|
|
10
|
-
const TableCompiler = require('./schema/oracledb-tablecompiler');
|
|
11
|
-
const ColumnCompiler = require('./schema/oracledb-columncompiler');
|
|
12
|
-
const {
|
|
13
|
-
BlobHelper,
|
|
14
|
-
ReturningHelper,
|
|
15
|
-
monkeyPatchConnection,
|
|
16
|
-
} = require('./utils');
|
|
17
|
-
const ViewCompiler = require('./schema/oracledb-viewcompiler');
|
|
18
|
-
const ViewBuilder = require('./schema/oracledb-viewbuilder');
|
|
19
|
-
const Transaction = require('./transaction');
|
|
20
|
-
const Client_Oracle = require('../oracle');
|
|
21
|
-
const { isString } = require('../../util/is');
|
|
22
|
-
const { outputQuery, unwrapRaw } = require('../../formatter/wrappingFormatter');
|
|
23
|
-
const { compileCallback } = require('../../formatter/formatterUtils');
|
|
24
|
-
|
|
25
|
-
class Client_Oracledb extends Client_Oracle {
|
|
26
|
-
constructor(config) {
|
|
27
|
-
super(config);
|
|
28
|
-
if (this.driver) {
|
|
29
|
-
process.env.UV_THREADPOOL_SIZE = process.env.UV_THREADPOOL_SIZE || 1;
|
|
30
|
-
process.env.UV_THREADPOOL_SIZE =
|
|
31
|
-
parseInt(process.env.UV_THREADPOOL_SIZE) + this.driver.poolMax;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
_driver() {
|
|
36
|
-
const client = this;
|
|
37
|
-
const oracledb = require('oracledb');
|
|
38
|
-
client.fetchAsString = [];
|
|
39
|
-
if (this.config.fetchAsString && Array.isArray(this.config.fetchAsString)) {
|
|
40
|
-
this.config.fetchAsString.forEach(function (type) {
|
|
41
|
-
if (!isString(type)) return;
|
|
42
|
-
type = type.toUpperCase();
|
|
43
|
-
if (oracledb[type]) {
|
|
44
|
-
if (
|
|
45
|
-
type !== 'NUMBER' &&
|
|
46
|
-
type !== 'DATE' &&
|
|
47
|
-
type !== 'CLOB' &&
|
|
48
|
-
type !== 'BUFFER'
|
|
49
|
-
) {
|
|
50
|
-
this.logger.warn(
|
|
51
|
-
'Only "date", "number", "clob" and "buffer" are supported for fetchAsString'
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
client.fetchAsString.push(oracledb[type]);
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
return oracledb;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
queryCompiler(builder, formatter) {
|
|
62
|
-
return new QueryCompiler(this, builder, formatter);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
tableCompiler() {
|
|
66
|
-
return new TableCompiler(this, ...arguments);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
columnCompiler() {
|
|
70
|
-
return new ColumnCompiler(this, ...arguments);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
viewBuilder() {
|
|
74
|
-
return new ViewBuilder(this, ...arguments);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
viewCompiler() {
|
|
78
|
-
return new ViewCompiler(this, ...arguments);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
formatter(builder) {
|
|
82
|
-
return new Formatter(this, builder);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
transaction() {
|
|
86
|
-
return new Transaction(this, ...arguments);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
prepBindings(bindings) {
|
|
90
|
-
return map(bindings, (value) => {
|
|
91
|
-
if (value instanceof BlobHelper && this.driver) {
|
|
92
|
-
return { type: this.driver.BLOB, dir: this.driver.BIND_OUT };
|
|
93
|
-
// Returning helper always use ROWID as string
|
|
94
|
-
} else if (value instanceof ReturningHelper && this.driver) {
|
|
95
|
-
return { type: this.driver.STRING, dir: this.driver.BIND_OUT };
|
|
96
|
-
} else if (typeof value === 'boolean') {
|
|
97
|
-
return value ? 1 : 0;
|
|
98
|
-
}
|
|
99
|
-
return value;
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Checks whether a value is a function... if it is, we compile it
|
|
104
|
-
// otherwise we check whether it's a raw
|
|
105
|
-
parameter(value, builder, formatter) {
|
|
106
|
-
if (typeof value === 'function') {
|
|
107
|
-
return outputQuery(
|
|
108
|
-
compileCallback(value, undefined, this, formatter),
|
|
109
|
-
true,
|
|
110
|
-
builder,
|
|
111
|
-
this
|
|
112
|
-
);
|
|
113
|
-
} else if (value instanceof BlobHelper) {
|
|
114
|
-
formatter.bindings.push(value.value);
|
|
115
|
-
return '?';
|
|
116
|
-
}
|
|
117
|
-
return unwrapRaw(value, true, builder, this, formatter) || '?';
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Get a raw connection, called by the `pool` whenever a new
|
|
121
|
-
// connection needs to be added to the pool.
|
|
122
|
-
acquireRawConnection() {
|
|
123
|
-
const client = this;
|
|
124
|
-
const asyncConnection = new Promise(function (resolver, rejecter) {
|
|
125
|
-
// If external authentication don't have to worry about username/password and
|
|
126
|
-
// if not need to set the username and password
|
|
127
|
-
const oracleDbConfig = client.connectionSettings.externalAuth
|
|
128
|
-
? { externalAuth: client.connectionSettings.externalAuth }
|
|
129
|
-
: {
|
|
130
|
-
user: client.connectionSettings.user,
|
|
131
|
-
password: client.connectionSettings.password,
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
// In the case of external authentication connection string will be given
|
|
135
|
-
oracleDbConfig.connectString = resolveConnectString(
|
|
136
|
-
client.connectionSettings
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
if (client.connectionSettings.prefetchRowCount) {
|
|
140
|
-
oracleDbConfig.prefetchRows =
|
|
141
|
-
client.connectionSettings.prefetchRowCount;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (client.connectionSettings.stmtCacheSize !== undefined) {
|
|
145
|
-
oracleDbConfig.stmtCacheSize = client.connectionSettings.stmtCacheSize;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
client.driver.fetchAsString = client.fetchAsString;
|
|
149
|
-
|
|
150
|
-
client.driver.getConnection(oracleDbConfig, function (err, connection) {
|
|
151
|
-
if (err) {
|
|
152
|
-
return rejecter(err);
|
|
153
|
-
}
|
|
154
|
-
monkeyPatchConnection(connection, client);
|
|
155
|
-
|
|
156
|
-
resolver(connection);
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
return asyncConnection;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Used to explicitly close a connection, called internally by the pool
|
|
163
|
-
// when a connection times out or the pool is shutdown.
|
|
164
|
-
destroyRawConnection(connection) {
|
|
165
|
-
return connection.release();
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Runs the query on the specified connection, providing the bindings
|
|
169
|
-
// and any other necessary prep work.
|
|
170
|
-
_query(connection, obj) {
|
|
171
|
-
if (!obj.sql) throw new Error('The query is empty');
|
|
172
|
-
|
|
173
|
-
const options = { autoCommit: false };
|
|
174
|
-
if (obj.method === 'select') {
|
|
175
|
-
options.resultSet = true;
|
|
176
|
-
}
|
|
177
|
-
return connection
|
|
178
|
-
.executeAsync(obj.sql, obj.bindings, options)
|
|
179
|
-
.then(async function (response) {
|
|
180
|
-
// Flatten outBinds
|
|
181
|
-
let outBinds = flatten(response.outBinds);
|
|
182
|
-
obj.response = response.rows || [];
|
|
183
|
-
obj.rowsAffected = response.rows
|
|
184
|
-
? response.rows.rowsAffected
|
|
185
|
-
: response.rowsAffected;
|
|
186
|
-
|
|
187
|
-
//added for outBind parameter
|
|
188
|
-
if (obj.method === 'raw' && outBinds.length > 0) {
|
|
189
|
-
return {
|
|
190
|
-
response: outBinds,
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
if (obj.method === 'update') {
|
|
195
|
-
const modifiedRowsCount = obj.rowsAffected.length || obj.rowsAffected;
|
|
196
|
-
const updatedObjOutBinding = [];
|
|
197
|
-
const updatedOutBinds = [];
|
|
198
|
-
const updateOutBinds = (i) =>
|
|
199
|
-
function (value, index) {
|
|
200
|
-
const OutBindsOffset = index * modifiedRowsCount;
|
|
201
|
-
updatedOutBinds.push(outBinds[i + OutBindsOffset]);
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
for (let i = 0; i < modifiedRowsCount; i++) {
|
|
205
|
-
updatedObjOutBinding.push(obj.outBinding[0]);
|
|
206
|
-
each(obj.outBinding[0], updateOutBinds(i));
|
|
207
|
-
}
|
|
208
|
-
outBinds = updatedOutBinds;
|
|
209
|
-
obj.outBinding = updatedObjOutBinding;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
if (!obj.returning && outBinds.length === 0) {
|
|
213
|
-
if (!connection.isTransaction) {
|
|
214
|
-
await connection.commitAsync();
|
|
215
|
-
}
|
|
216
|
-
return obj;
|
|
217
|
-
}
|
|
218
|
-
const rowIds = [];
|
|
219
|
-
let offset = 0;
|
|
220
|
-
|
|
221
|
-
for (let line = 0; line < obj.outBinding.length; line++) {
|
|
222
|
-
const ret = obj.outBinding[line];
|
|
223
|
-
|
|
224
|
-
offset =
|
|
225
|
-
offset +
|
|
226
|
-
(obj.outBinding[line - 1] ? obj.outBinding[line - 1].length : 0);
|
|
227
|
-
|
|
228
|
-
for (let index = 0; index < ret.length; index++) {
|
|
229
|
-
const out = ret[index];
|
|
230
|
-
|
|
231
|
-
await new Promise(function (bindResolver, bindRejecter) {
|
|
232
|
-
if (out instanceof BlobHelper) {
|
|
233
|
-
const blob = outBinds[index + offset];
|
|
234
|
-
if (out.returning) {
|
|
235
|
-
obj.response[line] = obj.response[line] || {};
|
|
236
|
-
obj.response[line][out.columnName] = out.value;
|
|
237
|
-
}
|
|
238
|
-
blob.on('error', function (err) {
|
|
239
|
-
bindRejecter(err);
|
|
240
|
-
});
|
|
241
|
-
blob.on('finish', function () {
|
|
242
|
-
bindResolver();
|
|
243
|
-
});
|
|
244
|
-
blob.write(out.value);
|
|
245
|
-
blob.end();
|
|
246
|
-
} else if (obj.outBinding[line][index] === 'ROWID') {
|
|
247
|
-
rowIds.push(outBinds[index + offset]);
|
|
248
|
-
bindResolver();
|
|
249
|
-
} else {
|
|
250
|
-
obj.response[line] = obj.response[line] || {};
|
|
251
|
-
obj.response[line][out] = outBinds[index + offset];
|
|
252
|
-
bindResolver();
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
if (connection.isTransaction) {
|
|
258
|
-
return obj;
|
|
259
|
-
}
|
|
260
|
-
await connection.commitAsync();
|
|
261
|
-
if (obj.returningSql) {
|
|
262
|
-
const response = await connection.executeAsync(
|
|
263
|
-
obj.returningSql(),
|
|
264
|
-
rowIds,
|
|
265
|
-
{ resultSet: true }
|
|
266
|
-
);
|
|
267
|
-
obj.response = response.rows;
|
|
268
|
-
}
|
|
269
|
-
return obj;
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// Process the response as returned from the query.
|
|
274
|
-
processResponse(obj, runner) {
|
|
275
|
-
const { response } = obj;
|
|
276
|
-
if (obj.output) {
|
|
277
|
-
return obj.output.call(runner, response);
|
|
278
|
-
}
|
|
279
|
-
switch (obj.method) {
|
|
280
|
-
case 'select':
|
|
281
|
-
return response;
|
|
282
|
-
case 'first':
|
|
283
|
-
return response[0];
|
|
284
|
-
case 'pluck':
|
|
285
|
-
return map(response, obj.pluck);
|
|
286
|
-
case 'insert':
|
|
287
|
-
case 'del':
|
|
288
|
-
case 'update':
|
|
289
|
-
case 'counter':
|
|
290
|
-
if (obj.returning && !isEmpty(obj.returning)) {
|
|
291
|
-
return response;
|
|
292
|
-
} else if (obj.rowsAffected !== undefined) {
|
|
293
|
-
return obj.rowsAffected;
|
|
294
|
-
} else {
|
|
295
|
-
return 1;
|
|
296
|
-
}
|
|
297
|
-
default:
|
|
298
|
-
return response;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
processPassedConnection(connection) {
|
|
303
|
-
monkeyPatchConnection(connection, this);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
Client_Oracledb.prototype.driverName = 'oracledb';
|
|
308
|
-
|
|
309
|
-
function resolveConnectString(connectionSettings) {
|
|
310
|
-
if (connectionSettings.connectString) {
|
|
311
|
-
return connectionSettings.connectString;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
if (!connectionSettings.port) {
|
|
315
|
-
return connectionSettings.host + '/' + connectionSettings.database;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
return (
|
|
319
|
-
connectionSettings.host +
|
|
320
|
-
':' +
|
|
321
|
-
connectionSettings.port +
|
|
322
|
-
'/' +
|
|
323
|
-
connectionSettings.database
|
|
324
|
-
);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
module.exports = Client_Oracledb;
|
|
1
|
+
// Oracledb Client
|
|
2
|
+
// -------
|
|
3
|
+
const each = require('lodash/each');
|
|
4
|
+
const flatten = require('lodash/flatten');
|
|
5
|
+
const isEmpty = require('lodash/isEmpty');
|
|
6
|
+
const map = require('lodash/map');
|
|
7
|
+
|
|
8
|
+
const Formatter = require('../../formatter');
|
|
9
|
+
const QueryCompiler = require('./query/oracledb-querycompiler');
|
|
10
|
+
const TableCompiler = require('./schema/oracledb-tablecompiler');
|
|
11
|
+
const ColumnCompiler = require('./schema/oracledb-columncompiler');
|
|
12
|
+
const {
|
|
13
|
+
BlobHelper,
|
|
14
|
+
ReturningHelper,
|
|
15
|
+
monkeyPatchConnection,
|
|
16
|
+
} = require('./utils');
|
|
17
|
+
const ViewCompiler = require('./schema/oracledb-viewcompiler');
|
|
18
|
+
const ViewBuilder = require('./schema/oracledb-viewbuilder');
|
|
19
|
+
const Transaction = require('./transaction');
|
|
20
|
+
const Client_Oracle = require('../oracle');
|
|
21
|
+
const { isString } = require('../../util/is');
|
|
22
|
+
const { outputQuery, unwrapRaw } = require('../../formatter/wrappingFormatter');
|
|
23
|
+
const { compileCallback } = require('../../formatter/formatterUtils');
|
|
24
|
+
|
|
25
|
+
class Client_Oracledb extends Client_Oracle {
|
|
26
|
+
constructor(config) {
|
|
27
|
+
super(config);
|
|
28
|
+
if (this.driver) {
|
|
29
|
+
process.env.UV_THREADPOOL_SIZE = process.env.UV_THREADPOOL_SIZE || 1;
|
|
30
|
+
process.env.UV_THREADPOOL_SIZE =
|
|
31
|
+
parseInt(process.env.UV_THREADPOOL_SIZE) + this.driver.poolMax;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
_driver() {
|
|
36
|
+
const client = this;
|
|
37
|
+
const oracledb = require('oracledb');
|
|
38
|
+
client.fetchAsString = [];
|
|
39
|
+
if (this.config.fetchAsString && Array.isArray(this.config.fetchAsString)) {
|
|
40
|
+
this.config.fetchAsString.forEach(function (type) {
|
|
41
|
+
if (!isString(type)) return;
|
|
42
|
+
type = type.toUpperCase();
|
|
43
|
+
if (oracledb[type]) {
|
|
44
|
+
if (
|
|
45
|
+
type !== 'NUMBER' &&
|
|
46
|
+
type !== 'DATE' &&
|
|
47
|
+
type !== 'CLOB' &&
|
|
48
|
+
type !== 'BUFFER'
|
|
49
|
+
) {
|
|
50
|
+
this.logger.warn(
|
|
51
|
+
'Only "date", "number", "clob" and "buffer" are supported for fetchAsString'
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
client.fetchAsString.push(oracledb[type]);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
return oracledb;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
queryCompiler(builder, formatter) {
|
|
62
|
+
return new QueryCompiler(this, builder, formatter);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
tableCompiler() {
|
|
66
|
+
return new TableCompiler(this, ...arguments);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
columnCompiler() {
|
|
70
|
+
return new ColumnCompiler(this, ...arguments);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
viewBuilder() {
|
|
74
|
+
return new ViewBuilder(this, ...arguments);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
viewCompiler() {
|
|
78
|
+
return new ViewCompiler(this, ...arguments);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
formatter(builder) {
|
|
82
|
+
return new Formatter(this, builder);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
transaction() {
|
|
86
|
+
return new Transaction(this, ...arguments);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
prepBindings(bindings) {
|
|
90
|
+
return map(bindings, (value) => {
|
|
91
|
+
if (value instanceof BlobHelper && this.driver) {
|
|
92
|
+
return { type: this.driver.BLOB, dir: this.driver.BIND_OUT };
|
|
93
|
+
// Returning helper always use ROWID as string
|
|
94
|
+
} else if (value instanceof ReturningHelper && this.driver) {
|
|
95
|
+
return { type: this.driver.STRING, dir: this.driver.BIND_OUT };
|
|
96
|
+
} else if (typeof value === 'boolean') {
|
|
97
|
+
return value ? 1 : 0;
|
|
98
|
+
}
|
|
99
|
+
return value;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Checks whether a value is a function... if it is, we compile it
|
|
104
|
+
// otherwise we check whether it's a raw
|
|
105
|
+
parameter(value, builder, formatter) {
|
|
106
|
+
if (typeof value === 'function') {
|
|
107
|
+
return outputQuery(
|
|
108
|
+
compileCallback(value, undefined, this, formatter),
|
|
109
|
+
true,
|
|
110
|
+
builder,
|
|
111
|
+
this
|
|
112
|
+
);
|
|
113
|
+
} else if (value instanceof BlobHelper) {
|
|
114
|
+
formatter.bindings.push(value.value);
|
|
115
|
+
return '?';
|
|
116
|
+
}
|
|
117
|
+
return unwrapRaw(value, true, builder, this, formatter) || '?';
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Get a raw connection, called by the `pool` whenever a new
|
|
121
|
+
// connection needs to be added to the pool.
|
|
122
|
+
acquireRawConnection() {
|
|
123
|
+
const client = this;
|
|
124
|
+
const asyncConnection = new Promise(function (resolver, rejecter) {
|
|
125
|
+
// If external authentication don't have to worry about username/password and
|
|
126
|
+
// if not need to set the username and password
|
|
127
|
+
const oracleDbConfig = client.connectionSettings.externalAuth
|
|
128
|
+
? { externalAuth: client.connectionSettings.externalAuth }
|
|
129
|
+
: {
|
|
130
|
+
user: client.connectionSettings.user,
|
|
131
|
+
password: client.connectionSettings.password,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// In the case of external authentication connection string will be given
|
|
135
|
+
oracleDbConfig.connectString = resolveConnectString(
|
|
136
|
+
client.connectionSettings
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
if (client.connectionSettings.prefetchRowCount) {
|
|
140
|
+
oracleDbConfig.prefetchRows =
|
|
141
|
+
client.connectionSettings.prefetchRowCount;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (client.connectionSettings.stmtCacheSize !== undefined) {
|
|
145
|
+
oracleDbConfig.stmtCacheSize = client.connectionSettings.stmtCacheSize;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
client.driver.fetchAsString = client.fetchAsString;
|
|
149
|
+
|
|
150
|
+
client.driver.getConnection(oracleDbConfig, function (err, connection) {
|
|
151
|
+
if (err) {
|
|
152
|
+
return rejecter(err);
|
|
153
|
+
}
|
|
154
|
+
monkeyPatchConnection(connection, client);
|
|
155
|
+
|
|
156
|
+
resolver(connection);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
return asyncConnection;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Used to explicitly close a connection, called internally by the pool
|
|
163
|
+
// when a connection times out or the pool is shutdown.
|
|
164
|
+
destroyRawConnection(connection) {
|
|
165
|
+
return connection.release();
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Runs the query on the specified connection, providing the bindings
|
|
169
|
+
// and any other necessary prep work.
|
|
170
|
+
_query(connection, obj) {
|
|
171
|
+
if (!obj.sql) throw new Error('The query is empty');
|
|
172
|
+
|
|
173
|
+
const options = { autoCommit: false };
|
|
174
|
+
if (obj.method === 'select') {
|
|
175
|
+
options.resultSet = true;
|
|
176
|
+
}
|
|
177
|
+
return connection
|
|
178
|
+
.executeAsync(obj.sql, obj.bindings, options)
|
|
179
|
+
.then(async function (response) {
|
|
180
|
+
// Flatten outBinds
|
|
181
|
+
let outBinds = flatten(response.outBinds);
|
|
182
|
+
obj.response = response.rows || [];
|
|
183
|
+
obj.rowsAffected = response.rows
|
|
184
|
+
? response.rows.rowsAffected
|
|
185
|
+
: response.rowsAffected;
|
|
186
|
+
|
|
187
|
+
//added for outBind parameter
|
|
188
|
+
if (obj.method === 'raw' && outBinds.length > 0) {
|
|
189
|
+
return {
|
|
190
|
+
response: outBinds,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (obj.method === 'update') {
|
|
195
|
+
const modifiedRowsCount = obj.rowsAffected.length || obj.rowsAffected;
|
|
196
|
+
const updatedObjOutBinding = [];
|
|
197
|
+
const updatedOutBinds = [];
|
|
198
|
+
const updateOutBinds = (i) =>
|
|
199
|
+
function (value, index) {
|
|
200
|
+
const OutBindsOffset = index * modifiedRowsCount;
|
|
201
|
+
updatedOutBinds.push(outBinds[i + OutBindsOffset]);
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
for (let i = 0; i < modifiedRowsCount; i++) {
|
|
205
|
+
updatedObjOutBinding.push(obj.outBinding[0]);
|
|
206
|
+
each(obj.outBinding[0], updateOutBinds(i));
|
|
207
|
+
}
|
|
208
|
+
outBinds = updatedOutBinds;
|
|
209
|
+
obj.outBinding = updatedObjOutBinding;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (!obj.returning && outBinds.length === 0) {
|
|
213
|
+
if (!connection.isTransaction) {
|
|
214
|
+
await connection.commitAsync();
|
|
215
|
+
}
|
|
216
|
+
return obj;
|
|
217
|
+
}
|
|
218
|
+
const rowIds = [];
|
|
219
|
+
let offset = 0;
|
|
220
|
+
|
|
221
|
+
for (let line = 0; line < obj.outBinding.length; line++) {
|
|
222
|
+
const ret = obj.outBinding[line];
|
|
223
|
+
|
|
224
|
+
offset =
|
|
225
|
+
offset +
|
|
226
|
+
(obj.outBinding[line - 1] ? obj.outBinding[line - 1].length : 0);
|
|
227
|
+
|
|
228
|
+
for (let index = 0; index < ret.length; index++) {
|
|
229
|
+
const out = ret[index];
|
|
230
|
+
|
|
231
|
+
await new Promise(function (bindResolver, bindRejecter) {
|
|
232
|
+
if (out instanceof BlobHelper) {
|
|
233
|
+
const blob = outBinds[index + offset];
|
|
234
|
+
if (out.returning) {
|
|
235
|
+
obj.response[line] = obj.response[line] || {};
|
|
236
|
+
obj.response[line][out.columnName] = out.value;
|
|
237
|
+
}
|
|
238
|
+
blob.on('error', function (err) {
|
|
239
|
+
bindRejecter(err);
|
|
240
|
+
});
|
|
241
|
+
blob.on('finish', function () {
|
|
242
|
+
bindResolver();
|
|
243
|
+
});
|
|
244
|
+
blob.write(out.value);
|
|
245
|
+
blob.end();
|
|
246
|
+
} else if (obj.outBinding[line][index] === 'ROWID') {
|
|
247
|
+
rowIds.push(outBinds[index + offset]);
|
|
248
|
+
bindResolver();
|
|
249
|
+
} else {
|
|
250
|
+
obj.response[line] = obj.response[line] || {};
|
|
251
|
+
obj.response[line][out] = outBinds[index + offset];
|
|
252
|
+
bindResolver();
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (connection.isTransaction) {
|
|
258
|
+
return obj;
|
|
259
|
+
}
|
|
260
|
+
await connection.commitAsync();
|
|
261
|
+
if (obj.returningSql) {
|
|
262
|
+
const response = await connection.executeAsync(
|
|
263
|
+
obj.returningSql(),
|
|
264
|
+
rowIds,
|
|
265
|
+
{ resultSet: true }
|
|
266
|
+
);
|
|
267
|
+
obj.response = response.rows;
|
|
268
|
+
}
|
|
269
|
+
return obj;
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Process the response as returned from the query.
|
|
274
|
+
processResponse(obj, runner) {
|
|
275
|
+
const { response } = obj;
|
|
276
|
+
if (obj.output) {
|
|
277
|
+
return obj.output.call(runner, response);
|
|
278
|
+
}
|
|
279
|
+
switch (obj.method) {
|
|
280
|
+
case 'select':
|
|
281
|
+
return response;
|
|
282
|
+
case 'first':
|
|
283
|
+
return response[0];
|
|
284
|
+
case 'pluck':
|
|
285
|
+
return map(response, obj.pluck);
|
|
286
|
+
case 'insert':
|
|
287
|
+
case 'del':
|
|
288
|
+
case 'update':
|
|
289
|
+
case 'counter':
|
|
290
|
+
if (obj.returning && !isEmpty(obj.returning)) {
|
|
291
|
+
return response;
|
|
292
|
+
} else if (obj.rowsAffected !== undefined) {
|
|
293
|
+
return obj.rowsAffected;
|
|
294
|
+
} else {
|
|
295
|
+
return 1;
|
|
296
|
+
}
|
|
297
|
+
default:
|
|
298
|
+
return response;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
processPassedConnection(connection) {
|
|
303
|
+
monkeyPatchConnection(connection, this);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
Client_Oracledb.prototype.driverName = 'oracledb';
|
|
308
|
+
|
|
309
|
+
function resolveConnectString(connectionSettings) {
|
|
310
|
+
if (connectionSettings.connectString) {
|
|
311
|
+
return connectionSettings.connectString;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (!connectionSettings.port) {
|
|
315
|
+
return connectionSettings.host + '/' + connectionSettings.database;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return (
|
|
319
|
+
connectionSettings.host +
|
|
320
|
+
':' +
|
|
321
|
+
connectionSettings.port +
|
|
322
|
+
'/' +
|
|
323
|
+
connectionSettings.database
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
module.exports = Client_Oracledb;
|