@bdkinc/knex-ibmi 0.3.21 → 0.3.22
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/LICENSE +0 -0
- package/README.md +13 -0
- package/dist/index.d.ts +43 -2
- package/dist/index.js +114 -82
- package/package.json +1 -1
package/LICENSE
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
@@ -248,3 +248,16 @@ If that still doesn't work, then unixodbc is probably looking for the config fil
|
|
|
248
248
|
A common case is that the configs are in `/etc` but your system expects them to be somewhere else.
|
|
249
249
|
In such a case, override the path unixodbc looks in via the `ODBCSYSINI` and `ODBCINI` environment variables.
|
|
250
250
|
E.g., `ODBCINI=/etc ODBCSYSINI=/etc`.
|
|
251
|
+
|
|
252
|
+
## Bundling with Vite
|
|
253
|
+
If you are bundling your application with Vite, then you will need to add this to your config.
|
|
254
|
+
|
|
255
|
+
```javascript
|
|
256
|
+
// vite.config.js
|
|
257
|
+
|
|
258
|
+
export default {
|
|
259
|
+
optimizeDeps: {
|
|
260
|
+
exclude: ["@mapbox"],
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
```
|
package/dist/index.d.ts
CHANGED
|
@@ -48,6 +48,26 @@ declare class IBMiQueryCompiler extends QueryCompiler {
|
|
|
48
48
|
columnizeWithPrefix(prefix: string, target: any): string;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
interface QueryObject {
|
|
52
|
+
response?: {
|
|
53
|
+
rows: any[];
|
|
54
|
+
rowCount: number;
|
|
55
|
+
};
|
|
56
|
+
sqlMethod: SqlMethod;
|
|
57
|
+
output?: (runner: any, response: any) => any;
|
|
58
|
+
pluck?: (row: any) => any;
|
|
59
|
+
select?: boolean;
|
|
60
|
+
}
|
|
61
|
+
declare enum SqlMethod {
|
|
62
|
+
SELECT = "select",
|
|
63
|
+
PLUCK = "pluck",
|
|
64
|
+
FIRST = "first",
|
|
65
|
+
INSERT = "insert",
|
|
66
|
+
DELETE = "del",
|
|
67
|
+
DELETE_ALT = "delete",
|
|
68
|
+
UPDATE = "update",
|
|
69
|
+
COUNTER = "counter"
|
|
70
|
+
}
|
|
51
71
|
declare class DB2Client extends knex.Client {
|
|
52
72
|
constructor(config: Knex.Config<DB2Config>);
|
|
53
73
|
_driver(): typeof odbc;
|
|
@@ -58,19 +78,28 @@ declare class DB2Client extends knex.Client {
|
|
|
58
78
|
acquireRawConnection(): Promise<any>;
|
|
59
79
|
destroyRawConnection(connection: any): Promise<any>;
|
|
60
80
|
_getConnectionString(connectionConfig: DB2ConnectionConfig): string;
|
|
61
|
-
_query(connection:
|
|
81
|
+
_query(connection: Connection, obj: any): Promise<any>;
|
|
82
|
+
private normalizeQueryObject;
|
|
83
|
+
private determineQueryMethod;
|
|
84
|
+
private isSelectMethod;
|
|
85
|
+
private executeSelectQuery;
|
|
86
|
+
private executeStatementQuery;
|
|
87
|
+
private formatStatementResponse;
|
|
62
88
|
_stream(connection: Connection, obj: {
|
|
63
89
|
sql: string;
|
|
64
90
|
bindings: any[];
|
|
65
91
|
}, stream: any, options: {
|
|
66
92
|
fetchSize?: number;
|
|
67
93
|
}): Promise<unknown>;
|
|
94
|
+
private _createCursorStream;
|
|
68
95
|
transaction(container: any, config: any, outerTx: any): Knex.Transaction;
|
|
69
96
|
schemaCompiler(tableBuilder: any): IBMiSchemaCompiler;
|
|
70
97
|
tableCompiler(tableBuilder: any): IBMiTableCompiler;
|
|
71
98
|
columnCompiler(tableCompiler: any, columnCompiler: any): IBMiColumnCompiler;
|
|
72
99
|
queryCompiler(builder: Knex.QueryBuilder, bindings?: any[]): IBMiQueryCompiler;
|
|
73
|
-
processResponse(obj:
|
|
100
|
+
processResponse(obj: QueryObject | null, runner: any): any;
|
|
101
|
+
private validateResponse;
|
|
102
|
+
private processSqlMethod;
|
|
74
103
|
}
|
|
75
104
|
interface DB2PoolConfig {
|
|
76
105
|
min?: number;
|
|
@@ -91,8 +120,20 @@ interface DB2ConnectionParams {
|
|
|
91
120
|
DECFLOATERROROPTION?: 0 | 1;
|
|
92
121
|
DECFLOATROUNDMODE?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
93
122
|
MAPDECIMALFLOATDESCRIBE?: 1 | 3;
|
|
123
|
+
TFT?: 0 | 1 | 2 | 3 | 4;
|
|
124
|
+
TSP?: 0 | 1 | 2 | 3;
|
|
125
|
+
TSFT?: 0 | 1;
|
|
126
|
+
XMLCURIMPPARSE?: 0 | 1;
|
|
127
|
+
XMLDECLARATION?: 1 | 2 | 3 | 4;
|
|
94
128
|
ALLOWPROCCALLS?: 0 | 1;
|
|
95
129
|
XDYNAMIC?: 0 | 1;
|
|
130
|
+
DFTPKGLIB?: string;
|
|
131
|
+
PKG?: 0 | 1 | 2;
|
|
132
|
+
BLOCKFETCH?: 0 | 1;
|
|
133
|
+
COMPRESSION?: 0 | 1;
|
|
134
|
+
CONCURRENCY?: 0 | 1;
|
|
135
|
+
CURSORSENSITIVITY?: 0 | 1 | 2;
|
|
136
|
+
EXTCOLINFO?: "SQL_DESC_AUTO_UNIQUE_VALUE" | "SQL_DESC_BASE_COLUMN_NAME" | "SQL_DESC_BASE_TABLE_NAME and SQL_DESC_TABLE_NAME" | "SQL_DESC_LABEL" | "SQL_DESC_SCHEMA_NAME" | "SQL_DESC_SEARCHABLE" | "SQL_DESC_UNNAMED" | "SQL_DESC_UPDATABLE";
|
|
96
137
|
}
|
|
97
138
|
interface DB2ConnectionConfig {
|
|
98
139
|
database: string;
|
package/dist/index.js
CHANGED
|
@@ -205,17 +205,13 @@ var IBMiQueryCompiler = class extends import_querycompiler.default {
|
|
|
205
205
|
_buildInsertData(insertValues, returningSql) {
|
|
206
206
|
let sql = "";
|
|
207
207
|
const insertData = this._prepInsert(insertValues);
|
|
208
|
-
if (
|
|
209
|
-
sql += insertData
|
|
208
|
+
if (insertData.columns.length) {
|
|
209
|
+
sql += `(${this.formatter.columnize(insertData.columns)}`;
|
|
210
|
+
sql += `) ${returningSql}values (` + this._buildInsertValues(insertData) + ")";
|
|
211
|
+
} else if (insertValues.length === 1 && insertValues[0]) {
|
|
212
|
+
sql += returningSql + this._emptyInsertValue;
|
|
210
213
|
} else {
|
|
211
|
-
|
|
212
|
-
sql += `(${this.formatter.columnize(insertData.columns)}`;
|
|
213
|
-
sql += `) ${returningSql}values (` + this._buildInsertValues(insertData) + ")";
|
|
214
|
-
} else if (insertValues.length === 1 && insertValues[0]) {
|
|
215
|
-
sql += returningSql + this._emptyInsertValue;
|
|
216
|
-
} else {
|
|
217
|
-
return "";
|
|
218
|
-
}
|
|
214
|
+
return "";
|
|
219
215
|
}
|
|
220
216
|
return sql;
|
|
221
217
|
}
|
|
@@ -280,6 +276,7 @@ var IBMiQueryCompiler = class extends import_querycompiler.default {
|
|
|
280
276
|
const { returning } = this.single;
|
|
281
277
|
let sql = "";
|
|
282
278
|
if (returning) {
|
|
279
|
+
console.error("IBMi DB2 does not support returning in update statements, only inserts");
|
|
283
280
|
sql += `select ${this.formatter.columnize(this.single.returning)} from FINAL TABLE(`;
|
|
284
281
|
}
|
|
285
282
|
sql += withSQL + `update ${this.single.only ? "only " : ""}${this.tableName} set ` + updates.join(", ") + (where ? ` ${where}` : "") + (order ? ` ${order}` : "") + (limit ? ` ${limit}` : "");
|
|
@@ -412,42 +409,61 @@ var DB2Client = class extends import_knex.knex.Client {
|
|
|
412
409
|
}
|
|
413
410
|
// Runs the query on the specified connection, providing the bindings
|
|
414
411
|
async _query(connection, obj) {
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
if (method === "select" || method === "first" || method === "pluck") {
|
|
421
|
-
const rows = await connection.query(obj.sql, obj.bindings);
|
|
422
|
-
if (rows) {
|
|
423
|
-
obj.response = { rows, rowCount: rows.length };
|
|
424
|
-
}
|
|
412
|
+
const queryObject = this.normalizeQueryObject(obj);
|
|
413
|
+
const method = this.determineQueryMethod(queryObject);
|
|
414
|
+
queryObject.sqlMethod = method;
|
|
415
|
+
if (this.isSelectMethod(method)) {
|
|
416
|
+
await this.executeSelectQuery(connection, queryObject);
|
|
425
417
|
} else {
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
if (result.statement.includes("IDENTITY_VAL_LOCAL()")) {
|
|
435
|
-
obj.response = {
|
|
436
|
-
rows: result.map(
|
|
437
|
-
(row) => result.columns && result.columns?.length > 0 ? row[result.columns[0].name] : row
|
|
438
|
-
),
|
|
439
|
-
rowCount: result.count
|
|
440
|
-
};
|
|
441
|
-
} else {
|
|
442
|
-
obj.response = { rows: result, rowCount: result.count };
|
|
443
|
-
}
|
|
444
|
-
} catch (err) {
|
|
445
|
-
this.printError(JSON.stringify(err));
|
|
446
|
-
}
|
|
418
|
+
await this.executeStatementQuery(connection, queryObject);
|
|
419
|
+
}
|
|
420
|
+
this.printDebug(queryObject);
|
|
421
|
+
return queryObject;
|
|
422
|
+
}
|
|
423
|
+
normalizeQueryObject(obj) {
|
|
424
|
+
if (!obj || typeof obj === "string") {
|
|
425
|
+
return { sql: obj };
|
|
447
426
|
}
|
|
448
|
-
this.printDebug(obj);
|
|
449
427
|
return obj;
|
|
450
428
|
}
|
|
429
|
+
determineQueryMethod(obj) {
|
|
430
|
+
return (obj.hasOwnProperty("method") && obj.method !== "raw" ? obj.method : obj.sql.split(" ")[0]).toLowerCase();
|
|
431
|
+
}
|
|
432
|
+
isSelectMethod(method) {
|
|
433
|
+
return method === "select" || method === "first" || method === "pluck";
|
|
434
|
+
}
|
|
435
|
+
async executeSelectQuery(connection, obj) {
|
|
436
|
+
const rows = await connection.query(obj.sql, obj.bindings);
|
|
437
|
+
if (rows) {
|
|
438
|
+
obj.response = { rows, rowCount: rows.length };
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
async executeStatementQuery(connection, obj) {
|
|
442
|
+
try {
|
|
443
|
+
const statement = await connection.createStatement();
|
|
444
|
+
await statement.prepare(obj.sql);
|
|
445
|
+
if (obj.bindings) {
|
|
446
|
+
await statement.bind(obj.bindings);
|
|
447
|
+
}
|
|
448
|
+
const result = await statement.execute();
|
|
449
|
+
this.printDebug(String(result));
|
|
450
|
+
obj.response = this.formatStatementResponse(result);
|
|
451
|
+
} catch (err) {
|
|
452
|
+
this.printError(JSON.stringify(err));
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
formatStatementResponse(result) {
|
|
456
|
+
if (result.statement.includes("IDENTITY_VAL_LOCAL()")) {
|
|
457
|
+
return {
|
|
458
|
+
rows: result.map(
|
|
459
|
+
(row) => result.columns && result.columns?.length > 0 ? row[result.columns[0].name] : row
|
|
460
|
+
),
|
|
461
|
+
rowCount: result.count
|
|
462
|
+
};
|
|
463
|
+
} else {
|
|
464
|
+
return { rows: result, rowCount: result.count };
|
|
465
|
+
}
|
|
466
|
+
}
|
|
451
467
|
async _stream(connection, obj, stream, options) {
|
|
452
468
|
if (!obj.sql) throw new Error("A query is required to stream results");
|
|
453
469
|
return new Promise((resolve, reject) => {
|
|
@@ -463,29 +479,9 @@ var DB2Client = class extends import_knex.knex.Client {
|
|
|
463
479
|
(error, cursor) => {
|
|
464
480
|
if (error) {
|
|
465
481
|
this.printError(JSON.stringify(error, null, 2));
|
|
482
|
+
return;
|
|
466
483
|
}
|
|
467
|
-
const readableStream =
|
|
468
|
-
objectMode: true,
|
|
469
|
-
read() {
|
|
470
|
-
cursor.fetch((error2, result) => {
|
|
471
|
-
if (error2) {
|
|
472
|
-
console.log(JSON.stringify(error2, null, 2));
|
|
473
|
-
}
|
|
474
|
-
if (!cursor.noData) {
|
|
475
|
-
this.push(result);
|
|
476
|
-
} else {
|
|
477
|
-
cursor.close((error3) => {
|
|
478
|
-
if (error3) {
|
|
479
|
-
console.log(JSON.stringify(error3, null, 2));
|
|
480
|
-
}
|
|
481
|
-
if (result) {
|
|
482
|
-
this.push(result);
|
|
483
|
-
}
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
});
|
|
487
|
-
}
|
|
488
|
-
});
|
|
484
|
+
const readableStream = this._createCursorStream(cursor);
|
|
489
485
|
readableStream.on("error", (err) => {
|
|
490
486
|
reject(err);
|
|
491
487
|
stream.emit("error", err);
|
|
@@ -495,6 +491,32 @@ var DB2Client = class extends import_knex.knex.Client {
|
|
|
495
491
|
);
|
|
496
492
|
});
|
|
497
493
|
}
|
|
494
|
+
_createCursorStream(cursor) {
|
|
495
|
+
const parentThis = this;
|
|
496
|
+
return new import_node_stream.Readable({
|
|
497
|
+
objectMode: true,
|
|
498
|
+
read() {
|
|
499
|
+
cursor.fetch((error, result) => {
|
|
500
|
+
if (error) {
|
|
501
|
+
parentThis.printError(JSON.stringify(error, null, 2));
|
|
502
|
+
}
|
|
503
|
+
if (!cursor.noData) {
|
|
504
|
+
this.push(result);
|
|
505
|
+
} else {
|
|
506
|
+
cursor.close((closeError) => {
|
|
507
|
+
if (closeError) {
|
|
508
|
+
parentThis.printError(JSON.stringify(closeError, null, 2));
|
|
509
|
+
}
|
|
510
|
+
if (result) {
|
|
511
|
+
this.push(result);
|
|
512
|
+
}
|
|
513
|
+
this.push(null);
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
}
|
|
498
520
|
transaction(container, config, outerTx) {
|
|
499
521
|
return new ibmi_transaction_default(this, container, config, outerTx);
|
|
500
522
|
}
|
|
@@ -512,30 +534,40 @@ var DB2Client = class extends import_knex.knex.Client {
|
|
|
512
534
|
}
|
|
513
535
|
processResponse(obj, runner) {
|
|
514
536
|
if (obj === null) return null;
|
|
515
|
-
const
|
|
516
|
-
|
|
517
|
-
|
|
537
|
+
const validationResult = this.validateResponse(obj);
|
|
538
|
+
if (validationResult !== null) return validationResult;
|
|
539
|
+
const { response } = obj;
|
|
540
|
+
if (obj.output) {
|
|
541
|
+
return obj.output(runner, response);
|
|
542
|
+
}
|
|
543
|
+
return this.processSqlMethod(obj);
|
|
544
|
+
}
|
|
545
|
+
validateResponse(obj) {
|
|
546
|
+
if (!obj.response) {
|
|
518
547
|
this.printDebug("response undefined" + obj);
|
|
548
|
+
return void 0;
|
|
519
549
|
}
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
550
|
+
if (!obj.response.rows) {
|
|
551
|
+
return this.printError("rows undefined" + obj);
|
|
552
|
+
}
|
|
553
|
+
return null;
|
|
554
|
+
}
|
|
555
|
+
processSqlMethod(obj) {
|
|
556
|
+
const { rows, rowCount } = obj.response;
|
|
557
|
+
switch (obj.sqlMethod) {
|
|
558
|
+
case "select" /* SELECT */:
|
|
524
559
|
return rows;
|
|
525
|
-
case "pluck"
|
|
560
|
+
case "pluck" /* PLUCK */:
|
|
526
561
|
return rows.map(obj.pluck);
|
|
527
|
-
case "first"
|
|
562
|
+
case "first" /* FIRST */:
|
|
528
563
|
return rows[0];
|
|
529
|
-
case "insert"
|
|
564
|
+
case "insert" /* INSERT */:
|
|
530
565
|
return rows;
|
|
531
|
-
case "del"
|
|
532
|
-
case "delete"
|
|
533
|
-
case "update"
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
}
|
|
537
|
-
return rowCount;
|
|
538
|
-
case "counter":
|
|
566
|
+
case "del" /* DELETE */:
|
|
567
|
+
case "delete" /* DELETE_ALT */:
|
|
568
|
+
case "update" /* UPDATE */:
|
|
569
|
+
return obj.select ? rows : rowCount;
|
|
570
|
+
case "counter" /* COUNTER */:
|
|
539
571
|
return rowCount;
|
|
540
572
|
default:
|
|
541
573
|
return rows;
|