@bdkinc/knex-ibmi 0.0.6 → 0.0.8
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/README.md +1 -1
- package/dist/index.js +120 -2
- package/dist/index.mjs +120 -2
- package/package.json +1 -1
- package/src/index.ts +57 -2
- package/src/query/ibmi-querycompiler.ts +102 -0
package/README.md
CHANGED
|
@@ -17,8 +17,8 @@ This is an external dialect for [knex](https://github.com/tgriesser/knex). This
|
|
|
17
17
|
Currently, this dialect has limited functionality compared to the Knex built-in dialects. Below are some of the limitations:
|
|
18
18
|
|
|
19
19
|
- No streaming support
|
|
20
|
+
- Updates return the value of the first column in that row. Make sure your identifier is the first column in the table. The returning option does not work on updates.
|
|
20
21
|
- Possibly other missing functionality
|
|
21
|
-
- Uses a pool for all connections
|
|
22
22
|
- Journaling must be handled separately. After a migration is ran journaling can be configured on the newly created tables. I recommend using the schema utility in the i access client solutions software.
|
|
23
23
|
|
|
24
24
|
## Installing
|
package/dist/index.js
CHANGED
|
@@ -183,7 +183,57 @@ var import_querycompiler = __toESM(require("knex/lib/query/querycompiler"));
|
|
|
183
183
|
var import_isObject2 = __toESM(require("lodash/isObject"));
|
|
184
184
|
var import_wrappingFormatter = require("knex/lib/formatter/wrappingFormatter");
|
|
185
185
|
var import_date_fns = require("date-fns");
|
|
186
|
+
var import_isEmpty = __toESM(require("lodash/isEmpty"));
|
|
186
187
|
var IBMiQueryCompiler = class extends import_querycompiler.default {
|
|
188
|
+
insert() {
|
|
189
|
+
const insertValues = this.single.insert || [];
|
|
190
|
+
let sql = `SELECT ${// @ts-ignore
|
|
191
|
+
this.single.returning ? (
|
|
192
|
+
// @ts-ignore
|
|
193
|
+
this.formatter.columnize(this.single.returning)
|
|
194
|
+
) : "IDENTITY_VAL_LOCAL()"} FROM FINAL TABLE(`;
|
|
195
|
+
sql += this.with() + `insert into ${this.tableName} `;
|
|
196
|
+
const { returning } = this.single;
|
|
197
|
+
const returningSql = returning ? (
|
|
198
|
+
// @ts-ignore
|
|
199
|
+
this._returning("insert", returning) + " "
|
|
200
|
+
) : "";
|
|
201
|
+
if (Array.isArray(insertValues)) {
|
|
202
|
+
if (insertValues.length === 0) {
|
|
203
|
+
return "";
|
|
204
|
+
}
|
|
205
|
+
} else if (typeof insertValues === "object" && (0, import_isEmpty.default)(insertValues)) {
|
|
206
|
+
return {
|
|
207
|
+
// @ts-ignore
|
|
208
|
+
sql: sql + returningSql + this._emptyInsertValue,
|
|
209
|
+
returning
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
sql += this._buildInsertData(insertValues, returningSql);
|
|
213
|
+
sql += ")";
|
|
214
|
+
return {
|
|
215
|
+
sql,
|
|
216
|
+
returning
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
_buildInsertData(insertValues, returningSql) {
|
|
220
|
+
let sql = "";
|
|
221
|
+
const insertData = this._prepInsert(insertValues);
|
|
222
|
+
if (typeof insertData === "string") {
|
|
223
|
+
sql += insertData;
|
|
224
|
+
} else {
|
|
225
|
+
if (insertData.columns.length) {
|
|
226
|
+
sql += `(${this.formatter.columnize(insertData.columns)}`;
|
|
227
|
+
sql += `) ${returningSql}values (` + // @ts-ignore
|
|
228
|
+
this._buildInsertValues(insertData) + ")";
|
|
229
|
+
} else if (insertValues.length === 1 && insertValues[0]) {
|
|
230
|
+
sql += returningSql + this._emptyInsertValue;
|
|
231
|
+
} else {
|
|
232
|
+
return "";
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return sql;
|
|
236
|
+
}
|
|
187
237
|
_prepInsert(data) {
|
|
188
238
|
if ((0, import_isObject2.default)(data)) {
|
|
189
239
|
if (data.hasOwnProperty("migration_time")) {
|
|
@@ -237,6 +287,33 @@ var IBMiQueryCompiler = class extends import_querycompiler.default {
|
|
|
237
287
|
values
|
|
238
288
|
};
|
|
239
289
|
}
|
|
290
|
+
_returning(method, value, withTrigger) {
|
|
291
|
+
switch (method) {
|
|
292
|
+
case "update":
|
|
293
|
+
case "insert":
|
|
294
|
+
return value ? (
|
|
295
|
+
// @ts-ignore
|
|
296
|
+
`${withTrigger ? " into #out" : ""}`
|
|
297
|
+
) : "";
|
|
298
|
+
case "del":
|
|
299
|
+
return value ? (
|
|
300
|
+
// @ts-ignore
|
|
301
|
+
`${withTrigger ? " into #out" : ""}`
|
|
302
|
+
) : "";
|
|
303
|
+
case "rowcount":
|
|
304
|
+
return value ? ";select @@rowcount" : "";
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
columnizeWithPrefix(prefix, target) {
|
|
308
|
+
const columns = typeof target === "string" ? [target] : target;
|
|
309
|
+
let str = "", i = -1;
|
|
310
|
+
while (++i < columns.length) {
|
|
311
|
+
if (i > 0)
|
|
312
|
+
str += ", ";
|
|
313
|
+
str += prefix + this.wrap(columns[i]);
|
|
314
|
+
}
|
|
315
|
+
return str;
|
|
316
|
+
}
|
|
240
317
|
};
|
|
241
318
|
var ibmi_querycompiler_default = IBMiQueryCompiler;
|
|
242
319
|
|
|
@@ -315,22 +392,62 @@ var DB2Client = class extends import_knex.default.Client {
|
|
|
315
392
|
obj.response = { rows, rowCount: rows.length };
|
|
316
393
|
}
|
|
317
394
|
} else {
|
|
395
|
+
const connection = await pool.connect();
|
|
396
|
+
await connection.beginTransaction();
|
|
318
397
|
try {
|
|
319
|
-
const connection = await pool.connect();
|
|
320
398
|
const statement = await connection.createStatement();
|
|
321
399
|
await statement.prepare(obj.sql);
|
|
400
|
+
console.log({ obj });
|
|
322
401
|
if (obj.bindings) {
|
|
323
402
|
await statement.bind(obj.bindings);
|
|
324
403
|
}
|
|
325
404
|
const result = await statement.execute();
|
|
326
|
-
|
|
405
|
+
if (result.statement.includes("IDENTITY_VAL_LOCAL()")) {
|
|
406
|
+
obj.response = {
|
|
407
|
+
rows: result.map(
|
|
408
|
+
(row) => result.columns.length > 0 ? row[result.columns[0].name] : row
|
|
409
|
+
),
|
|
410
|
+
rowCount: result.length
|
|
411
|
+
};
|
|
412
|
+
} else if (method === "update") {
|
|
413
|
+
let returningSelect = obj.sql.replace("update", "select * from ");
|
|
414
|
+
returningSelect = returningSelect.replace("where", "and");
|
|
415
|
+
returningSelect = returningSelect.replace("set", "where");
|
|
416
|
+
returningSelect = returningSelect.replace(this.tableName, "where");
|
|
417
|
+
const selectStatement = await connection.createStatement();
|
|
418
|
+
await selectStatement.prepare(returningSelect);
|
|
419
|
+
if (obj.bindings) {
|
|
420
|
+
await selectStatement.bind(obj.bindings);
|
|
421
|
+
}
|
|
422
|
+
const selected = await selectStatement.execute();
|
|
423
|
+
obj.response = { rows: selected.map(
|
|
424
|
+
(row) => selected.columns.length > 0 ? row[selected.columns[0].name] : row
|
|
425
|
+
), rowCount: selected.length };
|
|
426
|
+
} else {
|
|
427
|
+
obj.response = { rows: result, rowCount: result.length };
|
|
428
|
+
}
|
|
327
429
|
} catch (err) {
|
|
328
430
|
console.error(err);
|
|
431
|
+
await connection.rollback();
|
|
329
432
|
throw new Error(err);
|
|
433
|
+
} finally {
|
|
434
|
+
await connection.commit();
|
|
330
435
|
}
|
|
331
436
|
}
|
|
332
437
|
return obj;
|
|
333
438
|
}
|
|
439
|
+
_selectAfterUpdate() {
|
|
440
|
+
const returnSelect = `; SELECT ${this.single.returning ? (
|
|
441
|
+
// @ts-ignore
|
|
442
|
+
this.formatter.columnize(this.single.returning)
|
|
443
|
+
) : "*"} from ${this.tableName} `;
|
|
444
|
+
let whereStatement = [this.where()];
|
|
445
|
+
console.log({ whereStatement });
|
|
446
|
+
for (const [key, value] of Object.entries(this.single.update)) {
|
|
447
|
+
whereStatement.push(`WHERE ${key} = ${value}`);
|
|
448
|
+
}
|
|
449
|
+
return returnSelect + whereStatement.join(" and ");
|
|
450
|
+
}
|
|
334
451
|
transaction(container, config, outerTx) {
|
|
335
452
|
return new ibmi_transaction_default(this, ...arguments);
|
|
336
453
|
}
|
|
@@ -366,6 +483,7 @@ var DB2Client = class extends import_knex.default.Client {
|
|
|
366
483
|
case "del":
|
|
367
484
|
case "delete":
|
|
368
485
|
case "update":
|
|
486
|
+
return rows;
|
|
369
487
|
case "counter":
|
|
370
488
|
return resp.rowCount;
|
|
371
489
|
default:
|
package/dist/index.mjs
CHANGED
|
@@ -148,7 +148,57 @@ import QueryCompiler from "knex/lib/query/querycompiler";
|
|
|
148
148
|
import isObject2 from "lodash/isObject";
|
|
149
149
|
import { rawOrFn as rawOrFn_ } from "knex/lib/formatter/wrappingFormatter";
|
|
150
150
|
import { format } from "date-fns";
|
|
151
|
+
import isEmpty from "lodash/isEmpty";
|
|
151
152
|
var IBMiQueryCompiler = class extends QueryCompiler {
|
|
153
|
+
insert() {
|
|
154
|
+
const insertValues = this.single.insert || [];
|
|
155
|
+
let sql = `SELECT ${// @ts-ignore
|
|
156
|
+
this.single.returning ? (
|
|
157
|
+
// @ts-ignore
|
|
158
|
+
this.formatter.columnize(this.single.returning)
|
|
159
|
+
) : "IDENTITY_VAL_LOCAL()"} FROM FINAL TABLE(`;
|
|
160
|
+
sql += this.with() + `insert into ${this.tableName} `;
|
|
161
|
+
const { returning } = this.single;
|
|
162
|
+
const returningSql = returning ? (
|
|
163
|
+
// @ts-ignore
|
|
164
|
+
this._returning("insert", returning) + " "
|
|
165
|
+
) : "";
|
|
166
|
+
if (Array.isArray(insertValues)) {
|
|
167
|
+
if (insertValues.length === 0) {
|
|
168
|
+
return "";
|
|
169
|
+
}
|
|
170
|
+
} else if (typeof insertValues === "object" && isEmpty(insertValues)) {
|
|
171
|
+
return {
|
|
172
|
+
// @ts-ignore
|
|
173
|
+
sql: sql + returningSql + this._emptyInsertValue,
|
|
174
|
+
returning
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
sql += this._buildInsertData(insertValues, returningSql);
|
|
178
|
+
sql += ")";
|
|
179
|
+
return {
|
|
180
|
+
sql,
|
|
181
|
+
returning
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
_buildInsertData(insertValues, returningSql) {
|
|
185
|
+
let sql = "";
|
|
186
|
+
const insertData = this._prepInsert(insertValues);
|
|
187
|
+
if (typeof insertData === "string") {
|
|
188
|
+
sql += insertData;
|
|
189
|
+
} else {
|
|
190
|
+
if (insertData.columns.length) {
|
|
191
|
+
sql += `(${this.formatter.columnize(insertData.columns)}`;
|
|
192
|
+
sql += `) ${returningSql}values (` + // @ts-ignore
|
|
193
|
+
this._buildInsertValues(insertData) + ")";
|
|
194
|
+
} else if (insertValues.length === 1 && insertValues[0]) {
|
|
195
|
+
sql += returningSql + this._emptyInsertValue;
|
|
196
|
+
} else {
|
|
197
|
+
return "";
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return sql;
|
|
201
|
+
}
|
|
152
202
|
_prepInsert(data) {
|
|
153
203
|
if (isObject2(data)) {
|
|
154
204
|
if (data.hasOwnProperty("migration_time")) {
|
|
@@ -202,6 +252,33 @@ var IBMiQueryCompiler = class extends QueryCompiler {
|
|
|
202
252
|
values
|
|
203
253
|
};
|
|
204
254
|
}
|
|
255
|
+
_returning(method, value, withTrigger) {
|
|
256
|
+
switch (method) {
|
|
257
|
+
case "update":
|
|
258
|
+
case "insert":
|
|
259
|
+
return value ? (
|
|
260
|
+
// @ts-ignore
|
|
261
|
+
`${withTrigger ? " into #out" : ""}`
|
|
262
|
+
) : "";
|
|
263
|
+
case "del":
|
|
264
|
+
return value ? (
|
|
265
|
+
// @ts-ignore
|
|
266
|
+
`${withTrigger ? " into #out" : ""}`
|
|
267
|
+
) : "";
|
|
268
|
+
case "rowcount":
|
|
269
|
+
return value ? ";select @@rowcount" : "";
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
columnizeWithPrefix(prefix, target) {
|
|
273
|
+
const columns = typeof target === "string" ? [target] : target;
|
|
274
|
+
let str = "", i = -1;
|
|
275
|
+
while (++i < columns.length) {
|
|
276
|
+
if (i > 0)
|
|
277
|
+
str += ", ";
|
|
278
|
+
str += prefix + this.wrap(columns[i]);
|
|
279
|
+
}
|
|
280
|
+
return str;
|
|
281
|
+
}
|
|
205
282
|
};
|
|
206
283
|
var ibmi_querycompiler_default = IBMiQueryCompiler;
|
|
207
284
|
|
|
@@ -280,22 +357,62 @@ var DB2Client = class extends knex.Client {
|
|
|
280
357
|
obj.response = { rows, rowCount: rows.length };
|
|
281
358
|
}
|
|
282
359
|
} else {
|
|
360
|
+
const connection = await pool.connect();
|
|
361
|
+
await connection.beginTransaction();
|
|
283
362
|
try {
|
|
284
|
-
const connection = await pool.connect();
|
|
285
363
|
const statement = await connection.createStatement();
|
|
286
364
|
await statement.prepare(obj.sql);
|
|
365
|
+
console.log({ obj });
|
|
287
366
|
if (obj.bindings) {
|
|
288
367
|
await statement.bind(obj.bindings);
|
|
289
368
|
}
|
|
290
369
|
const result = await statement.execute();
|
|
291
|
-
|
|
370
|
+
if (result.statement.includes("IDENTITY_VAL_LOCAL()")) {
|
|
371
|
+
obj.response = {
|
|
372
|
+
rows: result.map(
|
|
373
|
+
(row) => result.columns.length > 0 ? row[result.columns[0].name] : row
|
|
374
|
+
),
|
|
375
|
+
rowCount: result.length
|
|
376
|
+
};
|
|
377
|
+
} else if (method === "update") {
|
|
378
|
+
let returningSelect = obj.sql.replace("update", "select * from ");
|
|
379
|
+
returningSelect = returningSelect.replace("where", "and");
|
|
380
|
+
returningSelect = returningSelect.replace("set", "where");
|
|
381
|
+
returningSelect = returningSelect.replace(this.tableName, "where");
|
|
382
|
+
const selectStatement = await connection.createStatement();
|
|
383
|
+
await selectStatement.prepare(returningSelect);
|
|
384
|
+
if (obj.bindings) {
|
|
385
|
+
await selectStatement.bind(obj.bindings);
|
|
386
|
+
}
|
|
387
|
+
const selected = await selectStatement.execute();
|
|
388
|
+
obj.response = { rows: selected.map(
|
|
389
|
+
(row) => selected.columns.length > 0 ? row[selected.columns[0].name] : row
|
|
390
|
+
), rowCount: selected.length };
|
|
391
|
+
} else {
|
|
392
|
+
obj.response = { rows: result, rowCount: result.length };
|
|
393
|
+
}
|
|
292
394
|
} catch (err) {
|
|
293
395
|
console.error(err);
|
|
396
|
+
await connection.rollback();
|
|
294
397
|
throw new Error(err);
|
|
398
|
+
} finally {
|
|
399
|
+
await connection.commit();
|
|
295
400
|
}
|
|
296
401
|
}
|
|
297
402
|
return obj;
|
|
298
403
|
}
|
|
404
|
+
_selectAfterUpdate() {
|
|
405
|
+
const returnSelect = `; SELECT ${this.single.returning ? (
|
|
406
|
+
// @ts-ignore
|
|
407
|
+
this.formatter.columnize(this.single.returning)
|
|
408
|
+
) : "*"} from ${this.tableName} `;
|
|
409
|
+
let whereStatement = [this.where()];
|
|
410
|
+
console.log({ whereStatement });
|
|
411
|
+
for (const [key, value] of Object.entries(this.single.update)) {
|
|
412
|
+
whereStatement.push(`WHERE ${key} = ${value}`);
|
|
413
|
+
}
|
|
414
|
+
return returnSelect + whereStatement.join(" and ");
|
|
415
|
+
}
|
|
299
416
|
transaction(container, config, outerTx) {
|
|
300
417
|
return new ibmi_transaction_default(this, ...arguments);
|
|
301
418
|
}
|
|
@@ -331,6 +448,7 @@ var DB2Client = class extends knex.Client {
|
|
|
331
448
|
case "del":
|
|
332
449
|
case "delete":
|
|
333
450
|
case "update":
|
|
451
|
+
return rows;
|
|
334
452
|
case "counter":
|
|
335
453
|
return resp.rowCount;
|
|
336
454
|
default:
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -110,24 +110,78 @@ class DB2Client extends knex.Client {
|
|
|
110
110
|
obj.response = { rows, rowCount: rows.length };
|
|
111
111
|
}
|
|
112
112
|
} else {
|
|
113
|
+
const connection = await pool.connect();
|
|
114
|
+
await connection.beginTransaction();
|
|
113
115
|
try {
|
|
114
|
-
const connection = await pool.connect();
|
|
115
116
|
const statement = await connection.createStatement();
|
|
116
117
|
await statement.prepare(obj.sql);
|
|
118
|
+
console.log({ obj });
|
|
117
119
|
if (obj.bindings) {
|
|
118
120
|
await statement.bind(obj.bindings);
|
|
119
121
|
}
|
|
120
122
|
const result = await statement.execute();
|
|
121
|
-
|
|
123
|
+
// this is hacky we check the SQL for the ID column
|
|
124
|
+
// most dialects return the ID of the inserted
|
|
125
|
+
// we check for the IDENTITY scalar function
|
|
126
|
+
// if that function is present, then we just return the value of the
|
|
127
|
+
// IDENTITY column
|
|
128
|
+
if (result.statement.includes("IDENTITY_VAL_LOCAL()")) {
|
|
129
|
+
obj.response = {
|
|
130
|
+
rows: result.map((row) =>
|
|
131
|
+
result.columns.length > 0 ? row[result.columns[0].name] : row,
|
|
132
|
+
),
|
|
133
|
+
rowCount: result.length,
|
|
134
|
+
};
|
|
135
|
+
} else if (method === "update") {
|
|
136
|
+
// if is in update we need to run a separate select query
|
|
137
|
+
// this also feels hacky and should be cleaned up
|
|
138
|
+
// it would be a lot easier if the table-reference function
|
|
139
|
+
// worked the same for updates as it does inserts
|
|
140
|
+
// on DB2 LUW it does work so if they ever add it we need to fix
|
|
141
|
+
let returningSelect = obj.sql.replace("update", "select * from ");
|
|
142
|
+
returningSelect = returningSelect.replace("where", "and");
|
|
143
|
+
returningSelect = returningSelect.replace("set", "where");
|
|
144
|
+
returningSelect = returningSelect.replace(this.tableName, "where");
|
|
145
|
+
const selectStatement = await connection.createStatement();
|
|
146
|
+
await selectStatement.prepare(returningSelect);
|
|
147
|
+
if (obj.bindings) {
|
|
148
|
+
await selectStatement.bind(obj.bindings);
|
|
149
|
+
}
|
|
150
|
+
const selected = await selectStatement.execute();
|
|
151
|
+
obj.response = {rows: selected.map((row) =>
|
|
152
|
+
selected.columns.length > 0 ? row[selected.columns[0].name] : row,
|
|
153
|
+
), rowCount: selected.length}
|
|
154
|
+
} else {
|
|
155
|
+
obj.response = { rows: result, rowCount: result.length };
|
|
156
|
+
}
|
|
122
157
|
} catch (err: any) {
|
|
123
158
|
console.error(err);
|
|
159
|
+
await connection.rollback()
|
|
124
160
|
throw new Error(err);
|
|
161
|
+
} finally {
|
|
162
|
+
await connection.commit()
|
|
125
163
|
}
|
|
164
|
+
|
|
126
165
|
}
|
|
127
166
|
|
|
128
167
|
return obj;
|
|
129
168
|
}
|
|
130
169
|
|
|
170
|
+
_selectAfterUpdate() {
|
|
171
|
+
const returnSelect = `; SELECT ${
|
|
172
|
+
this.single.returning
|
|
173
|
+
? // @ts-ignore
|
|
174
|
+
this.formatter.columnize(this.single.returning)
|
|
175
|
+
: "*"
|
|
176
|
+
} from ${this.tableName} `;
|
|
177
|
+
let whereStatement = [this.where()];
|
|
178
|
+
console.log({ whereStatement });
|
|
179
|
+
for (const [key, value] of Object.entries(this.single.update)) {
|
|
180
|
+
whereStatement.push(`WHERE ${key} = ${value}`);
|
|
181
|
+
}
|
|
182
|
+
return returnSelect + whereStatement.join(" and ");
|
|
183
|
+
}
|
|
184
|
+
|
|
131
185
|
transaction(container: any, config: any, outerTx: any): Knex.Transaction {
|
|
132
186
|
// @ts-ignore
|
|
133
187
|
return new Transaction(this, ...arguments);
|
|
@@ -174,6 +228,7 @@ class DB2Client extends knex.Client {
|
|
|
174
228
|
case "del":
|
|
175
229
|
case "delete":
|
|
176
230
|
case "update":
|
|
231
|
+
return rows;
|
|
177
232
|
case "counter":
|
|
178
233
|
return resp.rowCount;
|
|
179
234
|
default:
|
|
@@ -2,8 +2,80 @@ import QueryCompiler from "knex/lib/query/querycompiler";
|
|
|
2
2
|
import isObject from "lodash/isObject";
|
|
3
3
|
import { rawOrFn as rawOrFn_ } from "knex/lib/formatter/wrappingFormatter";
|
|
4
4
|
import { format } from "date-fns";
|
|
5
|
+
import * as console from "console";
|
|
6
|
+
import isEmpty from "lodash/isEmpty";
|
|
5
7
|
|
|
6
8
|
class IBMiQueryCompiler extends QueryCompiler {
|
|
9
|
+
insert() {
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
const insertValues = this.single.insert || [];
|
|
12
|
+
// we need to return a value
|
|
13
|
+
// we need to wrap the insert statement in a select statement
|
|
14
|
+
// we use the "IDENTITY_VAL_LOCAL()" function to return the IDENTITY
|
|
15
|
+
// unless specified in a return
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
let sql = `SELECT ${
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
this.single.returning
|
|
20
|
+
? // @ts-ignore
|
|
21
|
+
this.formatter.columnize(this.single.returning)
|
|
22
|
+
: "IDENTITY_VAL_LOCAL()"
|
|
23
|
+
} FROM FINAL TABLE(`;
|
|
24
|
+
// @ts-ignore
|
|
25
|
+
sql += this.with() + `insert into ${this.tableName} `;
|
|
26
|
+
// @ts-ignore
|
|
27
|
+
const { returning } = this.single;
|
|
28
|
+
const returningSql = returning
|
|
29
|
+
? // @ts-ignore
|
|
30
|
+
this._returning("insert", returning) + " "
|
|
31
|
+
: "";
|
|
32
|
+
|
|
33
|
+
if (Array.isArray(insertValues)) {
|
|
34
|
+
if (insertValues.length === 0) {
|
|
35
|
+
return "";
|
|
36
|
+
}
|
|
37
|
+
} else if (typeof insertValues === "object" && isEmpty(insertValues)) {
|
|
38
|
+
return {
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
sql: sql + returningSql + this._emptyInsertValue,
|
|
41
|
+
returning,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// @ts-ignore
|
|
46
|
+
sql += this._buildInsertData(insertValues, returningSql);
|
|
47
|
+
sql += ")";
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
sql,
|
|
51
|
+
returning,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
_buildInsertData(insertValues, returningSql) {
|
|
56
|
+
let sql = "";
|
|
57
|
+
const insertData = this._prepInsert(insertValues);
|
|
58
|
+
if (typeof insertData === "string") {
|
|
59
|
+
sql += insertData;
|
|
60
|
+
} else {
|
|
61
|
+
if (insertData.columns.length) {
|
|
62
|
+
// @ts-ignore
|
|
63
|
+
sql += `(${this.formatter.columnize(insertData.columns)}`;
|
|
64
|
+
sql +=
|
|
65
|
+
`) ${returningSql}values (` +
|
|
66
|
+
// @ts-ignore
|
|
67
|
+
this._buildInsertValues(insertData) +
|
|
68
|
+
")";
|
|
69
|
+
} else if (insertValues.length === 1 && insertValues[0]) {
|
|
70
|
+
// @ts-ignore
|
|
71
|
+
sql += returningSql + this._emptyInsertValue;
|
|
72
|
+
} else {
|
|
73
|
+
return "";
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return sql;
|
|
77
|
+
}
|
|
78
|
+
|
|
7
79
|
_prepInsert(data) {
|
|
8
80
|
if (isObject(data)) {
|
|
9
81
|
if (data.hasOwnProperty("migration_time")) {
|
|
@@ -54,6 +126,36 @@ class IBMiQueryCompiler extends QueryCompiler {
|
|
|
54
126
|
values,
|
|
55
127
|
};
|
|
56
128
|
}
|
|
129
|
+
|
|
130
|
+
_returning(method, value, withTrigger) {
|
|
131
|
+
// currently a placeholder in case I need to update return values
|
|
132
|
+
switch (method) {
|
|
133
|
+
case "update":
|
|
134
|
+
case "insert":
|
|
135
|
+
return value
|
|
136
|
+
? // @ts-ignore
|
|
137
|
+
`${withTrigger ? " into #out" : ""}`
|
|
138
|
+
: "";
|
|
139
|
+
case "del":
|
|
140
|
+
return value
|
|
141
|
+
? // @ts-ignore
|
|
142
|
+
`${withTrigger ? " into #out" : ""}`
|
|
143
|
+
: "";
|
|
144
|
+
case "rowcount":
|
|
145
|
+
return value ? ";select @@rowcount" : "";
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
columnizeWithPrefix(prefix, target) {
|
|
150
|
+
const columns = typeof target === "string" ? [target] : target;
|
|
151
|
+
let str = "",
|
|
152
|
+
i = -1;
|
|
153
|
+
while (++i < columns.length) {
|
|
154
|
+
if (i > 0) str += ", ";
|
|
155
|
+
str += prefix + this.wrap(columns[i]);
|
|
156
|
+
}
|
|
157
|
+
return str;
|
|
158
|
+
}
|
|
57
159
|
}
|
|
58
160
|
|
|
59
161
|
export default IBMiQueryCompiler;
|