@bdkinc/knex-ibmi 0.0.2 → 0.0.4

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/dist/index.mjs CHANGED
@@ -1,103 +1,336 @@
1
- // src/index.ts
2
- import * as process from "process";
3
- import knex from "knex";
4
- import * as odbc from "odbc";
5
- var DB2Client = class extends knex.Client {
6
- constructor(config = {}) {
7
- super(config);
8
- this.driverName = "odbc";
9
- if (this.driverName && config.connection) {
10
- this.initializeDriver();
11
- if (!config.pool || config.pool && config.pool.max !== 0) {
12
- this.initializePool(config);
13
- }
14
- }
15
- }
16
- _driver() {
17
- return odbc;
18
- }
19
- wrapIdentifierImpl(value) {
20
- return value;
21
- }
22
- printDebug(message) {
23
- if (process.env.DEBUG === "true") {
24
- this.logger.debug(message);
25
- }
26
- }
27
- // Get a raw connection, called by the pool manager whenever a new
28
- // connection needs to be added to the pool.
29
- async acquireRawConnection() {
30
- this.printDebug("acquiring raw connection");
31
- const connectionConfig = this.config.connection;
32
- return await this.driver.connect(
33
- this._getConnectionString(connectionConfig)
34
- );
35
- }
36
- // Used to explicitly close a connection, called internally by the pool manager
37
- // when a connection times out or the pool is shutdown.
38
- async destroyRawConnection(connection) {
39
- return await connection.close();
40
- }
41
- _getConnectionString(connectionConfig = {}) {
42
- const connectionStringParams = connectionConfig.connectionStringParams || {};
43
- const connectionStringExtension = Object.keys(
44
- connectionStringParams
45
- ).reduce((result, key) => {
46
- const value = connectionStringParams[key];
47
- return `${result}${key}=${value};`;
48
- }, "");
49
- return `${`DRIVER=${connectionConfig.driver};SYSTEM=${connectionConfig.host};HOSTNAME=${connectionConfig.host};PORT=${connectionConfig.port};DATABASE=${connectionConfig.database};UID=${connectionConfig.user};PWD=${connectionConfig.password};`}${connectionStringExtension}`;
50
- }
51
- // Runs the query on the specified connection, providing the bindings
52
- // and any other necessary prep work.
53
- async _query(connection, obj) {
54
- if (!obj || typeof obj == "string")
55
- obj = { sql: obj };
56
- const method = (obj.method !== "raw" ? obj.method : obj.sql.split(" ")[0]).toLowerCase();
57
- obj.sqlMethod = method;
58
- if (method === "select" || method === "first" || method === "pluck") {
59
- const rows = await connection.query(obj.sql, obj.bindings);
60
- if (rows) {
61
- obj.response = { rows, rowCount: rows.length };
62
- }
63
- return obj;
64
- }
65
- const statement = await connection.createStatement();
66
- await statement.prepare(obj.sql);
67
- await statement.bind(obj.bindings);
68
- obj.response = await statement.execute();
69
- return obj;
70
- }
71
- processResponse(obj, runner) {
72
- if (obj === null)
73
- return null;
74
- const resp = obj.response;
75
- const method = obj.sqlMethod;
76
- const { rows } = resp;
77
- if (obj.output)
78
- return obj.output.call(runner, resp);
79
- switch (method) {
80
- case "select":
81
- case "pluck":
82
- case "first": {
83
- if (method === "pluck")
84
- return rows.map(obj.pluck);
85
- return method === "first" ? rows[0] : rows;
86
- }
87
- case "insert":
88
- case "del":
89
- case "delete":
90
- case "update":
91
- case "counter":
92
- return resp.rowCount;
93
- default:
94
- return resp;
95
- }
96
- }
97
- };
98
- var DB2Dialect = DB2Client;
99
- var src_default = DB2Client;
100
- export {
101
- DB2Dialect,
102
- src_default as default
103
- };
1
+ // src/index.ts
2
+ import * as process from "process";
3
+ import knex from "knex";
4
+ import * as odbc from "odbc";
5
+ import * as console3 from "console";
6
+
7
+ // src/schema/ibmi-compiler.ts
8
+ import SchemaCompiler from "knex/lib/schema/compiler";
9
+ import * as console from "console";
10
+ var IBMiSchemaCompiler = class extends SchemaCompiler {
11
+ constructor(client, builder) {
12
+ super(client, builder);
13
+ }
14
+ hasTable(tableName) {
15
+ const formattedTable = this.client.parameter(
16
+ // @ts-ignore
17
+ prefixedTableName(this.schema, tableName),
18
+ // @ts-ignore
19
+ this.builder,
20
+ // @ts-ignore
21
+ this.bindingsHolder
22
+ );
23
+ const bindings = [tableName.toUpperCase()];
24
+ let sql = `SELECT TABLE_NAME FROM QSYS2.SYSTABLES WHERE TYPE = 'T' AND TABLE_NAME = ${formattedTable}`;
25
+ if (this.schema) {
26
+ sql += " AND TABLE_SCHEMA = ?";
27
+ bindings.push(this.schema);
28
+ }
29
+ this.pushQuery({
30
+ sql,
31
+ bindings,
32
+ output: (resp) => {
33
+ return resp.rowCount > 0;
34
+ }
35
+ });
36
+ }
37
+ toSQL() {
38
+ const sequence = this.builder._sequence;
39
+ for (let i = 0, l = sequence.length; i < l; i++) {
40
+ const query = sequence[i];
41
+ console.log(query.method, query);
42
+ this[query.method].apply(this, query.args);
43
+ }
44
+ return this.sequence;
45
+ }
46
+ };
47
+ function prefixedTableName(prefix, table) {
48
+ return prefix ? `${prefix}.${table}` : table;
49
+ }
50
+ var ibmi_compiler_default = IBMiSchemaCompiler;
51
+
52
+ // src/schema/ibmi-tablecompiler.ts
53
+ import TableCompiler from "knex/lib/schema/tablecompiler";
54
+ var IBMiTableCompiler = class extends TableCompiler {
55
+ createQuery(columns, ifNot, like) {
56
+ let createStatement = ifNot ? `if object_id('${this.tableName()}', 'U') is null ` : "";
57
+ if (like) {
58
+ createStatement += `SELECT * INTO ${this.tableName()} FROM ${this.tableNameLike()} WHERE 0=1`;
59
+ } else {
60
+ createStatement += "CREATE TABLE " + // @ts-ignore
61
+ this.tableName() + // @ts-ignore
62
+ (this._formatting ? " (\n " : " (") + // @ts-ignore
63
+ columns.sql.join(this._formatting ? ",\n " : ", ") + // @ts-ignore
64
+ this._addChecks() + ")";
65
+ }
66
+ this.pushQuery(createStatement);
67
+ if (this.single.comment) {
68
+ this.comment(this.single.comment);
69
+ }
70
+ if (like) {
71
+ this.addColumns(columns, this.addColumnsPrefix);
72
+ }
73
+ }
74
+ // All of the columns to "add" for the query
75
+ addColumns(columns, prefix) {
76
+ prefix = prefix || this.addColumnsPrefix;
77
+ if (columns.sql.length > 0) {
78
+ const columnSql = columns.sql.map((column) => {
79
+ return prefix + column;
80
+ });
81
+ this.pushQuery({
82
+ sql: (
83
+ // @ts-ignore
84
+ (this.lowerCase ? "alter table " : "ALTER TABLE ") + // @ts-ignore
85
+ this.tableName() + " " + columnSql.join(" ")
86
+ ),
87
+ bindings: columns.bindings
88
+ });
89
+ }
90
+ }
91
+ async commit(conn, value) {
92
+ return await conn.commit();
93
+ }
94
+ };
95
+ var ibmi_tablecompiler_default = IBMiTableCompiler;
96
+
97
+ // src/schema/ibmi-columncompiler.ts
98
+ import ColumnCompiler from "knex/lib/schema/columncompiler";
99
+ var IBMiColumnCompiler = class extends ColumnCompiler {
100
+ increments(options = { primaryKey: true }) {
101
+ return "int not null generated always as identity (start with 1, increment by 1)" + // @ts-ignore
102
+ (this.tableCompiler._canBeAddPrimaryKey(options) ? " primary key" : "");
103
+ }
104
+ };
105
+ var ibmi_columncompiler_default = IBMiColumnCompiler;
106
+
107
+ // src/execution/ibmi-transaction.ts
108
+ import Transaction from "knex/lib/execution/transaction";
109
+ import * as console2 from "console";
110
+ var IBMiTransaction = class extends Transaction {
111
+ async begin(conn) {
112
+ const connection = await conn.connect();
113
+ await connection.beginTransaction();
114
+ return connection;
115
+ }
116
+ async rollback(conn) {
117
+ console2.log({ conn });
118
+ const connection = await conn.connect();
119
+ await connection.rollback();
120
+ return connection;
121
+ }
122
+ async commit(conn) {
123
+ await conn.commit();
124
+ return conn;
125
+ }
126
+ };
127
+ var ibmi_transaction_default = IBMiTransaction;
128
+
129
+ // src/query/ibmi-querycompiler.ts
130
+ import QueryCompiler from "knex/lib/query/querycompiler";
131
+ import isObject from "lodash/isObject";
132
+ import { rawOrFn as rawOrFn_ } from "knex/lib/formatter/wrappingFormatter";
133
+ import { format } from "date-fns";
134
+ var IBMiQueryCompiler = class extends QueryCompiler {
135
+ _prepInsert(data) {
136
+ if (isObject(data)) {
137
+ if (data.hasOwnProperty("migration_time")) {
138
+ const parsed = new Date(data.migration_time);
139
+ data.migration_time = format(parsed, "yyyy-MM-dd HH:mm:ss");
140
+ }
141
+ }
142
+ const isRaw = rawOrFn_(
143
+ data,
144
+ void 0,
145
+ // @ts-ignore
146
+ this.builder,
147
+ // @ts-ignore
148
+ this.client,
149
+ // @ts-ignore
150
+ this.bindingsHolder
151
+ );
152
+ if (isRaw)
153
+ return isRaw;
154
+ let columns = [];
155
+ const values = [];
156
+ if (!Array.isArray(data))
157
+ data = data ? [data] : [];
158
+ let i = -1;
159
+ while (++i < data.length) {
160
+ if (data[i] == null)
161
+ break;
162
+ if (i === 0)
163
+ columns = Object.keys(data[i]).sort();
164
+ const row = new Array(columns.length);
165
+ const keys = Object.keys(data[i]);
166
+ let j = -1;
167
+ while (++j < keys.length) {
168
+ const key = keys[j];
169
+ let idx = columns.indexOf(key);
170
+ if (idx === -1) {
171
+ columns = columns.concat(key).sort();
172
+ idx = columns.indexOf(key);
173
+ let k = -1;
174
+ while (++k < values.length) {
175
+ values[k].splice(idx, 0, void 0);
176
+ }
177
+ row.splice(idx, 0, void 0);
178
+ }
179
+ row[idx] = data[i][key];
180
+ }
181
+ values.push(row);
182
+ }
183
+ return {
184
+ columns,
185
+ values
186
+ };
187
+ }
188
+ };
189
+ var ibmi_querycompiler_default = IBMiQueryCompiler;
190
+
191
+ // src/index.ts
192
+ var DB2Client = class extends knex.Client {
193
+ constructor(config) {
194
+ super(config);
195
+ this.driverName = "odbc";
196
+ if (this.dialect && !this.config.client) {
197
+ this.logger.warn(
198
+ `Using 'this.dialect' to identify the client is deprecated and support for it will be removed in the future. Please use configuration option 'client' instead.`
199
+ );
200
+ }
201
+ const dbClient = this.config.client || this.dialect;
202
+ if (!dbClient) {
203
+ throw new Error(
204
+ `knex: Required configuration option 'client' is missing.`
205
+ );
206
+ }
207
+ if (config.version) {
208
+ this.version = config.version;
209
+ }
210
+ if (this.driverName && config.connection) {
211
+ this.initializeDriver();
212
+ if (!config.pool || config.pool && config.pool.max !== 0) {
213
+ this.initializePool(config);
214
+ }
215
+ }
216
+ this.valueForUndefined = this.raw("DEFAULT");
217
+ if (config.useNullAsDefault) {
218
+ this.valueForUndefined = null;
219
+ }
220
+ }
221
+ _driver() {
222
+ return odbc;
223
+ }
224
+ wrapIdentifierImpl(value) {
225
+ if (value.includes("knex_migrations")) {
226
+ return value.toUpperCase();
227
+ }
228
+ return value;
229
+ }
230
+ printDebug(message) {
231
+ if (process.env.DEBUG === "true") {
232
+ this.logger.debug(message);
233
+ }
234
+ }
235
+ // Get a raw connection, called by the pool manager whenever a new
236
+ // connection needs to be added to the pool.
237
+ async acquireRawConnection() {
238
+ this.printDebug("acquiring raw connection");
239
+ const connectionConfig = this.config.connection;
240
+ console3.log(this._getConnectionString(connectionConfig));
241
+ return await this.driver.pool(this._getConnectionString(connectionConfig));
242
+ }
243
+ // Used to explicitly close a connection, called internally by the pool manager
244
+ // when a connection times out or the pool is shutdown.
245
+ async destroyRawConnection(connection) {
246
+ console3.log("destroy connection");
247
+ return await connection.close();
248
+ }
249
+ _getConnectionString(connectionConfig) {
250
+ const connectionStringParams = connectionConfig.connectionStringParams || {};
251
+ const connectionStringExtension = Object.keys(
252
+ connectionStringParams
253
+ ).reduce((result, key) => {
254
+ const value = connectionStringParams[key];
255
+ return `${result}${key}=${value};`;
256
+ }, "");
257
+ return `${`DRIVER=${connectionConfig.driver};SYSTEM=${connectionConfig.host};HOSTNAME=${connectionConfig.host};PORT=${connectionConfig.port};DATABASE=${connectionConfig.database};UID=${connectionConfig.user};PWD=${connectionConfig.password};`}${connectionStringExtension}`;
258
+ }
259
+ // Runs the query on the specified connection, providing the bindings
260
+ // and any other necessary prep work.
261
+ async _query(pool, obj) {
262
+ if (!obj || typeof obj == "string")
263
+ obj = { sql: obj };
264
+ const method = (obj.hasOwnProperty("method") && obj.method !== "raw" ? obj.method : obj.sql.split(" ")[0]).toLowerCase();
265
+ obj.sqlMethod = method;
266
+ if (method === "select" || method === "first" || method === "pluck") {
267
+ const rows = await pool.query(obj.sql, obj.bindings);
268
+ if (rows) {
269
+ obj.response = { rows, rowCount: rows.length };
270
+ }
271
+ } else {
272
+ try {
273
+ const connection = await pool.connect();
274
+ const statement = await connection.createStatement();
275
+ await statement.prepare(obj.sql);
276
+ if (obj.bindings) {
277
+ await statement.bind(obj.bindings);
278
+ }
279
+ const result = await statement.execute();
280
+ obj.response = { rows: [result.count], rowCount: result.count };
281
+ } catch (err) {
282
+ console3.error(err);
283
+ throw new Error(err);
284
+ }
285
+ }
286
+ console3.log({ obj });
287
+ return obj;
288
+ }
289
+ transaction(container, config, outerTx) {
290
+ return new ibmi_transaction_default(this, ...arguments);
291
+ }
292
+ schemaCompiler() {
293
+ return new ibmi_compiler_default(this, ...arguments);
294
+ }
295
+ tableCompiler() {
296
+ return new ibmi_tablecompiler_default(this, ...arguments);
297
+ }
298
+ columnCompiler() {
299
+ return new ibmi_columncompiler_default(this, ...arguments);
300
+ }
301
+ queryCompiler() {
302
+ return new ibmi_querycompiler_default(this, ...arguments);
303
+ }
304
+ processResponse(obj, runner) {
305
+ if (obj === null)
306
+ return null;
307
+ const resp = obj.response;
308
+ const method = obj.sqlMethod;
309
+ const { rows } = resp;
310
+ if (obj.output)
311
+ return obj.output.call(runner, resp);
312
+ switch (method) {
313
+ case "select":
314
+ case "pluck":
315
+ case "first": {
316
+ if (method === "pluck")
317
+ return rows.map(obj.pluck);
318
+ return method === "first" ? rows[0] : rows;
319
+ }
320
+ case "insert":
321
+ case "del":
322
+ case "delete":
323
+ case "update":
324
+ case "counter":
325
+ return resp.rowCount;
326
+ default:
327
+ return resp;
328
+ }
329
+ }
330
+ };
331
+ var DB2Dialect = DB2Client;
332
+ var src_default = DB2Client;
333
+ export {
334
+ DB2Dialect,
335
+ src_default as default
336
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bdkinc/knex-ibmi",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Knex dialect for IBMi",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -58,7 +58,9 @@
58
58
  "LICENSE"
59
59
  ],
60
60
  "dependencies": {
61
+ "date-fns": "^2.30.0",
61
62
  "knex": "^2",
63
+ "lodash": "^4.17.21",
62
64
  "odbc": "^2.4.8"
63
65
  }
64
66
  }
@@ -0,0 +1,24 @@
1
+ import Transaction from "knex/lib/execution/transaction";
2
+ import * as console from "console";
3
+
4
+ class IBMiTransaction extends Transaction {
5
+ async begin(conn) {
6
+ const connection = await conn.connect();
7
+ await connection.beginTransaction();
8
+ return connection;
9
+ }
10
+
11
+ async rollback(conn) {
12
+ console.log({ conn });
13
+ const connection = await conn.connect();
14
+ await connection.rollback();
15
+ return connection;
16
+ }
17
+
18
+ async commit(conn) {
19
+ await conn.commit();
20
+ return conn;
21
+ }
22
+ }
23
+
24
+ export default IBMiTransaction;