@bdkinc/knex-ibmi 0.5.2 → 0.5.3

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.d.mts CHANGED
@@ -109,8 +109,12 @@ interface DB2PoolConfig {
109
109
  acquireConnectionTimeout?: number;
110
110
  }
111
111
  interface DB2ConnectionParams {
112
- CMT?: number;
113
- CONNTYPE?: number;
112
+ DSN?: string;
113
+ SIGNON?: 0 | 1 | 2 | 3 | 4;
114
+ SSL?: 0 | 1;
115
+ CMT?: 0 | 1 | 2 | 3 | 4;
116
+ CONNTYPE?: 0 | 1 | 2;
117
+ DATABASE?: string;
114
118
  DBQ?: string;
115
119
  MAXDECPREC?: 31 | 63;
116
120
  MAXDECSCALE?: number;
@@ -126,17 +130,57 @@ interface DB2ConnectionParams {
126
130
  TSP?: 0 | 1 | 2 | 3;
127
131
  TSFT?: 0 | 1;
128
132
  XMLCURIMPPARSE?: 0 | 1;
129
- XMLDECLARATION?: 1 | 2 | 3 | 4;
130
- ALLOWPROCCALLS?: 0 | 1;
131
- XDYNAMIC?: 0 | 1;
133
+ XMLDECLARATION?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
132
134
  DFTPKGLIB?: string;
133
- PKG?: 0 | 1 | 2;
135
+ PKG?: string;
136
+ XDYNAMIC?: 0 | 1;
134
137
  BLOCKFETCH?: 0 | 1;
138
+ BLOCKSIZE?: number;
135
139
  COMPRESSION?: 0 | 1;
136
140
  CONCURRENCY?: 0 | 1;
137
141
  CURSORSENSITIVITY?: 0 | 1 | 2;
138
- 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";
142
+ EXTCOLINFO?: 0 | 1;
143
+ LAZYCLOSE?: 0 | 1;
144
+ MAXFIELDLEN?: number;
145
+ PREFETCH?: 0 | 1;
146
+ QRYSTGLMT?: number | "*NOMAX";
147
+ QUERYOPTIMIZEGOAL?: 0 | 1 | 2;
148
+ QUERYTIMEOUT?: 0 | 1;
149
+ LANGUAGEID?: "AFR" | "ARA" | "BEL" | "BGR" | "CAT" | "CHS" | "CHT" | "CSY" | "DAN" | "DES" | "DEU" | "ELL" | "ENA" | "ENB" | "ENG" | "ENP" | "ENU" | "ESP" | "EST" | "FAR" | "FIN" | "FRA" | "FRB" | "FRC" | "FRS" | "GAE" | "HEB" | "HRV" | "HUN" | "ISL" | "ITA" | "ITS" | "JPN" | "KOR" | "LAO" | "LVA" | "LTU" | "MKD" | "NLB" | "NLD" | "NON" | "NOR" | "PLK" | "PTB" | "PTG" | "RMS" | "ROM" | "RUS" | "SKY" | "SLO" | "SQI" | "SRB" | "SRL" | "SVE" | "THA" | "TRK" | "UKR" | "URD" | "VIE";
150
+ SORTTABLE?: string;
151
+ SORTTYPE?: 0 | 1 | 2 | 3;
152
+ SORTWEIGHT?: 0 | 1;
153
+ CATALOGOPTIONS?: number;
154
+ LIBVIEW?: 0 | 1 | 2;
155
+ REMARKS?: 0 | 1;
156
+ SEARCHPATTERN?: 0 | 1;
157
+ ALLOWUNSCHAR?: 0 | 1;
158
+ CCSID?: number;
159
+ GRAPHIC?: 0 | 1 | 2 | 3;
160
+ HEXPARSEROPT?: 0 | 1;
161
+ TRANSLATE?: 0 | 1;
162
+ TRIMCHAR?: 0 | 1;
163
+ UNICODESQL?: 0 | 1;
164
+ XLATEDLL?: string;
165
+ XLATEOPT?: number;
166
+ QAQQINILIB?: string;
167
+ SQDIAGCODE?: string;
168
+ TRACE?: number;
169
+ ALWAYSCALCLEN?: 0 | 1;
170
+ ALLOWPROCCALLS?: 0 | 1;
171
+ CONCURRENTACCESSRESOLUTION?: 0 | 1 | 2 | 3;
172
+ DB2SQLSTATES?: 0 | 1;
173
+ DATETIMETOCHAR?: number;
174
+ DBCSNoTruncError?: 0 | 1;
175
+ DEBUG?: number;
176
+ KEEPALIVE?: 0 | 1 | 2;
177
+ LOGINTIMEOUT?: number;
178
+ TIMEOUT?: number;
139
179
  TRUEAUTOCOMMIT?: 0 | 1;
180
+ NEWPWD?: string;
181
+ XALCS?: 0 | 1;
182
+ XALOCKTIMEOUT?: number;
183
+ XATXNTIMEOUT?: number;
140
184
  }
141
185
  interface DB2ConnectionConfig {
142
186
  database: string;
package/dist/index.d.ts CHANGED
@@ -109,8 +109,12 @@ interface DB2PoolConfig {
109
109
  acquireConnectionTimeout?: number;
110
110
  }
111
111
  interface DB2ConnectionParams {
112
- CMT?: number;
113
- CONNTYPE?: number;
112
+ DSN?: string;
113
+ SIGNON?: 0 | 1 | 2 | 3 | 4;
114
+ SSL?: 0 | 1;
115
+ CMT?: 0 | 1 | 2 | 3 | 4;
116
+ CONNTYPE?: 0 | 1 | 2;
117
+ DATABASE?: string;
114
118
  DBQ?: string;
115
119
  MAXDECPREC?: 31 | 63;
116
120
  MAXDECSCALE?: number;
@@ -126,17 +130,57 @@ interface DB2ConnectionParams {
126
130
  TSP?: 0 | 1 | 2 | 3;
127
131
  TSFT?: 0 | 1;
128
132
  XMLCURIMPPARSE?: 0 | 1;
129
- XMLDECLARATION?: 1 | 2 | 3 | 4;
130
- ALLOWPROCCALLS?: 0 | 1;
131
- XDYNAMIC?: 0 | 1;
133
+ XMLDECLARATION?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
132
134
  DFTPKGLIB?: string;
133
- PKG?: 0 | 1 | 2;
135
+ PKG?: string;
136
+ XDYNAMIC?: 0 | 1;
134
137
  BLOCKFETCH?: 0 | 1;
138
+ BLOCKSIZE?: number;
135
139
  COMPRESSION?: 0 | 1;
136
140
  CONCURRENCY?: 0 | 1;
137
141
  CURSORSENSITIVITY?: 0 | 1 | 2;
138
- 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";
142
+ EXTCOLINFO?: 0 | 1;
143
+ LAZYCLOSE?: 0 | 1;
144
+ MAXFIELDLEN?: number;
145
+ PREFETCH?: 0 | 1;
146
+ QRYSTGLMT?: number | "*NOMAX";
147
+ QUERYOPTIMIZEGOAL?: 0 | 1 | 2;
148
+ QUERYTIMEOUT?: 0 | 1;
149
+ LANGUAGEID?: "AFR" | "ARA" | "BEL" | "BGR" | "CAT" | "CHS" | "CHT" | "CSY" | "DAN" | "DES" | "DEU" | "ELL" | "ENA" | "ENB" | "ENG" | "ENP" | "ENU" | "ESP" | "EST" | "FAR" | "FIN" | "FRA" | "FRB" | "FRC" | "FRS" | "GAE" | "HEB" | "HRV" | "HUN" | "ISL" | "ITA" | "ITS" | "JPN" | "KOR" | "LAO" | "LVA" | "LTU" | "MKD" | "NLB" | "NLD" | "NON" | "NOR" | "PLK" | "PTB" | "PTG" | "RMS" | "ROM" | "RUS" | "SKY" | "SLO" | "SQI" | "SRB" | "SRL" | "SVE" | "THA" | "TRK" | "UKR" | "URD" | "VIE";
150
+ SORTTABLE?: string;
151
+ SORTTYPE?: 0 | 1 | 2 | 3;
152
+ SORTWEIGHT?: 0 | 1;
153
+ CATALOGOPTIONS?: number;
154
+ LIBVIEW?: 0 | 1 | 2;
155
+ REMARKS?: 0 | 1;
156
+ SEARCHPATTERN?: 0 | 1;
157
+ ALLOWUNSCHAR?: 0 | 1;
158
+ CCSID?: number;
159
+ GRAPHIC?: 0 | 1 | 2 | 3;
160
+ HEXPARSEROPT?: 0 | 1;
161
+ TRANSLATE?: 0 | 1;
162
+ TRIMCHAR?: 0 | 1;
163
+ UNICODESQL?: 0 | 1;
164
+ XLATEDLL?: string;
165
+ XLATEOPT?: number;
166
+ QAQQINILIB?: string;
167
+ SQDIAGCODE?: string;
168
+ TRACE?: number;
169
+ ALWAYSCALCLEN?: 0 | 1;
170
+ ALLOWPROCCALLS?: 0 | 1;
171
+ CONCURRENTACCESSRESOLUTION?: 0 | 1 | 2 | 3;
172
+ DB2SQLSTATES?: 0 | 1;
173
+ DATETIMETOCHAR?: number;
174
+ DBCSNoTruncError?: 0 | 1;
175
+ DEBUG?: number;
176
+ KEEPALIVE?: 0 | 1 | 2;
177
+ LOGINTIMEOUT?: number;
178
+ TIMEOUT?: number;
139
179
  TRUEAUTOCOMMIT?: 0 | 1;
180
+ NEWPWD?: string;
181
+ XALCS?: 0 | 1;
182
+ XALOCKTIMEOUT?: number;
183
+ XATXNTIMEOUT?: number;
140
184
  }
141
185
  interface DB2ConnectionConfig {
142
186
  database: string;
package/dist/index.js CHANGED
@@ -1161,7 +1161,9 @@ var DB2Client = class extends import_knex.default.Client {
1161
1161
  statement = cache.get(obj.sql);
1162
1162
  if (statement) {
1163
1163
  usedCache = true;
1164
- this.printDebug(`Using cached statement for: ${obj.sql.substring(0, 50)}...`);
1164
+ this.printDebug(
1165
+ `Using cached statement for: ${obj.sql.substring(0, 50)}...`
1166
+ );
1165
1167
  } else {
1166
1168
  statement = await connection.createStatement();
1167
1169
  await statement.prepare(obj.sql);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/schema/ibmi-compiler.ts","../src/schema/ibmi-tablecompiler.ts","../src/schema/ibmi-columncompiler.ts","../src/execution/ibmi-transaction.ts","../src/query/ibmi-querycompiler.ts","../src/migrations/ibmi-migration-runner.ts"],"sourcesContent":["import process from \"node:process\";\nimport knex, { Knex } from \"knex\";\nimport odbc, { Connection } from \"odbc\";\nimport SchemaCompiler from \"./schema/ibmi-compiler\";\nimport TableCompiler from \"./schema/ibmi-tablecompiler\";\nimport ColumnCompiler from \"./schema/ibmi-columncompiler\";\nimport Transaction from \"./execution/ibmi-transaction\";\nimport QueryCompiler from \"./query/ibmi-querycompiler\";\nimport { Readable } from \"node:stream\";\nimport {\n IBMiMigrationRunner,\n createIBMiMigrationRunner,\n} from \"./migrations/ibmi-migration-runner\";\n\ninterface QueryObject {\n response?: {\n rows: any[];\n rowCount: number;\n };\n sqlMethod: SqlMethod;\n output?: (runner: any, response: any) => any;\n pluck?: (row: any) => any;\n select?: boolean;\n}\n\nenum SqlMethod {\n SELECT = \"select\",\n PLUCK = \"pluck\",\n FIRST = \"first\",\n INSERT = \"insert\",\n DELETE = \"del\",\n DELETE_ALT = \"delete\",\n UPDATE = \"update\",\n COUNTER = \"counter\",\n}\n\n// Simple LRU cache for prepared statements\nclass StatementCache {\n private cache = new Map<string, any>();\n private maxSize: number;\n\n constructor(maxSize: number = 100) {\n this.maxSize = maxSize;\n }\n\n get(sql: string): any | undefined {\n const stmt = this.cache.get(sql);\n if (stmt) {\n // Move to end (most recently used)\n this.cache.delete(sql);\n this.cache.set(sql, stmt);\n }\n return stmt;\n }\n\n set(sql: string, stmt: any): void {\n // Remove oldest if at capacity\n if (this.cache.size >= this.maxSize) {\n const firstKey = this.cache.keys().next().value;\n const oldStmt = this.cache.get(firstKey);\n this.cache.delete(firstKey);\n // Close the evicted statement\n if (oldStmt && typeof oldStmt.close === 'function') {\n oldStmt.close().catch(() => {});\n }\n }\n this.cache.set(sql, stmt);\n }\n\n async clear(): Promise<void> {\n const statements = Array.from(this.cache.values());\n this.cache.clear();\n // Close all cached statements\n await Promise.all(\n statements.map((stmt) =>\n stmt && typeof stmt.close === 'function'\n ? stmt.close().catch(() => {})\n : Promise.resolve()\n )\n );\n }\n\n size(): number {\n return this.cache.size;\n }\n}\n\nclass DB2Client extends knex.Client {\n // Per-connection statement cache (WeakMap so it's GC'd with connections)\n private statementCaches = new WeakMap<Connection, StatementCache>();\n\n constructor(config: Knex.Config<DB2Config>) {\n super(config);\n this.driverName = \"odbc\";\n\n if (this.dialect && !this.config.client) {\n this.printWarn(\n `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.`\n );\n }\n\n const dbClient = this.config.client || this.dialect;\n if (!dbClient) {\n throw new Error(\n `knex: Required configuration option 'client' is missing.`\n );\n }\n\n if (config.version) {\n this.version = config.version;\n }\n\n if (this.driverName && config.connection) {\n this.initializeDriver();\n if (!config.pool || (config.pool && config.pool.max !== 0)) {\n this.initializePool(config);\n }\n }\n\n this.valueForUndefined = this.raw(\"DEFAULT\");\n if (config.useNullAsDefault) {\n this.valueForUndefined = null;\n }\n }\n\n // Helper method to safely stringify objects that might have circular references\n private safeStringify(obj: any, indent: number = 0): string {\n try {\n return JSON.stringify(obj, null, indent);\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"circular\")) {\n return `[Circular structure - ${typeof obj}]`;\n }\n return `[Stringify error - ${typeof obj}]`;\n }\n }\n\n _driver() {\n return odbc;\n }\n\n wrapIdentifierImpl(value: string) {\n // override default wrapper (\")\n // we don't want to use it since\n // it makes identifier case-sensitive in DB2\n\n if (!value) return value;\n\n // Handle migration tables specifically - keep simple for now\n if (\n value.includes(\"KNEX_MIGRATIONS\") ||\n value.includes(\"knex_migrations\")\n ) {\n return value.toUpperCase();\n }\n\n // For now, just return the value as-is to avoid binding issues\n // IBM i DB2 is case-insensitive by default anyway\n return value;\n }\n\n printDebug(message: string) {\n if (process.env.DEBUG === \"true\") {\n if (this.logger.debug) {\n this.logger.debug(\"knex-ibmi: \" + message);\n }\n }\n }\n\n printError(message: string) {\n if (this.logger.error) {\n this.logger.error(\"knex-ibmi: \" + message);\n }\n }\n\n printWarn(message: string) {\n if (process.env.DEBUG === \"true\") {\n if (this.logger.warn) {\n this.logger.warn(\"knex-ibmi: \" + message);\n }\n }\n }\n\n // Get a raw connection, called by the pool manager whenever a new\n // connection needs to be added to the pool.\n async acquireRawConnection() {\n this.printDebug(\"acquiring raw connection\");\n const connectionConfig = this.config.connection as DB2ConnectionConfig;\n\n if (!connectionConfig) {\n throw new Error(\"There is no connection config defined\");\n }\n\n this.printDebug(\n \"connection config: \" + this._getConnectionString(connectionConfig)\n );\n\n // Use simple ODBC connection - Knex manages the pooling\n // This fixes the double-pooling bug where a new ODBC pool was created per connection\n const connection = await this.driver.connect(\n this._getConnectionString(connectionConfig)\n );\n\n return connection;\n }\n\n // Used to explicitly close a connection, called internally by the pool manager\n // when a connection times out or the pool is shutdown.\n async destroyRawConnection(connection: any) {\n this.printDebug(\"destroy connection\");\n \n // Clean up statement cache if it exists\n const cache = this.statementCaches.get(connection);\n if (cache) {\n await cache.clear();\n this.statementCaches.delete(connection);\n }\n \n return await connection.close();\n }\n\n _getConnectionString(connectionConfig: DB2ConnectionConfig) {\n // Apply performance defaults if not explicitly set\n const defaults: DB2ConnectionParams = {\n BLOCKFETCH: 1, // Enable block fetch for better performance\n TRUEAUTOCOMMIT: 0, // Use proper transaction handling\n };\n\n // Merge defaults with user-provided params (user params take precedence)\n const connectionStringParams = {\n ...defaults,\n ...(connectionConfig.connectionStringParams || {}),\n };\n\n const connectionStringExtension = Object.keys(\n connectionStringParams\n ).reduce((result, key) => {\n const value = connectionStringParams[key];\n return `${result}${key}=${value};`;\n }, \"\");\n\n return (\n `DRIVER=${connectionConfig.driver};` +\n `SYSTEM=${connectionConfig.host};` +\n `PORT=${connectionConfig.port || 8471};` +\n `DATABASE=${connectionConfig.database};` +\n `UID=${connectionConfig.user};` +\n `PWD=${connectionConfig.password};` +\n connectionStringExtension\n );\n }\n\n // Runs the query on the specified connection, providing the bindings\n async _query(connection: Connection, obj: any) {\n const queryObject = this.normalizeQueryObject(obj);\n const method = this.determineQueryMethod(queryObject);\n queryObject.sqlMethod = method;\n\n // Special handling for UPDATE with returning clause\n if (queryObject._ibmiUpdateReturning) {\n return await this.executeUpdateReturning(connection, queryObject);\n }\n\n // Sequential multi-row insert execution path\n if (queryObject._ibmiSequentialInsert) {\n return await this.executeSequentialInsert(connection, queryObject);\n }\n\n // DELETE ... RETURNING emulation\n if (queryObject._ibmiDeleteReturning) {\n return await this.executeDeleteReturning(connection, queryObject);\n }\n\n // Debug migration queries (only if DEBUG environment variable is set)\n if (\n process.env.DEBUG === \"true\" &&\n queryObject.sql &&\n (queryObject.sql.toLowerCase().includes(\"create table\") ||\n queryObject.sql.toLowerCase().includes(\"knex_migrations\"))\n ) {\n this.printDebug(\n `Executing ${method} query: ${queryObject.sql.substring(0, 200)}...`\n );\n if (queryObject.bindings?.length) {\n this.printDebug(\n `Bindings: ${this.safeStringify(queryObject.bindings)}`\n );\n }\n }\n\n try {\n const startTime = Date.now();\n if (this.isSelectMethod(method)) {\n await this.executeSelectQuery(connection, queryObject);\n } else {\n await this.executeStatementQuery(connection, queryObject);\n }\n const endTime = Date.now();\n\n if (\n process.env.DEBUG === \"true\" &&\n queryObject.sql &&\n (queryObject.sql.toLowerCase().includes(\"create table\") ||\n queryObject.sql.toLowerCase().includes(\"knex_migrations\"))\n ) {\n this.printDebug(`${method} completed in ${endTime - startTime}ms`);\n }\n\n this.printDebug(`Query completed: ${method} (${endTime - startTime}ms)`);\n return queryObject;\n } catch (error: any) {\n // Enhanced error handling for connection issues\n const wrappedError = this.wrapError(error, method, queryObject);\n\n if (this.isConnectionError(error)) {\n this.printError(\n `Connection error during ${method} query: ${error.message}`\n );\n\n // For critical migration operations, retry once before failing\n if (this.shouldRetryQuery(queryObject, method)) {\n return await this.retryQuery(connection, queryObject, method);\n }\n\n throw wrappedError;\n }\n throw wrappedError;\n }\n }\n\n /**\n * Execute UPDATE with returning clause using transaction + SELECT approach\n * Since IBM i DB2 doesn't support FINAL TABLE with UPDATE, we:\n * 1. Execute the UPDATE statement\n * 2. Execute a SELECT to get the updated values using the same WHERE clause\n */\n private async executeUpdateReturning(\n connection: Connection,\n obj: any\n ): Promise<any> {\n const { _ibmiUpdateReturning } = obj;\n const { updateSql, selectColumns, whereClause, tableName } =\n _ibmiUpdateReturning;\n\n this.printDebug(\n \"Executing UPDATE with returning using transaction approach\"\n );\n\n try {\n // Execute the UPDATE statement\n const updateObj = {\n sql: updateSql,\n bindings: obj.bindings,\n sqlMethod: \"update\",\n };\n\n await this.executeStatementQuery(connection, updateObj);\n\n // Build and execute SELECT to get the updated values\n const selectSql = whereClause\n ? `select ${selectColumns} from ${tableName} ${whereClause}`\n : `select ${selectColumns} from ${tableName}`;\n\n // Extract only WHERE clause bindings for SELECT\n // UPDATE bindings format: [set_values..., where_values...]\n // We need to figure out how many bindings are for SET vs WHERE\n const updateSqlParts = updateSql.split(\" where \");\n const setClausePart = updateSqlParts[0];\n const setBindingCount = (setClausePart.match(/\\?/g) || []).length;\n const whereBindings = obj.bindings\n ? obj.bindings.slice(setBindingCount)\n : [];\n\n const selectObj = {\n sql: selectSql,\n bindings: whereBindings,\n sqlMethod: \"select\",\n response: undefined,\n };\n\n await this.executeSelectQuery(connection, selectObj);\n\n // Return the SELECT results as the final response\n obj.response = selectObj.response;\n obj.sqlMethod = \"update\";\n obj.select = true; // Mark as SELECT behavior to return rows instead of rowCount\n return obj;\n } catch (error: any) {\n this.printError(`UPDATE with returning failed: ${error.message}`);\n throw this.wrapError(error, \"update_returning\", obj);\n }\n }\n\n private async executeSequentialInsert(\n connection: Connection,\n obj: any\n ): Promise<any> {\n const meta = obj._ibmiSequentialInsert;\n const { rows, columns, tableName, returning, identityOnly } = meta;\n this.printDebug(\"Executing sequential multi-row insert\");\n const insertedRows: any[] = [];\n\n const transactional =\n (this.config as any)?.ibmi?.sequentialInsertTransactional === true;\n let beganTx = false;\n if (transactional) {\n try {\n await connection.query(\"BEGIN\");\n beganTx = true;\n } catch (e) {\n this.printWarn(\n \"Could not begin transaction for sequential insert; proceeding without\"\n );\n }\n }\n\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i];\n const colList = columns.join(\", \");\n const placeholders = columns.map(() => \"?\").join(\", \");\n const singleValues = columns.map((c: string) => row[c]);\n const baseInsert = `insert into ${tableName} (${colList}) values (${placeholders})`;\n const selectCols = returning\n ? this.queryCompiler({} as any).formatter.columnize(returning)\n : \"IDENTITY_VAL_LOCAL()\";\n const wrapped = `select ${selectCols} from FINAL TABLE(${baseInsert})`;\n const singleObj = {\n sql: wrapped,\n bindings: singleValues,\n sqlMethod: \"insert\",\n response: undefined,\n };\n await this.executeStatementQuery(connection, singleObj);\n const resp = (singleObj as any).response?.rows;\n if (resp) insertedRows.push(...resp);\n }\n\n if (transactional && beganTx) {\n try {\n await connection.query(\"COMMIT\");\n } catch (commitErr) {\n this.printError(\n \"Commit failed for sequential insert, attempting rollback: \" +\n (commitErr as any)?.message\n );\n try {\n await connection.query(\"ROLLBACK\");\n } catch {\n /* ignore */\n }\n throw commitErr;\n }\n }\n\n obj.response = { rows: insertedRows, rowCount: insertedRows.length };\n obj.sqlMethod = \"insert\";\n obj.select = true;\n return obj;\n }\n\n private async executeDeleteReturning(\n connection: Connection,\n obj: any\n ): Promise<any> {\n const meta = obj._ibmiDeleteReturning;\n const { deleteSql, selectColumns, whereClause, tableName } = meta;\n this.printDebug(\"Executing DELETE with returning emulation\");\n try {\n // SELECT rows first\n const selectSql = whereClause\n ? `select ${selectColumns} from ${tableName} ${whereClause}`\n : `select ${selectColumns} from ${tableName}`;\n const selectObj = {\n sql: selectSql,\n bindings: obj.bindings,\n sqlMethod: \"select\",\n response: undefined,\n };\n await this.executeSelectQuery(connection, selectObj);\n const rowsToReturn = (selectObj as any).response?.rows || [];\n // Execute DELETE\n const deleteObj = {\n sql: deleteSql,\n bindings: obj.bindings,\n sqlMethod: \"del\",\n response: undefined,\n };\n await this.executeStatementQuery(connection, deleteObj);\n obj.response = { rows: rowsToReturn, rowCount: rowsToReturn.length };\n obj.sqlMethod = \"del\";\n obj.select = true;\n return obj;\n } catch (error: any) {\n this.printError(`DELETE with returning failed: ${error.message}`);\n throw this.wrapError(error, \"delete_returning\", obj);\n }\n }\n\n private normalizeQueryObject(obj: any): any {\n if (!obj || typeof obj === \"string\") {\n return { sql: obj };\n }\n return obj;\n }\n\n private determineQueryMethod(obj: any): string {\n return (\n obj.hasOwnProperty(\"method\") && obj.method !== \"raw\"\n ? obj.method\n : obj.sql.split(\" \")[0]\n ).toLowerCase();\n }\n\n private isSelectMethod(method: string): boolean {\n return method === \"select\" || method === \"first\" || method === \"pluck\";\n }\n\n private async executeSelectQuery(\n connection: Connection,\n obj: { sql: string; bindings: any[]; response: unknown }\n ): Promise<void> {\n const rows: Record<any, any>[] = await connection.query(\n obj.sql,\n obj.bindings\n );\n if (rows) {\n obj.response = { rows, rowCount: rows.length };\n }\n }\n\n private async executeStatementQuery(\n connection: Connection,\n obj: any\n ): Promise<void> {\n let statement: any;\n let usedCache = false;\n const cacheEnabled = (this.config as any)?.ibmi?.preparedStatementCache === true;\n \n try {\n // Try to use cached statement if enabled\n if (cacheEnabled) {\n let cache = this.statementCaches.get(connection);\n if (!cache) {\n const cacheSize = (this.config as any)?.ibmi?.preparedStatementCacheSize || 100;\n cache = new StatementCache(cacheSize);\n this.statementCaches.set(connection, cache);\n }\n \n statement = cache.get(obj.sql);\n if (statement) {\n usedCache = true;\n this.printDebug(`Using cached statement for: ${obj.sql.substring(0, 50)}...`);\n } else {\n // Create and cache new statement\n statement = await connection.createStatement();\n await statement.prepare(obj.sql);\n cache.set(obj.sql, statement);\n this.printDebug(`Cached new statement (cache size: ${cache.size()})`);\n }\n } else {\n // No caching - create statement normally\n statement = await connection.createStatement();\n await statement.prepare(obj.sql);\n }\n\n if (obj.bindings) {\n await statement.bind(obj.bindings);\n }\n\n const result = await statement.execute();\n this.printDebug(String(result));\n\n obj.response = this.formatStatementResponse(result);\n } catch (err: any) {\n // Special handling for UPDATE/DELETE queries that affect 0 rows\n // Some ODBC drivers signal 0-row DML via empty error/\"no data\" (SQLSTATE 02000)\n const sql = (obj.sql || \"\").toLowerCase();\n const isDml =\n obj.sqlMethod === SqlMethod.UPDATE ||\n sql.includes(\" update \") ||\n sql.startsWith(\"update\") ||\n obj.sqlMethod === SqlMethod.DELETE ||\n sql.includes(\" delete \") ||\n sql.startsWith(\"delete\");\n\n const odbcErrors = err?.odbcErrors;\n const isEmptyOdbcError =\n Array.isArray(odbcErrors) && odbcErrors.length === 0;\n const hasNoDataState = Array.isArray(odbcErrors)\n ? odbcErrors.some(\n (e: any) =>\n String(e?.state || e?.SQLSTATE || \"\").toUpperCase() === \"02000\"\n )\n : false;\n\n if (\n isDml &&\n (isEmptyOdbcError || hasNoDataState || this.isNoDataError(err))\n ) {\n this.printWarn(\n `ODBC signaled no-data for ${sql.includes(\"update\") ? \"UPDATE\" : \"DELETE\"}; treating as 0 rows affected`\n );\n obj.response = { rows: [], rowCount: 0 };\n return;\n }\n\n this.printError(this.safeStringify(err));\n throw err;\n } finally {\n // Only close statement if it's not cached\n if (!usedCache && statement && typeof statement.close === \"function\") {\n try {\n await statement.close();\n } catch (closeErr) {\n // Ignore close errors, log in debug mode only\n this.printDebug(\n `Error closing statement: ${this.safeStringify(closeErr, 2)}`\n );\n }\n }\n }\n }\n\n private isNoDataError(error: any): boolean {\n if (!error) return false;\n const msg = String(error?.message || error || \"\").toLowerCase();\n // Match common indicators of 0-row DML reported as error\n return (\n msg.includes(\"02000\") ||\n msg.includes(\"no data\") ||\n msg.includes(\"no rows\") ||\n msg.includes(\"0 rows\")\n );\n }\n\n /**\n * Format statement response from ODBC driver\n * Handles special case for IDENTITY_VAL_LOCAL() function\n */\n private formatStatementResponse(result: any): {\n rows: any;\n rowCount: number;\n } {\n const isIdentityQuery = result.statement?.includes(\"IDENTITY_VAL_LOCAL()\");\n\n if (isIdentityQuery && result.columns?.length > 0) {\n return {\n rows: result.map(\n (row: { [x: string]: any }) => row[result.columns[0].name]\n ),\n rowCount: result.count,\n };\n }\n\n // Normalize result for DML (UPDATE/DELETE/INSERT) to surface rowCount consistently\n const rowCount = typeof result?.count === \"number\" ? result.count : 0;\n return {\n rows: result,\n rowCount,\n };\n }\n\n async _stream(\n connection: Connection,\n obj: { sql: string; bindings: any[] },\n stream: any,\n options: {\n fetchSize?: number;\n }\n ) {\n if (!obj.sql) throw new Error(\"A query is required to stream results\");\n\n const optimizedFetchSize =\n options?.fetchSize || this.calculateOptimalFetchSize(obj.sql);\n\n return new Promise((resolve, reject) => {\n let isResolved = false;\n\n const cleanup = () => {\n if (!isResolved) {\n isResolved = true;\n }\n };\n\n stream.on(\"error\", (err: any) => {\n cleanup();\n reject(err);\n });\n\n stream.on(\"end\", () => {\n cleanup();\n resolve(undefined);\n });\n\n connection.query(\n obj.sql,\n obj.bindings,\n {\n cursor: true,\n fetchSize: optimizedFetchSize,\n },\n (error, cursor) => {\n if (error) {\n this.printError(this.safeStringify(error, 2));\n cleanup();\n reject(error);\n return;\n }\n\n const readableStream = this._createCursorStream(cursor);\n readableStream.on(\"error\", (err) => {\n cleanup();\n reject(err);\n });\n readableStream.pipe(stream);\n }\n );\n });\n }\n\n private calculateOptimalFetchSize(sql: string): number {\n const sqlLower = sql.toLowerCase();\n const hasJoins = /\\s+join\\s+/i.test(sql);\n const hasAggregates = /\\s+(count|sum|avg|max|min)\\s*\\(/i.test(sql);\n const hasOrderBy = /\\s+order\\s+by\\s+/i.test(sql);\n const hasGroupBy = /\\s+group\\s+by\\s+/i.test(sql);\n\n // For complex analytical queries, use larger fetch sizes\n if (hasJoins || hasAggregates || hasOrderBy || hasGroupBy) {\n return 500;\n }\n\n // For simple queries, use moderate fetch size\n return 100;\n }\n\n private _createCursorStream(cursor: any): Readable {\n const parentThis = this;\n let isClosed = false;\n\n return new Readable({\n objectMode: true,\n read() {\n if (isClosed) return;\n\n cursor.fetch((error: unknown, result: unknown) => {\n if (error) {\n parentThis.printError(parentThis.safeStringify(error, 2));\n isClosed = true;\n this.emit(\"error\", error);\n return;\n }\n\n if (!cursor.noData) {\n this.push(result);\n } else {\n isClosed = true;\n cursor.close((closeError: unknown) => {\n if (closeError) {\n parentThis.printError(parentThis.safeStringify(closeError, 2));\n }\n if (result) {\n this.push(result);\n }\n this.push(null); // End the stream\n });\n }\n });\n },\n destroy(err, callback) {\n if (!isClosed) {\n isClosed = true;\n cursor.close((closeError: unknown) => {\n if (closeError) {\n parentThis.printDebug(\n \"Error closing cursor during destroy: \" +\n parentThis.safeStringify(closeError)\n );\n }\n callback(err);\n });\n } else {\n callback(err);\n }\n },\n });\n }\n\n transaction(container: any, config: any, outerTx: any): Knex.Transaction {\n return new (Transaction as any)(this, container, config, outerTx);\n }\n\n schemaCompiler(tableBuilder: any) {\n return new (SchemaCompiler as any)(this, tableBuilder);\n }\n\n tableCompiler(tableBuilder: any) {\n return new (TableCompiler as any)(this, tableBuilder);\n }\n\n columnCompiler(tableCompiler: any, columnCompiler: any) {\n return new (ColumnCompiler as any)(this, tableCompiler, columnCompiler);\n }\n\n queryCompiler(builder: Knex.QueryBuilder, bindings?: any[]) {\n return new (QueryCompiler as any)(this, builder, bindings);\n }\n\n // Create IBM i-specific migration runner that bypasses Knex's problematic locking system\n createMigrationRunner(\n config?: Partial<\n import(\"./migrations/ibmi-migration-runner\").IBMiMigrationConfig\n >\n ) {\n // Pass the knex instance from the client context\n const knexInstance = (this as any).context || (this as any);\n return createIBMiMigrationRunner(knexInstance, config);\n }\n\n processResponse(obj: QueryObject | null, runner: any): any {\n if (obj === null) return null;\n\n const { response } = obj;\n\n // If there's a custom output function, use it directly without validation\n // This allows custom queries like hasTable to handle their own response format\n if (obj.output) {\n try {\n const result = obj.output(runner, response);\n return result;\n } catch (error: any) {\n // Enhanced error handling for custom output functions\n const wrappedError = this.wrapError(error, \"custom_output\", obj);\n this.printError(\n `Custom output function failed: ${wrappedError.message}`\n );\n if (this.isConnectionError(error)) {\n throw new Error(\n \"Connection closed during query processing - consider using migrations.disableTransactions: true for DDL operations\"\n );\n }\n throw wrappedError;\n }\n }\n\n // Only validate for standard SQL methods that expect rows structure\n const validationResult = this.validateResponse(obj);\n if (validationResult !== null) return validationResult;\n\n return this.processSqlMethod(obj);\n }\n\n private validateResponse(obj: QueryObject): any {\n if (!obj.response) {\n this.printDebug(\"response undefined \" + this.safeStringify(obj));\n return null;\n }\n\n // For non-select methods, it's fine if rows is empty/undefined as long as rowCount is set.\n // Do not short-circuit here; allow processSqlMethod to normalize the return value.\n\n if (!obj.response.rows) {\n this.printError(\"rows undefined \" + this.safeStringify(obj));\n return null;\n }\n\n return null;\n }\n\n private wrapError(error: any, method: string, queryObject: any): Error {\n const context = {\n method,\n sql: queryObject.sql\n ? queryObject.sql.substring(0, 100) + \"...\"\n : \"unknown\",\n timestamp: new Date().toISOString(),\n };\n\n const contextStr = this.safeStringify(context);\n\n if (this.isConnectionError(error)) {\n return new Error(\n `IBM i DB2 connection error during ${method}: ${error.message} | Context: ${contextStr}`\n );\n }\n\n if (this.isTimeoutError(error)) {\n return new Error(\n `IBM i DB2 timeout during ${method}: ${error.message} | Context: ${contextStr}`\n );\n }\n\n if (this.isSQLError(error)) {\n return new Error(\n `IBM i DB2 SQL error during ${method}: ${error.message} | Context: ${contextStr}`\n );\n }\n\n // Generic error with context\n return new Error(\n `IBM i DB2 error during ${method}: ${error.message} | Context: ${contextStr}`\n );\n }\n\n private shouldRetryQuery(queryObject: any, method: string): boolean {\n return (\n queryObject.sql?.toLowerCase().includes(\"systables\") ||\n queryObject.sql?.toLowerCase().includes(\"knex_migrations\")\n );\n }\n\n private async retryQuery(\n connection: Connection,\n queryObject: any,\n method: string\n ): Promise<any> {\n this.printDebug(`Retrying ${method} query due to connection error...`);\n try {\n // Wait a moment and retry the query\n await new Promise((resolve) => setTimeout(resolve, 1000));\n if (this.isSelectMethod(method)) {\n await this.executeSelectQuery(connection, queryObject);\n } else {\n await this.executeStatementQuery(connection, queryObject);\n }\n return queryObject;\n } catch (retryError: any) {\n this.printError(`Retry failed: ${retryError.message}`);\n // If retry fails, return empty result to prevent migration corruption\n queryObject.response = { rows: [], rowCount: 0 };\n return queryObject;\n }\n }\n\n /**\n * Extract SQLSTATE from ODBC error if available\n */\n private getSQLState(error: any): string | null {\n // Check for ODBC error format with state property\n if (error?.odbcErrors && Array.isArray(error.odbcErrors)) {\n for (const odbcErr of error.odbcErrors) {\n const state = odbcErr?.state || odbcErr?.SQLSTATE;\n if (state) return String(state).toUpperCase();\n }\n }\n return null;\n }\n\n private isConnectionError(error: any): boolean {\n const sqlState = this.getSQLState(error);\n \n // ODBC SQLSTATE codes for connection errors\n // 08xxx = Connection exception\n if (sqlState) {\n return (\n sqlState.startsWith('08') || // 08001, 08003, 08007, 08S01, etc.\n sqlState === '40003' // Transaction rollback due to connection\n );\n }\n\n // Fallback to message parsing\n const errorMessage = (\n error.message ||\n error.toString ||\n error\n ).toLowerCase();\n return (\n errorMessage.includes(\"connection\") &&\n (errorMessage.includes(\"closed\") ||\n errorMessage.includes(\"invalid\") ||\n errorMessage.includes(\"terminated\") ||\n errorMessage.includes(\"not connected\"))\n );\n }\n\n private isTimeoutError(error: any): boolean {\n const sqlState = this.getSQLState(error);\n \n // ODBC SQLSTATE codes for timeout errors\n if (sqlState) {\n return (\n sqlState === 'HYT00' || // Timeout expired\n sqlState === 'HYT01' // Connection timeout expired\n );\n }\n\n // Fallback to message parsing\n const errorMessage = (\n error.message ||\n error.toString ||\n error\n ).toLowerCase();\n return (\n errorMessage.includes(\"timeout\") || errorMessage.includes(\"timed out\")\n );\n }\n\n private isSQLError(error: any): boolean {\n const sqlState = this.getSQLState(error);\n \n // ODBC SQLSTATE codes for SQL errors\n if (sqlState) {\n return (\n sqlState.startsWith('42') || // Syntax error or access violation\n sqlState.startsWith('22') || // Data exception\n sqlState.startsWith('23') || // Integrity constraint violation\n sqlState.startsWith('21') // Cardinality violation\n );\n }\n\n // Fallback to message parsing\n const errorMessage = (\n error.message ||\n error.toString ||\n error\n ).toLowerCase();\n return (\n errorMessage.includes(\"sql\") ||\n errorMessage.includes(\"syntax\") ||\n errorMessage.includes(\"table\") ||\n errorMessage.includes(\"column\")\n );\n }\n\n private processSqlMethod(obj: QueryObject): any {\n const { rows, rowCount } = obj.response!;\n\n switch (obj.sqlMethod) {\n case SqlMethod.SELECT:\n return rows;\n case SqlMethod.PLUCK:\n return rows.map(obj.pluck!);\n case SqlMethod.FIRST:\n return rows[0];\n case SqlMethod.INSERT:\n return rows;\n case SqlMethod.DELETE:\n case SqlMethod.DELETE_ALT:\n case SqlMethod.UPDATE:\n // Align with MySQL: return affected rows as a number for DML\n return obj.select ? rows : (rowCount ?? 0);\n case SqlMethod.COUNTER:\n return rowCount;\n default:\n return rows;\n }\n }\n}\n\ninterface DB2PoolConfig {\n min?: number;\n max?: number;\n acquireConnectionTimeout?: number;\n}\n\ninterface DB2ConnectionParams {\n CMT?: number;\n CONNTYPE?: number;\n DBQ?: string;\n MAXDECPREC?: 31 | 63;\n MAXDECSCALE?: number;\n MINDIVSCALE?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;\n NAM?: 0 | 1;\n DFT?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;\n DSP?: 0 | 1 | 2 | 3 | 4;\n DEC?: 0 | 1;\n DECFLOATERROROPTION?: 0 | 1;\n DECFLOATROUNDMODE?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n MAPDECIMALFLOATDESCRIBE?: 1 | 3;\n TFT?: 0 | 1 | 2 | 3 | 4;\n TSP?: 0 | 1 | 2 | 3;\n TSFT?: 0 | 1;\n XMLCURIMPPARSE?: 0 | 1;\n XMLDECLARATION?: 1 | 2 | 3 | 4;\n ALLOWPROCCALLS?: 0 | 1;\n XDYNAMIC?: 0 | 1;\n DFTPKGLIB?: string;\n PKG?: 0 | 1 | 2;\n BLOCKFETCH?: 0 | 1;\n COMPRESSION?: 0 | 1;\n CONCURRENCY?: 0 | 1;\n CURSORSENSITIVITY?: 0 | 1 | 2;\n EXTCOLINFO?:\n | \"SQL_DESC_AUTO_UNIQUE_VALUE\"\n | \"SQL_DESC_BASE_COLUMN_NAME\"\n | \"SQL_DESC_BASE_TABLE_NAME and SQL_DESC_TABLE_NAME\"\n | \"SQL_DESC_LABEL\"\n | \"SQL_DESC_SCHEMA_NAME\"\n | \"SQL_DESC_SEARCHABLE\"\n | \"SQL_DESC_UNNAMED\"\n | \"SQL_DESC_UPDATABLE\";\n TRUEAUTOCOMMIT?: 0 | 1;\n}\n\ninterface DB2ConnectionConfig {\n database: string;\n host: string;\n port: 8471 | 9471 | number;\n user: string;\n password: string;\n driver: \"IBM i Access ODBC Driver\" | string;\n connectionStringParams?: DB2ConnectionParams;\n}\n\nexport interface DB2Config extends Knex.Config {\n client: any;\n connection: DB2ConnectionConfig;\n pool?: DB2PoolConfig;\n ibmi?: {\n multiRowInsert?: \"auto\" | \"sequential\" | \"disabled\";\n sequentialInsertTransactional?: boolean;\n preparedStatementCache?: boolean; // Enable per-connection statement caching\n preparedStatementCacheSize?: number; // Max cached statements per connection (default: 100)\n readUncommitted?: boolean; // Append WITH UR to SELECT queries\n };\n}\n\nexport const DB2Dialect = DB2Client;\nexport { IBMiMigrationRunner, createIBMiMigrationRunner };\nexport default DB2Client;\n","import SchemaCompiler from \"knex/lib/schema/compiler.js\";\n\nclass IBMiSchemaCompiler extends SchemaCompiler {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n hasTable(tableName: string) {\n const upperName = String(tableName).toUpperCase();\n\n // Extract schema and table name if qualified\n let schemaName: string | null = null;\n let actualTableName = upperName;\n\n if (upperName.includes(\".\")) {\n const parts = upperName.split(\".\");\n schemaName = parts[0];\n actualTableName = parts[1];\n }\n\n // Use schema from the builder if available\n const builderSchema = (this.builder as any)._schema;\n if (builderSchema) {\n schemaName = builderSchema.toUpperCase();\n }\n\n let sql: string;\n let bindings: any[];\n\n if (schemaName) {\n sql = `select count(*) as table_count from QSYS2.SYSTABLES where UPPER(TABLE_NAME) = ? AND UPPER(TABLE_SCHEMA) = ?`;\n bindings = [actualTableName, schemaName];\n } else {\n sql = `select count(*) as table_count from QSYS2.SYSTABLES where UPPER(TABLE_NAME) = ?`;\n bindings = [actualTableName];\n }\n\n this.pushQuery({\n sql,\n bindings,\n output: (runner: any, resp: any) => {\n // Handle the response from the ODBC query\n // The first parameter is the runner, the second is the actual response\n if (!resp) {\n return false;\n }\n\n // Check if response is an array with results\n if (Array.isArray(resp) && resp.length > 0) {\n const firstRow = resp[0];\n if (firstRow && typeof firstRow === \"object\") {\n // Look for table_count or any count field\n const count =\n firstRow.table_count ||\n firstRow.TABLE_COUNT ||\n firstRow.count ||\n firstRow.COUNT ||\n 0;\n return count > 0;\n }\n }\n\n // Handle ODBC response format with numeric keys\n if (typeof resp === \"object\" && resp !== null) {\n // Check for ODBC array-like response with numeric indices\n const keys = Object.keys(resp);\n for (const key of keys) {\n if (!isNaN(parseInt(key))) {\n const row = resp[key];\n if (row && typeof row === \"object\") {\n const count =\n row.table_count ||\n row.TABLE_COUNT ||\n row.count ||\n row.COUNT ||\n 0;\n return count > 0;\n }\n }\n }\n\n // Handle response with rows property\n if (resp.rows && Array.isArray(resp.rows) && resp.rows.length > 0) {\n const firstRow = resp.rows[0];\n if (firstRow && typeof firstRow === \"object\") {\n const count =\n firstRow.table_count ||\n firstRow.TABLE_COUNT ||\n firstRow.count ||\n firstRow.COUNT ||\n 0;\n return count > 0;\n }\n }\n }\n\n return false;\n },\n });\n }\n\n toSQL() {\n const sequence = (this.builder as any)._sequence as any[];\n\n for (let i = 0, l = sequence.length; i < l; i++) {\n const query = sequence[i];\n this[query.method].apply(this, query.args);\n }\n\n return this.sequence;\n }\n}\n\nfunction prefixedTableName(prefix: any, table: any) {\n return prefix ? `${prefix}.${table}` : table;\n}\n\nexport default IBMiSchemaCompiler;\n","import TableCompiler from \"knex/lib/schema/tablecompiler.js\";\nimport { Connection } from \"odbc\";\n\nclass IBMiTableCompiler extends TableCompiler {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n createQuery(columns: { sql: any[] }, ifNot: any, like: any) {\n // Note: IBM i DB2 does not support IF NOT EXISTS syntax directly\n // The ifNot parameter should be handled by checking hasTable first\n if (ifNot && this.client?.logger?.warn) {\n this.client.logger.warn(\n 'IBM i DB2: IF NOT EXISTS is not natively supported. Use hasTable() check instead.'\n );\n }\n\n let createStatement = \"\";\n\n if (like) {\n // IBM i DB2 syntax for creating table from existing structure\n createStatement = `create table ${this.tableName()} as (select * from ${this.tableNameLike()}) with no data`;\n } else {\n createStatement =\n \"create table \" +\n this.tableName() +\n (this._formatting ? \" (\\n \" : \" (\") +\n columns.sql.join(this._formatting ? \",\\n \" : \", \") +\n this._addChecks() +\n \")\";\n }\n\n this.pushQuery(createStatement);\n\n if (this.single.comment) {\n this.comment(this.single.comment);\n }\n\n if (like) {\n this.addColumns(columns, this.addColumnsPrefix);\n }\n }\n\n dropUnique(columns: string[], indexName: any) {\n indexName = indexName\n ? this.formatter.wrap(indexName)\n : this._indexCommand(\"unique\", this.tableNameRaw, columns);\n\n this.pushQuery(`drop index ${indexName}`);\n }\n\n unique(\n columns: string[],\n indexName:\n | string\n | { indexName?: string; deferrable?: string; predicate?: any }\n ) {\n let deferrable: string = \"\";\n let predicate: any;\n let finalIndexName: string | undefined;\n\n if (typeof indexName === \"object\" && indexName !== null) {\n deferrable = indexName.deferrable || \"\";\n predicate = indexName.predicate;\n finalIndexName = indexName.indexName;\n } else {\n finalIndexName = indexName;\n }\n\n if (deferrable && deferrable !== \"not deferrable\") {\n this.client.logger.warn?.(\n `IBMi: unique index \\`${finalIndexName}\\` will not be deferrable ${deferrable}.`\n );\n }\n\n const wrappedIndexName = finalIndexName\n ? this.formatter.wrap(finalIndexName)\n : this._indexCommand(\"unique\", this.tableNameRaw, columns);\n columns = this.formatter.columnize(columns);\n\n const predicateQuery = predicate\n ? \" \" + this.client.queryCompiler(predicate).where()\n : \"\";\n\n this.pushQuery(\n `create unique index ${wrappedIndexName} on ${this.tableName()} (${columns})${predicateQuery}`\n );\n }\n\n // All of the columns to \"add\" for the query\n addColumns(columns: any, prefix: any) {\n prefix = prefix || this.addColumnsPrefix;\n\n if (columns.sql.length > 0) {\n const columnSql = columns.sql.map((column) => {\n return prefix + column;\n });\n this.pushQuery({\n sql:\n (this.lowerCase ? \"alter table \" : \"ALTER TABLE \") +\n this.tableName() +\n \" \" +\n columnSql.join(\" \"),\n bindings: columns.bindings,\n });\n }\n }\n\n async commit(connection: Connection) {\n return await connection.commit();\n }\n}\n\nexport default IBMiTableCompiler;\n","import ColumnCompiler from \"knex/lib/schema/columncompiler.js\";\n\nclass IBMiColumnCompiler extends ColumnCompiler {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n increments(options = { primaryKey: true }) {\n return (\n \"int not null generated always as identity (start with 1, increment by 1)\" +\n (this.tableCompiler._canBeAddPrimaryKey(options) ? \" primary key\" : \"\")\n );\n }\n\n // Add more IBM i DB2 specific column types for better support\n bigIncrements(options = { primaryKey: true }) {\n return (\n \"bigint not null generated always as identity (start with 1, increment by 1)\" +\n (this.tableCompiler._canBeAddPrimaryKey(options) ? \" primary key\" : \"\")\n );\n }\n\n varchar(length?: number) {\n return length ? `varchar(${length})` : 'varchar(255)';\n }\n\n char(length?: number) {\n return length ? `char(${length})` : 'char(1)';\n }\n\n text() {\n // IBM i DB2 uses CLOB for large text\n return 'clob(1M)';\n }\n\n mediumtext() {\n return 'clob(16M)';\n }\n\n longtext() {\n return 'clob(2G)';\n }\n\n binary(length?: number) {\n return length ? `binary(${length})` : 'binary(1)';\n }\n\n varbinary(length?: number) {\n return length ? `varbinary(${length})` : 'varbinary(255)';\n }\n\n // IBM i DB2 decimal with precision/scale\n decimal(precision?: number, scale?: number) {\n if (precision && scale) {\n return `decimal(${precision}, ${scale})`;\n } else if (precision) {\n return `decimal(${precision})`;\n }\n return 'decimal(10, 2)';\n }\n\n // IBM i DB2 timestamp\n // Note: IBM i DB2 does not support TIMESTAMP WITH TIME ZONE\n timestamp(options?: any) {\n if (options?.useTz && this.client?.logger?.warn) {\n this.client.logger.warn(\n 'IBM i DB2 does not support TIMESTAMP WITH TIME ZONE. Using plain TIMESTAMP instead.'\n );\n }\n return 'timestamp';\n }\n\n datetime(options?: any) {\n return this.timestamp(options);\n }\n\n // IBM i DB2 date and time types\n date() {\n return 'date';\n }\n\n time() {\n return 'time';\n }\n\n // JSON support (IBM i 7.3+)\n // Note: CHECK constraints with column references are not supported in this context\n // Users should add validation constraints separately if needed\n json() {\n return 'clob(16M)';\n }\n\n jsonb() {\n // IBM i doesn't have native JSONB, use CLOB\n return 'clob(16M)';\n }\n\n // UUID support using CHAR(36)\n uuid() {\n return 'char(36)';\n }\n}\n\nexport default IBMiColumnCompiler;\n","import Transaction from \"knex/lib/execution/transaction.js\";\n\nclass IBMiTransaction extends Transaction {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n begin(connection: any): any {\n try {\n return connection.beginTransaction();\n } catch (error: any) {\n if (this.isConnectionClosed(error)) {\n console.warn(\n \"IBM i DB2: Connection closed during transaction begin, DDL operations may have caused implicit commit\"\n );\n throw new Error(\n \"Connection closed during transaction begin - consider using migrations.disableTransactions: true\"\n );\n }\n throw error;\n }\n }\n\n rollback(connection: any): any {\n try {\n return connection.rollback();\n } catch (error: any) {\n // Treat rollback on a closed connection as success to avoid hangs\n console.warn(\n \"IBM i DB2: Rollback encountered an error (likely closed connection):\",\n error?.message || error\n );\n return Promise.resolve();\n }\n }\n\n commit(connection: any): any {\n try {\n return connection.commit();\n } catch (error: any) {\n if (this.isConnectionClosed(error)) {\n console.warn(\n \"IBM i DB2: Connection closed during commit - DDL operations cause implicit commits\"\n );\n // Re-throw so Knex can surface the expected failure semantics\n throw new Error(\n \"Connection closed during commit - this is expected with DDL operations on IBM i DB2\"\n );\n }\n throw error;\n }\n }\n\n private isConnectionClosed(error: any): boolean {\n const message = String(error?.message || error || \"\").toLowerCase();\n return (\n message.includes(\"connection\") &&\n (message.includes(\"closed\") ||\n message.includes(\"invalid\") ||\n message.includes(\"terminated\") ||\n message.includes(\"not connected\"))\n );\n }\n}\n\nexport default IBMiTransaction;\n","import QueryCompiler from \"knex/lib/query/querycompiler.js\";\nimport { rawOrFn as rawOrFn_ } from \"knex/lib/formatter/wrappingFormatter.js\";\n\nclass IBMiQueryCompiler extends QueryCompiler {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n // Cache for column metadata to improve performance with repeated operations\n private columnCache = new Map<string, string[]>();\n\n // Override select method to add IBM i optimization hints\n select() {\n let sql = super.select.call(this);\n \n // Add WITH UR (uncommitted read) if configured\n const readUncommitted = this.client?.config?.ibmi?.readUncommitted === true;\n if (readUncommitted && typeof sql === 'string') {\n sql = sql + ' WITH UR';\n }\n \n return sql;\n }\n\n private formatTimestampLocal(date: Date): string {\n const pad = (n: number) => String(n).padStart(2, \"0\");\n const y = date.getFullYear();\n const m = pad(date.getMonth() + 1);\n const d = pad(date.getDate());\n const hh = pad(date.getHours());\n const mm = pad(date.getMinutes());\n const ss = pad(date.getSeconds());\n return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;\n }\n insert() {\n const insertValues = this.single.insert || [];\n const { returning } = this.single;\n\n // Handle empty insert values\n if (this.isEmptyInsertValues(insertValues)) {\n if (this.isEmptyObject(insertValues)) {\n return this.buildEmptyInsertResult(returning);\n }\n return \"\";\n }\n\n // Decide multi-row insert strategy (default: allow multi-row single statement)\n const ibmiConfig = this.client?.config?.ibmi || {};\n const multiRowStrategy = ibmiConfig.multiRowInsert || \"auto\"; // 'auto' | 'sequential' | 'disabled'\n\n // When disabled, or sequential strategy with >1 rows, fall back to first row only SQL generation here.\n // Sequential execution of additional rows is handled at runtime in the client (future enhancement).\n const isArrayInsert =\n Array.isArray(insertValues) && insertValues.length > 1;\n // Keep original values for sequential strategy metadata\n const originalValues = isArrayInsert ? insertValues.slice() : insertValues;\n const forceSingleRow =\n multiRowStrategy === \"disabled\" ||\n (multiRowStrategy === \"sequential\" && isArrayInsert);\n\n // If forcing single row, keep legacy single-row path by trimming to first element\n let workingValues: any = insertValues;\n if (forceSingleRow && isArrayInsert) {\n workingValues = [insertValues[0]];\n this.single.insert = workingValues; // mutate for downstream calls\n }\n\n // Get the standard INSERT statement from parent class (will include multi-row SQL if available)\n const standardInsert = super.insert();\n\n // If it's an object with sql property, use that; otherwise use the string directly\n const insertSql =\n typeof standardInsert === \"object\" && standardInsert.sql\n ? standardInsert.sql\n : standardInsert;\n\n // For IBM i, wrap INSERT with FINAL TABLE only when RETURNING is requested\n // Multi-row inserts without RETURNING should use plain INSERT for performance\n const multiRow = isArrayInsert && !forceSingleRow;\n \n // If multi-row insert without returning, use plain INSERT (return rowCount only)\n if (multiRow && !returning) {\n return { sql: insertSql, returning: undefined };\n }\n \n // Warn about potentially large result sets\n if (multiRow && returning === \"*\") {\n if (this.client?.printWarn) {\n this.client.printWarn(\"multi-row insert with returning * may be large\");\n }\n }\n \n // Use FINAL TABLE for single-row or when returning is specified\n const selectColumns = returning\n ? this.formatter.columnize(returning)\n : \"IDENTITY_VAL_LOCAL()\";\n const sql = `select ${selectColumns} from FINAL TABLE(${insertSql})`;\n\n // Add metadata for sequential strategy so runtime can execute remaining rows\n if (multiRowStrategy === \"sequential\" && isArrayInsert) {\n // Build column list using first row keys (sorted to match _prepInsert logic)\n const first = originalValues[0];\n const columns = Object.keys(first).sort();\n return {\n sql,\n returning: undefined,\n _ibmiSequentialInsert: {\n columns,\n rows: originalValues,\n tableName: this.tableName,\n returning: returning || null,\n identityOnly: !returning,\n },\n };\n }\n\n return { sql, returning: undefined };\n }\n\n private isEmptyInsertValues(insertValues: any): boolean {\n return (\n (Array.isArray(insertValues) && insertValues.length === 0) ||\n this.isEmptyObject(insertValues)\n );\n }\n\n private isEmptyObject(insertValues: any): boolean {\n return (\n insertValues !== null &&\n typeof insertValues === \"object\" &&\n !Array.isArray(insertValues) &&\n Object.keys(insertValues).length === 0\n );\n }\n\n private buildEmptyInsertResult(returning: any): {\n sql: string;\n returning: any;\n } {\n const selectColumns = returning\n ? this.formatter.columnize(returning)\n : \"IDENTITY_VAL_LOCAL()\";\n\n const returningSql = returning\n ? this._returning(\"insert\", returning, undefined) + \" \"\n : \"\";\n\n const insertSql = [\n this.with(),\n `insert into ${this.tableName}`,\n returningSql + this._emptyInsertValue,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const sql = `select ${selectColumns} from FINAL TABLE(${insertSql})`;\n\n return { sql, returning };\n }\n\n _buildInsertData(insertValues: string | any[], returningSql: string): string {\n const insertData = this._prepInsert(insertValues);\n\n if (insertData.columns.length > 0) {\n const parts: string[] = [];\n parts.push(\"(\" + this.formatter.columnize(insertData.columns) + \") \");\n if (returningSql) parts.push(returningSql);\n parts.push(\"values \");\n\n const rowsSql: string[] = [];\n for (const row of insertData.values) {\n const placeholders = row.map(() => \"?\").join(\", \");\n rowsSql.push(\"(\" + placeholders + \")\");\n }\n parts.push(rowsSql.join(\", \"));\n return parts.join(\"\");\n }\n\n if (\n Array.isArray(insertValues) &&\n insertValues.length === 1 &&\n insertValues[0]\n ) {\n return (returningSql || \"\") + this._emptyInsertValue;\n }\n return \"\";\n }\n\n private generateCacheKey(data: any): string {\n if (Array.isArray(data) && data.length > 0) {\n // Use the keys of the first object as cache key\n return Object.keys(data[0] || {})\n .sort()\n .join(\"|\");\n }\n if (data && typeof data === \"object\") {\n return Object.keys(data).sort().join(\"|\");\n }\n return \"\";\n }\n\n private buildFromCache(\n data: any,\n cachedColumns: string[]\n ): { columns: any; values: any } {\n const dataArray = Array.isArray(data) ? data : data ? [data] : [];\n const values: any[] = [];\n\n // Build values array using cached column order\n for (const item of dataArray) {\n if (item == null) {\n break;\n }\n const row = cachedColumns.map((column) => item[column] ?? undefined);\n values.push(row);\n }\n\n return {\n columns: cachedColumns,\n values,\n };\n }\n\n _prepInsert(data: any): { columns: any; values: any } {\n // Handle timestamps in knex migrations\n if (typeof data === \"object\" && data?.migration_time) {\n const parsed = new Date(data.migration_time);\n if (!isNaN(parsed.getTime())) {\n data.migration_time = this.formatTimestampLocal(parsed);\n }\n }\n\n const isRaw = rawOrFn_(\n data,\n undefined,\n this.builder,\n this.client,\n this.bindingsHolder\n );\n\n if (isRaw) {\n return isRaw;\n }\n\n // Normalize data to array format\n const dataArray = Array.isArray(data) ? data : data ? [data] : [];\n\n if (dataArray.length === 0) {\n return { columns: [], values: [] };\n }\n\n // Multi-row support: build unified column list from first row, then map all rows\n const firstItem = dataArray[0];\n if (!firstItem || typeof firstItem !== \"object\") {\n return { columns: [], values: [] };\n }\n\n const cacheKey = this.generateCacheKey(firstItem);\n let columns: string[];\n if (cacheKey && this.columnCache.has(cacheKey)) {\n columns = this.columnCache.get(cacheKey)!;\n } else {\n columns = Object.keys(firstItem).sort();\n if (cacheKey && columns.length > 0)\n this.columnCache.set(cacheKey, columns);\n }\n\n const values: any[] = [];\n for (const item of dataArray) {\n if (!item || typeof item !== \"object\") continue;\n values.push(columns.map((c) => item[c] ?? undefined));\n }\n\n return { columns, values };\n }\n\n update(): { sql: string; returning: any; _ibmiUpdateReturning?: any } {\n const withSQL = this.with();\n const updates = this._prepUpdate(this.single.update);\n const where = this.where();\n const order = this.order();\n const limit = this.limit();\n const { returning } = this.single;\n\n // Add IBM i v7r3+ optimization hints for UPDATE\n const optimizationHints = \"\";\n\n // Build the base update statement\n const baseUpdateSql = [\n withSQL,\n `update ${this.single.only ? \"only \" : \"\"}${this.tableName}`,\n \"set\",\n updates.join(\", \"),\n where,\n order,\n limit,\n optimizationHints,\n ]\n .filter(Boolean)\n .join(\" \");\n\n // Handle returning clause\n if (returning) {\n // For tests and toString(), show the expected FINAL TABLE format\n // But add metadata for actual execution using UPDATE + SELECT approach\n const selectColumns = this.formatter.columnize(this.single.returning);\n const expectedSql = `select ${selectColumns} from FINAL TABLE(${baseUpdateSql})`;\n\n return {\n sql: expectedSql,\n returning,\n _ibmiUpdateReturning: {\n updateSql: baseUpdateSql,\n selectColumns,\n whereClause: where,\n tableName: this.tableName,\n },\n };\n }\n\n return { sql: baseUpdateSql, returning };\n }\n\n // Emulate DELETE ... RETURNING by compiling a FINAL TABLE wrapper for display and attaching metadata\n del(): { sql: string; returning: any; _ibmiDeleteReturning?: any } {\n const baseDelete = super.del();\n const { returning } = this.single;\n if (!returning) {\n return { sql: baseDelete as string, returning: undefined };\n }\n const deleteSql =\n typeof baseDelete === \"object\" && (baseDelete as any).sql\n ? (baseDelete as any).sql\n : baseDelete;\n const selectColumns = this.formatter.columnize(returning);\n const expectedSql = `select ${selectColumns} from FINAL TABLE(${deleteSql})`;\n return {\n sql: expectedSql,\n returning,\n _ibmiDeleteReturning: {\n deleteSql,\n selectColumns,\n whereClause: this.where(),\n tableName: this.tableName,\n },\n };\n }\n\n /**\n * Handle returning clause for IBMi DB2 queries\n * Note: IBMi DB2 has limited support for RETURNING clauses\n * @param method - The SQL method (insert, update, delete)\n * @param value - The returning value\n * @param withTrigger - Trigger support (currently unused)\n */\n _returning(method: string, value: any, withTrigger: undefined) {\n switch (method) {\n case \"update\":\n case \"insert\":\n return value ? `${withTrigger ? \" into #out\" : \"\"}` : \"\";\n case \"del\":\n return value ? `${withTrigger ? \" into #out\" : \"\"}` : \"\";\n case \"rowcount\":\n return value ? \"select @@rowcount\" : \"\";\n default:\n return \"\";\n }\n }\n\n private getOptimizationHints(queryType: string, data?: any): string {\n const hints: string[] = [];\n\n // IBM i DB2 doesn't support OPTIMIZE FOR in all contexts\n // Use WITH UR (Uncommitted Read) for better concurrency instead\n if (queryType === \"select\") {\n hints.push(\"WITH UR\"); // Uncommitted Read for better performance on read-heavy workloads\n }\n\n return hints.length > 0 ? \" \" + hints.join(\" \") : \"\";\n }\n\n private getSelectOptimizationHints(sql: string): string {\n const hints: string[] = [];\n\n // Only use WITH UR for read operations on IBM i DB2\n // OPTIMIZE FOR syntax causes errors on this IBM i version\n hints.push(\"WITH UR\");\n\n return hints.length > 0 ? \" \" + hints.join(\" \") : \"\";\n }\n\n columnizeWithPrefix(prefix: string, target: string | string[]) {\n const columns = typeof target === \"string\" ? [target] : target;\n const parts: string[] = [];\n\n for (let i = 0; i < columns.length; i++) {\n if (i > 0) parts.push(\", \");\n parts.push(prefix + this.wrap(columns[i]));\n }\n\n return parts.join(\"\");\n }\n}\n\nexport default IBMiQueryCompiler;\n","import fs from \"fs\";\nimport path from \"path\";\nimport { Knex } from \"knex\";\n\nexport interface IBMiMigrationConfig {\n directory: string;\n tableName: string;\n schemaName?: string;\n extension?: string;\n}\n\nexport class IBMiMigrationRunner {\n private knex: Knex;\n private config: IBMiMigrationConfig;\n\n constructor(knex: Knex, config?: Partial<IBMiMigrationConfig>) {\n this.knex = knex;\n\n // Default configuration\n this.config = {\n directory: \"./migrations\",\n tableName: \"KNEX_MIGRATIONS\",\n schemaName: undefined,\n extension: \"js\",\n ...config,\n };\n }\n\n private getFullTableName(): string {\n return this.config.schemaName\n ? `${this.config.schemaName}.${this.config.tableName}`\n : this.config.tableName;\n }\n\n async latest(): Promise<void> {\n try {\n console.log(\n \"šŸš€ IBM i DB2 Migration Runner - bypassing Knex locking system\"\n );\n\n // Ensure the migration table exists\n const tableName = this.getFullTableName();\n\n const migrationTableExists = await (this.knex as any).schema.hasTable(\n tableName\n );\n if (!migrationTableExists) {\n console.log(`šŸ“ Creating migration table: ${tableName}`);\n await (this.knex as any).schema.createTable(tableName, (table) => {\n table.increments(\"id\").primary();\n table.string(\"name\").unique(); // Prevent duplicate migration names\n table.integer(\"batch\");\n table.timestamp(\"migration_time\");\n });\n console.log(\"āœ… Migration table created\");\n }\n\n // Get completed migrations (IBM i uses uppercase column names)\n const completed = await this.knex(tableName).select(\"NAME\").orderBy(\"ID\");\n const completedNames = completed.map((c: any) => c.NAME);\n console.log(`šŸ“‹ Found ${completedNames.length} completed migrations`);\n\n // Get migration files\n const migrationFiles = this.getMigrationFiles();\n console.log(`šŸ“ Found ${migrationFiles.length} migration files`);\n\n // Find new migrations to run\n const newMigrations = migrationFiles.filter(\n (file) => !completedNames.includes(file)\n );\n\n if (newMigrations.length === 0) {\n console.log(\"āœ… No new migrations to run\");\n return;\n }\n\n console.log(`šŸŽÆ Running ${newMigrations.length} new migrations:`);\n newMigrations.forEach((file) => console.log(` - ${file}`));\n\n // Get next batch number (IBM i uses uppercase column names)\n const batchResult = await this.knex(tableName).max(\"BATCH as max_batch\");\n const nextBatch = (batchResult[0]?.max_batch || 0) + 1;\n console.log(`šŸ“Š Using batch number: ${nextBatch}`);\n\n // Run each migration\n for (const migrationFile of newMigrations) {\n console.log(`\\nšŸ”„ Running migration: ${migrationFile}`);\n\n try {\n // Import the migration\n const migrationPath = this.getMigrationPath(migrationFile);\n const migration = await import(migrationPath);\n\n if (!migration.up || typeof migration.up !== \"function\") {\n throw new Error(`Migration ${migrationFile} has no 'up' function`);\n }\n\n // Execute the migration\n console.log(` ⚔ Executing migration...`);\n await migration.up(this.knex);\n\n // Record the migration\n await this.knex(tableName).insert({\n name: migrationFile,\n batch: nextBatch,\n migration_time: new Date(),\n });\n\n console.log(` āœ… Migration ${migrationFile} completed successfully`);\n } catch (error: any) {\n console.error(\n ` āŒ Migration ${migrationFile} failed:`,\n error.message\n );\n throw error;\n }\n }\n\n console.log(`\\nšŸŽ‰ All migrations completed successfully!`);\n } catch (error: any) {\n console.error(\"āŒ Migration runner failed:\", error.message);\n throw error;\n }\n }\n\n async rollback(steps: number = 1): Promise<void> {\n try {\n console.log(`šŸ”„ Rolling back ${steps} migration batch(es)...`);\n\n const tableName = this.getFullTableName();\n\n // Get the last batch(es) to rollback\n const batchesToRollback = await this.knex(tableName)\n .distinct(\"BATCH\")\n .orderBy(\"BATCH\", \"desc\")\n .limit(steps);\n\n if (batchesToRollback.length === 0) {\n console.log(\"āœ… No migrations to rollback\");\n return;\n }\n\n const batchNumbers = batchesToRollback.map((b: any) => b.BATCH);\n console.log(`šŸ“Š Rolling back batches: ${batchNumbers.join(\", \")}`);\n\n // Get migrations to rollback\n const migrationsToRollback = await this.knex(tableName)\n .select(\"NAME\")\n .whereIn(\"BATCH\", batchNumbers)\n .orderBy(\"ID\", \"desc\");\n\n console.log(`šŸŽÆ Rolling back ${migrationsToRollback.length} migrations:`);\n migrationsToRollback.forEach((m: any) => console.log(` - ${m.NAME}`));\n\n // Rollback each migration\n for (const migrationRecord of migrationsToRollback) {\n const migrationFile = migrationRecord.NAME;\n console.log(`\\nšŸ”„ Rolling back migration: ${migrationFile}`);\n\n try {\n // Import the migration\n const migrationPath = this.getMigrationPath(migrationFile);\n const migration = await import(migrationPath);\n\n if (migration.down && typeof migration.down === \"function\") {\n console.log(` ⚔ Executing rollback...`);\n await migration.down(this.knex);\n } else {\n console.log(\n ` āš ļø Migration ${migrationFile} has no 'down' function, skipping rollback`\n );\n }\n\n // Remove the migration record\n await this.knex(tableName).where(\"NAME\", migrationFile).del();\n\n console.log(\n ` āœ… Migration ${migrationFile} rolled back successfully`\n );\n } catch (error: any) {\n console.error(\n ` āŒ Migration ${migrationFile} rollback failed:`,\n error.message\n );\n throw error;\n }\n }\n\n console.log(`\\nšŸŽ‰ Rollback completed successfully!`);\n } catch (error: any) {\n console.error(\"āŒ Rollback failed:\", error.message);\n throw error;\n }\n }\n\n async currentVersion(): Promise<string | null> {\n try {\n const tableName = this.getFullTableName();\n\n const migrationTableExists = await (this.knex as any).schema.hasTable(\n tableName\n );\n if (!migrationTableExists) {\n return null;\n }\n\n const result = await this.knex(tableName)\n .select(\"NAME\")\n .orderBy(\"ID\", \"desc\")\n .first();\n\n return result?.NAME || null;\n } catch (error: any) {\n console.error(\"āŒ Error getting current version:\", error.message);\n return null;\n }\n }\n\n async listExecuted(): Promise<string[]> {\n try {\n const tableName = this.getFullTableName();\n\n const migrationTableExists = await (this.knex as any).schema.hasTable(\n tableName\n );\n if (!migrationTableExists) {\n return [];\n }\n\n const completed = await this.knex(tableName).select(\"NAME\").orderBy(\"ID\");\n return completed.map((c: any) => c.NAME);\n } catch (error: any) {\n console.error(\"āŒ Error listing executed migrations:\", error.message);\n return [];\n }\n }\n\n async listPending(): Promise<string[]> {\n try {\n const allFiles = this.getMigrationFiles();\n const executed = await this.listExecuted();\n return allFiles.filter((file) => !executed.includes(file));\n } catch (error: any) {\n console.error(\"āŒ Error listing pending migrations:\", error.message);\n return [];\n }\n }\n\n private getMigrationFiles(): string[] {\n const { directory, extension } = this.config;\n\n if (!fs.existsSync(directory)) {\n throw new Error(`Migration directory does not exist: ${directory}`);\n }\n\n // Support multiple extensions by checking for common migration file extensions\n const validExtensions = [\"js\", \"ts\", \"mjs\", \"cjs\"];\n const extensionToCheck = extension || \"js\";\n\n return fs\n .readdirSync(directory)\n .filter((file) => {\n // If a specific extension is configured, use only that\n if (extension && extension !== \"js\") {\n return file.endsWith(`.${extension}`);\n }\n // Otherwise, check for any valid migration extension\n return validExtensions.some((ext) => file.endsWith(`.${ext}`));\n })\n .sort();\n }\n\n private getMigrationPath(filename: string): string {\n return path.resolve(this.config.directory, filename);\n }\n}\n\n// Export a factory function for easy instantiation\nexport function createIBMiMigrationRunner(\n knex: Knex,\n config?: Partial<IBMiMigrationConfig>\n): IBMiMigrationRunner {\n return new IBMiMigrationRunner(knex, config);\n}\n"],"mappings":"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","names":["SchemaCompiler","TableCompiler","ColumnCompiler","Transaction","QueryCompiler","rawOrFn_","knex","fs","path","knex","odbc","process"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/schema/ibmi-compiler.ts","../src/schema/ibmi-tablecompiler.ts","../src/schema/ibmi-columncompiler.ts","../src/execution/ibmi-transaction.ts","../src/query/ibmi-querycompiler.ts","../src/migrations/ibmi-migration-runner.ts"],"sourcesContent":["import process from \"node:process\";\nimport knex, { Knex } from \"knex\";\nimport odbc, { Connection } from \"odbc\";\nimport SchemaCompiler from \"./schema/ibmi-compiler\";\nimport TableCompiler from \"./schema/ibmi-tablecompiler\";\nimport ColumnCompiler from \"./schema/ibmi-columncompiler\";\nimport Transaction from \"./execution/ibmi-transaction\";\nimport QueryCompiler from \"./query/ibmi-querycompiler\";\nimport { Readable } from \"node:stream\";\nimport {\n IBMiMigrationRunner,\n createIBMiMigrationRunner,\n} from \"./migrations/ibmi-migration-runner\";\n\ninterface QueryObject {\n response?: {\n rows: any[];\n rowCount: number;\n };\n sqlMethod: SqlMethod;\n output?: (runner: any, response: any) => any;\n pluck?: (row: any) => any;\n select?: boolean;\n}\n\nenum SqlMethod {\n SELECT = \"select\",\n PLUCK = \"pluck\",\n FIRST = \"first\",\n INSERT = \"insert\",\n DELETE = \"del\",\n DELETE_ALT = \"delete\",\n UPDATE = \"update\",\n COUNTER = \"counter\",\n}\n\n// Simple LRU cache for prepared statements\nclass StatementCache {\n private cache = new Map<string, any>();\n private maxSize: number;\n\n constructor(maxSize: number = 100) {\n this.maxSize = maxSize;\n }\n\n get(sql: string): any | undefined {\n const stmt = this.cache.get(sql);\n if (stmt) {\n // Move to end (most recently used)\n this.cache.delete(sql);\n this.cache.set(sql, stmt);\n }\n return stmt;\n }\n\n set(sql: string, stmt: any): void {\n // Remove oldest if at capacity\n if (this.cache.size >= this.maxSize) {\n const firstKey = this.cache.keys().next().value;\n const oldStmt = this.cache.get(firstKey);\n this.cache.delete(firstKey);\n // Close the evicted statement\n if (oldStmt && typeof oldStmt.close === \"function\") {\n oldStmt.close().catch(() => {});\n }\n }\n this.cache.set(sql, stmt);\n }\n\n async clear(): Promise<void> {\n const statements = Array.from(this.cache.values());\n this.cache.clear();\n // Close all cached statements\n await Promise.all(\n statements.map((stmt) =>\n stmt && typeof stmt.close === \"function\"\n ? stmt.close().catch(() => {})\n : Promise.resolve()\n )\n );\n }\n\n size(): number {\n return this.cache.size;\n }\n}\n\nclass DB2Client extends knex.Client {\n // Per-connection statement cache (WeakMap so it's GC'd with connections)\n private statementCaches = new WeakMap<Connection, StatementCache>();\n\n constructor(config: Knex.Config<DB2Config>) {\n super(config);\n this.driverName = \"odbc\";\n\n if (this.dialect && !this.config.client) {\n this.printWarn(\n `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.`\n );\n }\n\n const dbClient = this.config.client || this.dialect;\n if (!dbClient) {\n throw new Error(\n `knex: Required configuration option 'client' is missing.`\n );\n }\n\n if (config.version) {\n this.version = config.version;\n }\n\n if (this.driverName && config.connection) {\n this.initializeDriver();\n if (!config.pool || (config.pool && config.pool.max !== 0)) {\n this.initializePool(config);\n }\n }\n\n this.valueForUndefined = this.raw(\"DEFAULT\");\n if (config.useNullAsDefault) {\n this.valueForUndefined = null;\n }\n }\n\n // Helper method to safely stringify objects that might have circular references\n private safeStringify(obj: any, indent: number = 0): string {\n try {\n return JSON.stringify(obj, null, indent);\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"circular\")) {\n return `[Circular structure - ${typeof obj}]`;\n }\n return `[Stringify error - ${typeof obj}]`;\n }\n }\n\n _driver() {\n return odbc;\n }\n\n wrapIdentifierImpl(value: string) {\n // override default wrapper (\")\n // we don't want to use it since\n // it makes identifier case-sensitive in DB2\n\n if (!value) return value;\n\n // Handle migration tables specifically - keep simple for now\n if (\n value.includes(\"KNEX_MIGRATIONS\") ||\n value.includes(\"knex_migrations\")\n ) {\n return value.toUpperCase();\n }\n\n // For now, just return the value as-is to avoid binding issues\n // IBM i DB2 is case-insensitive by default anyway\n return value;\n }\n\n printDebug(message: string) {\n if (process.env.DEBUG === \"true\") {\n if (this.logger.debug) {\n this.logger.debug(\"knex-ibmi: \" + message);\n }\n }\n }\n\n printError(message: string) {\n if (this.logger.error) {\n this.logger.error(\"knex-ibmi: \" + message);\n }\n }\n\n printWarn(message: string) {\n if (process.env.DEBUG === \"true\") {\n if (this.logger.warn) {\n this.logger.warn(\"knex-ibmi: \" + message);\n }\n }\n }\n\n // Get a raw connection, called by the pool manager whenever a new\n // connection needs to be added to the pool.\n async acquireRawConnection() {\n this.printDebug(\"acquiring raw connection\");\n const connectionConfig = this.config.connection as DB2ConnectionConfig;\n\n if (!connectionConfig) {\n throw new Error(\"There is no connection config defined\");\n }\n\n this.printDebug(\n \"connection config: \" + this._getConnectionString(connectionConfig)\n );\n\n // Use simple ODBC connection - Knex manages the pooling\n // This fixes the double-pooling bug where a new ODBC pool was created per connection\n const connection = await this.driver.connect(\n this._getConnectionString(connectionConfig)\n );\n\n return connection;\n }\n\n // Used to explicitly close a connection, called internally by the pool manager\n // when a connection times out or the pool is shutdown.\n async destroyRawConnection(connection: any) {\n this.printDebug(\"destroy connection\");\n\n // Clean up statement cache if it exists\n const cache = this.statementCaches.get(connection);\n if (cache) {\n await cache.clear();\n this.statementCaches.delete(connection);\n }\n\n return await connection.close();\n }\n\n _getConnectionString(connectionConfig: DB2ConnectionConfig) {\n // Apply performance defaults if not explicitly set\n const defaults: DB2ConnectionParams = {\n BLOCKFETCH: 1, // Enable block fetch for better performance\n TRUEAUTOCOMMIT: 0, // Use proper transaction handling\n };\n\n // Merge defaults with user-provided params (user params take precedence)\n const connectionStringParams = {\n ...defaults,\n ...(connectionConfig.connectionStringParams || {}),\n };\n\n const connectionStringExtension = Object.keys(\n connectionStringParams\n ).reduce((result, key) => {\n const value = connectionStringParams[key];\n return `${result}${key}=${value};`;\n }, \"\");\n\n return (\n `DRIVER=${connectionConfig.driver};` +\n `SYSTEM=${connectionConfig.host};` +\n `PORT=${connectionConfig.port || 8471};` +\n `DATABASE=${connectionConfig.database};` +\n `UID=${connectionConfig.user};` +\n `PWD=${connectionConfig.password};` +\n connectionStringExtension\n );\n }\n\n // Runs the query on the specified connection, providing the bindings\n async _query(connection: Connection, obj: any) {\n const queryObject = this.normalizeQueryObject(obj);\n const method = this.determineQueryMethod(queryObject);\n queryObject.sqlMethod = method;\n\n // Special handling for UPDATE with returning clause\n if (queryObject._ibmiUpdateReturning) {\n return await this.executeUpdateReturning(connection, queryObject);\n }\n\n // Sequential multi-row insert execution path\n if (queryObject._ibmiSequentialInsert) {\n return await this.executeSequentialInsert(connection, queryObject);\n }\n\n // DELETE ... RETURNING emulation\n if (queryObject._ibmiDeleteReturning) {\n return await this.executeDeleteReturning(connection, queryObject);\n }\n\n // Debug migration queries (only if DEBUG environment variable is set)\n if (\n process.env.DEBUG === \"true\" &&\n queryObject.sql &&\n (queryObject.sql.toLowerCase().includes(\"create table\") ||\n queryObject.sql.toLowerCase().includes(\"knex_migrations\"))\n ) {\n this.printDebug(\n `Executing ${method} query: ${queryObject.sql.substring(0, 200)}...`\n );\n if (queryObject.bindings?.length) {\n this.printDebug(\n `Bindings: ${this.safeStringify(queryObject.bindings)}`\n );\n }\n }\n\n try {\n const startTime = Date.now();\n if (this.isSelectMethod(method)) {\n await this.executeSelectQuery(connection, queryObject);\n } else {\n await this.executeStatementQuery(connection, queryObject);\n }\n const endTime = Date.now();\n\n if (\n process.env.DEBUG === \"true\" &&\n queryObject.sql &&\n (queryObject.sql.toLowerCase().includes(\"create table\") ||\n queryObject.sql.toLowerCase().includes(\"knex_migrations\"))\n ) {\n this.printDebug(`${method} completed in ${endTime - startTime}ms`);\n }\n\n this.printDebug(`Query completed: ${method} (${endTime - startTime}ms)`);\n return queryObject;\n } catch (error: any) {\n // Enhanced error handling for connection issues\n const wrappedError = this.wrapError(error, method, queryObject);\n\n if (this.isConnectionError(error)) {\n this.printError(\n `Connection error during ${method} query: ${error.message}`\n );\n\n // For critical migration operations, retry once before failing\n if (this.shouldRetryQuery(queryObject, method)) {\n return await this.retryQuery(connection, queryObject, method);\n }\n\n throw wrappedError;\n }\n throw wrappedError;\n }\n }\n\n /**\n * Execute UPDATE with returning clause using transaction + SELECT approach\n * Since IBM i DB2 doesn't support FINAL TABLE with UPDATE, we:\n * 1. Execute the UPDATE statement\n * 2. Execute a SELECT to get the updated values using the same WHERE clause\n */\n private async executeUpdateReturning(\n connection: Connection,\n obj: any\n ): Promise<any> {\n const { _ibmiUpdateReturning } = obj;\n const { updateSql, selectColumns, whereClause, tableName } =\n _ibmiUpdateReturning;\n\n this.printDebug(\n \"Executing UPDATE with returning using transaction approach\"\n );\n\n try {\n // Execute the UPDATE statement\n const updateObj = {\n sql: updateSql,\n bindings: obj.bindings,\n sqlMethod: \"update\",\n };\n\n await this.executeStatementQuery(connection, updateObj);\n\n // Build and execute SELECT to get the updated values\n const selectSql = whereClause\n ? `select ${selectColumns} from ${tableName} ${whereClause}`\n : `select ${selectColumns} from ${tableName}`;\n\n // Extract only WHERE clause bindings for SELECT\n // UPDATE bindings format: [set_values..., where_values...]\n // We need to figure out how many bindings are for SET vs WHERE\n const updateSqlParts = updateSql.split(\" where \");\n const setClausePart = updateSqlParts[0];\n const setBindingCount = (setClausePart.match(/\\?/g) || []).length;\n const whereBindings = obj.bindings\n ? obj.bindings.slice(setBindingCount)\n : [];\n\n const selectObj = {\n sql: selectSql,\n bindings: whereBindings,\n sqlMethod: \"select\",\n response: undefined,\n };\n\n await this.executeSelectQuery(connection, selectObj);\n\n // Return the SELECT results as the final response\n obj.response = selectObj.response;\n obj.sqlMethod = \"update\";\n obj.select = true; // Mark as SELECT behavior to return rows instead of rowCount\n return obj;\n } catch (error: any) {\n this.printError(`UPDATE with returning failed: ${error.message}`);\n throw this.wrapError(error, \"update_returning\", obj);\n }\n }\n\n private async executeSequentialInsert(\n connection: Connection,\n obj: any\n ): Promise<any> {\n const meta = obj._ibmiSequentialInsert;\n const { rows, columns, tableName, returning, identityOnly } = meta;\n this.printDebug(\"Executing sequential multi-row insert\");\n const insertedRows: any[] = [];\n\n const transactional =\n (this.config as any)?.ibmi?.sequentialInsertTransactional === true;\n let beganTx = false;\n if (transactional) {\n try {\n await connection.query(\"BEGIN\");\n beganTx = true;\n } catch (e) {\n this.printWarn(\n \"Could not begin transaction for sequential insert; proceeding without\"\n );\n }\n }\n\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i];\n const colList = columns.join(\", \");\n const placeholders = columns.map(() => \"?\").join(\", \");\n const singleValues = columns.map((c: string) => row[c]);\n const baseInsert = `insert into ${tableName} (${colList}) values (${placeholders})`;\n const selectCols = returning\n ? this.queryCompiler({} as any).formatter.columnize(returning)\n : \"IDENTITY_VAL_LOCAL()\";\n const wrapped = `select ${selectCols} from FINAL TABLE(${baseInsert})`;\n const singleObj = {\n sql: wrapped,\n bindings: singleValues,\n sqlMethod: \"insert\",\n response: undefined,\n };\n await this.executeStatementQuery(connection, singleObj);\n const resp = (singleObj as any).response?.rows;\n if (resp) insertedRows.push(...resp);\n }\n\n if (transactional && beganTx) {\n try {\n await connection.query(\"COMMIT\");\n } catch (commitErr) {\n this.printError(\n \"Commit failed for sequential insert, attempting rollback: \" +\n (commitErr as any)?.message\n );\n try {\n await connection.query(\"ROLLBACK\");\n } catch {\n /* ignore */\n }\n throw commitErr;\n }\n }\n\n obj.response = { rows: insertedRows, rowCount: insertedRows.length };\n obj.sqlMethod = \"insert\";\n obj.select = true;\n return obj;\n }\n\n private async executeDeleteReturning(\n connection: Connection,\n obj: any\n ): Promise<any> {\n const meta = obj._ibmiDeleteReturning;\n const { deleteSql, selectColumns, whereClause, tableName } = meta;\n this.printDebug(\"Executing DELETE with returning emulation\");\n try {\n // SELECT rows first\n const selectSql = whereClause\n ? `select ${selectColumns} from ${tableName} ${whereClause}`\n : `select ${selectColumns} from ${tableName}`;\n const selectObj = {\n sql: selectSql,\n bindings: obj.bindings,\n sqlMethod: \"select\",\n response: undefined,\n };\n await this.executeSelectQuery(connection, selectObj);\n const rowsToReturn = (selectObj as any).response?.rows || [];\n // Execute DELETE\n const deleteObj = {\n sql: deleteSql,\n bindings: obj.bindings,\n sqlMethod: \"del\",\n response: undefined,\n };\n await this.executeStatementQuery(connection, deleteObj);\n obj.response = { rows: rowsToReturn, rowCount: rowsToReturn.length };\n obj.sqlMethod = \"del\";\n obj.select = true;\n return obj;\n } catch (error: any) {\n this.printError(`DELETE with returning failed: ${error.message}`);\n throw this.wrapError(error, \"delete_returning\", obj);\n }\n }\n\n private normalizeQueryObject(obj: any): any {\n if (!obj || typeof obj === \"string\") {\n return { sql: obj };\n }\n return obj;\n }\n\n private determineQueryMethod(obj: any): string {\n return (\n obj.hasOwnProperty(\"method\") && obj.method !== \"raw\"\n ? obj.method\n : obj.sql.split(\" \")[0]\n ).toLowerCase();\n }\n\n private isSelectMethod(method: string): boolean {\n return method === \"select\" || method === \"first\" || method === \"pluck\";\n }\n\n private async executeSelectQuery(\n connection: Connection,\n obj: { sql: string; bindings: any[]; response: unknown }\n ): Promise<void> {\n const rows: Record<any, any>[] = await connection.query(\n obj.sql,\n obj.bindings\n );\n if (rows) {\n obj.response = { rows, rowCount: rows.length };\n }\n }\n\n private async executeStatementQuery(\n connection: Connection,\n obj: any\n ): Promise<void> {\n let statement: any;\n let usedCache = false;\n const cacheEnabled =\n (this.config as any)?.ibmi?.preparedStatementCache === true;\n\n try {\n // Try to use cached statement if enabled\n if (cacheEnabled) {\n let cache = this.statementCaches.get(connection);\n if (!cache) {\n const cacheSize =\n (this.config as any)?.ibmi?.preparedStatementCacheSize || 100;\n cache = new StatementCache(cacheSize);\n this.statementCaches.set(connection, cache);\n }\n\n statement = cache.get(obj.sql);\n if (statement) {\n usedCache = true;\n this.printDebug(\n `Using cached statement for: ${obj.sql.substring(0, 50)}...`\n );\n } else {\n // Create and cache new statement\n statement = await connection.createStatement();\n await statement.prepare(obj.sql);\n cache.set(obj.sql, statement);\n this.printDebug(`Cached new statement (cache size: ${cache.size()})`);\n }\n } else {\n // No caching - create statement normally\n statement = await connection.createStatement();\n await statement.prepare(obj.sql);\n }\n\n if (obj.bindings) {\n await statement.bind(obj.bindings);\n }\n\n const result = await statement.execute();\n this.printDebug(String(result));\n\n obj.response = this.formatStatementResponse(result);\n } catch (err: any) {\n // Special handling for UPDATE/DELETE queries that affect 0 rows\n // Some ODBC drivers signal 0-row DML via empty error/\"no data\" (SQLSTATE 02000)\n const sql = (obj.sql || \"\").toLowerCase();\n const isDml =\n obj.sqlMethod === SqlMethod.UPDATE ||\n sql.includes(\" update \") ||\n sql.startsWith(\"update\") ||\n obj.sqlMethod === SqlMethod.DELETE ||\n sql.includes(\" delete \") ||\n sql.startsWith(\"delete\");\n\n const odbcErrors = err?.odbcErrors;\n const isEmptyOdbcError =\n Array.isArray(odbcErrors) && odbcErrors.length === 0;\n const hasNoDataState = Array.isArray(odbcErrors)\n ? odbcErrors.some(\n (e: any) =>\n String(e?.state || e?.SQLSTATE || \"\").toUpperCase() === \"02000\"\n )\n : false;\n\n if (\n isDml &&\n (isEmptyOdbcError || hasNoDataState || this.isNoDataError(err))\n ) {\n this.printWarn(\n `ODBC signaled no-data for ${sql.includes(\"update\") ? \"UPDATE\" : \"DELETE\"}; treating as 0 rows affected`\n );\n obj.response = { rows: [], rowCount: 0 };\n return;\n }\n\n this.printError(this.safeStringify(err));\n throw err;\n } finally {\n // Only close statement if it's not cached\n if (!usedCache && statement && typeof statement.close === \"function\") {\n try {\n await statement.close();\n } catch (closeErr) {\n // Ignore close errors, log in debug mode only\n this.printDebug(\n `Error closing statement: ${this.safeStringify(closeErr, 2)}`\n );\n }\n }\n }\n }\n\n private isNoDataError(error: any): boolean {\n if (!error) return false;\n const msg = String(error?.message || error || \"\").toLowerCase();\n // Match common indicators of 0-row DML reported as error\n return (\n msg.includes(\"02000\") ||\n msg.includes(\"no data\") ||\n msg.includes(\"no rows\") ||\n msg.includes(\"0 rows\")\n );\n }\n\n /**\n * Format statement response from ODBC driver\n * Handles special case for IDENTITY_VAL_LOCAL() function\n */\n private formatStatementResponse(result: any): {\n rows: any;\n rowCount: number;\n } {\n const isIdentityQuery = result.statement?.includes(\"IDENTITY_VAL_LOCAL()\");\n\n if (isIdentityQuery && result.columns?.length > 0) {\n return {\n rows: result.map(\n (row: { [x: string]: any }) => row[result.columns[0].name]\n ),\n rowCount: result.count,\n };\n }\n\n // Normalize result for DML (UPDATE/DELETE/INSERT) to surface rowCount consistently\n const rowCount = typeof result?.count === \"number\" ? result.count : 0;\n return {\n rows: result,\n rowCount,\n };\n }\n\n async _stream(\n connection: Connection,\n obj: { sql: string; bindings: any[] },\n stream: any,\n options: {\n fetchSize?: number;\n }\n ) {\n if (!obj.sql) throw new Error(\"A query is required to stream results\");\n\n const optimizedFetchSize =\n options?.fetchSize || this.calculateOptimalFetchSize(obj.sql);\n\n return new Promise((resolve, reject) => {\n let isResolved = false;\n\n const cleanup = () => {\n if (!isResolved) {\n isResolved = true;\n }\n };\n\n stream.on(\"error\", (err: any) => {\n cleanup();\n reject(err);\n });\n\n stream.on(\"end\", () => {\n cleanup();\n resolve(undefined);\n });\n\n connection.query(\n obj.sql,\n obj.bindings,\n {\n cursor: true,\n fetchSize: optimizedFetchSize,\n },\n (error, cursor) => {\n if (error) {\n this.printError(this.safeStringify(error, 2));\n cleanup();\n reject(error);\n return;\n }\n\n const readableStream = this._createCursorStream(cursor);\n readableStream.on(\"error\", (err) => {\n cleanup();\n reject(err);\n });\n readableStream.pipe(stream);\n }\n );\n });\n }\n\n private calculateOptimalFetchSize(sql: string): number {\n const sqlLower = sql.toLowerCase();\n const hasJoins = /\\s+join\\s+/i.test(sql);\n const hasAggregates = /\\s+(count|sum|avg|max|min)\\s*\\(/i.test(sql);\n const hasOrderBy = /\\s+order\\s+by\\s+/i.test(sql);\n const hasGroupBy = /\\s+group\\s+by\\s+/i.test(sql);\n\n // For complex analytical queries, use larger fetch sizes\n if (hasJoins || hasAggregates || hasOrderBy || hasGroupBy) {\n return 500;\n }\n\n // For simple queries, use moderate fetch size\n return 100;\n }\n\n private _createCursorStream(cursor: any): Readable {\n const parentThis = this;\n let isClosed = false;\n\n return new Readable({\n objectMode: true,\n read() {\n if (isClosed) return;\n\n cursor.fetch((error: unknown, result: unknown) => {\n if (error) {\n parentThis.printError(parentThis.safeStringify(error, 2));\n isClosed = true;\n this.emit(\"error\", error);\n return;\n }\n\n if (!cursor.noData) {\n this.push(result);\n } else {\n isClosed = true;\n cursor.close((closeError: unknown) => {\n if (closeError) {\n parentThis.printError(parentThis.safeStringify(closeError, 2));\n }\n if (result) {\n this.push(result);\n }\n this.push(null); // End the stream\n });\n }\n });\n },\n destroy(err, callback) {\n if (!isClosed) {\n isClosed = true;\n cursor.close((closeError: unknown) => {\n if (closeError) {\n parentThis.printDebug(\n \"Error closing cursor during destroy: \" +\n parentThis.safeStringify(closeError)\n );\n }\n callback(err);\n });\n } else {\n callback(err);\n }\n },\n });\n }\n\n transaction(container: any, config: any, outerTx: any): Knex.Transaction {\n return new (Transaction as any)(this, container, config, outerTx);\n }\n\n schemaCompiler(tableBuilder: any) {\n return new (SchemaCompiler as any)(this, tableBuilder);\n }\n\n tableCompiler(tableBuilder: any) {\n return new (TableCompiler as any)(this, tableBuilder);\n }\n\n columnCompiler(tableCompiler: any, columnCompiler: any) {\n return new (ColumnCompiler as any)(this, tableCompiler, columnCompiler);\n }\n\n queryCompiler(builder: Knex.QueryBuilder, bindings?: any[]) {\n return new (QueryCompiler as any)(this, builder, bindings);\n }\n\n // Create IBM i-specific migration runner that bypasses Knex's problematic locking system\n createMigrationRunner(\n config?: Partial<\n import(\"./migrations/ibmi-migration-runner\").IBMiMigrationConfig\n >\n ) {\n // Pass the knex instance from the client context\n const knexInstance = (this as any).context || (this as any);\n return createIBMiMigrationRunner(knexInstance, config);\n }\n\n processResponse(obj: QueryObject | null, runner: any): any {\n if (obj === null) return null;\n\n const { response } = obj;\n\n // If there's a custom output function, use it directly without validation\n // This allows custom queries like hasTable to handle their own response format\n if (obj.output) {\n try {\n const result = obj.output(runner, response);\n return result;\n } catch (error: any) {\n // Enhanced error handling for custom output functions\n const wrappedError = this.wrapError(error, \"custom_output\", obj);\n this.printError(\n `Custom output function failed: ${wrappedError.message}`\n );\n if (this.isConnectionError(error)) {\n throw new Error(\n \"Connection closed during query processing - consider using migrations.disableTransactions: true for DDL operations\"\n );\n }\n throw wrappedError;\n }\n }\n\n // Only validate for standard SQL methods that expect rows structure\n const validationResult = this.validateResponse(obj);\n if (validationResult !== null) return validationResult;\n\n return this.processSqlMethod(obj);\n }\n\n private validateResponse(obj: QueryObject): any {\n if (!obj.response) {\n this.printDebug(\"response undefined \" + this.safeStringify(obj));\n return null;\n }\n\n // For non-select methods, it's fine if rows is empty/undefined as long as rowCount is set.\n // Do not short-circuit here; allow processSqlMethod to normalize the return value.\n\n if (!obj.response.rows) {\n this.printError(\"rows undefined \" + this.safeStringify(obj));\n return null;\n }\n\n return null;\n }\n\n private wrapError(error: any, method: string, queryObject: any): Error {\n const context = {\n method,\n sql: queryObject.sql\n ? queryObject.sql.substring(0, 100) + \"...\"\n : \"unknown\",\n timestamp: new Date().toISOString(),\n };\n\n const contextStr = this.safeStringify(context);\n\n if (this.isConnectionError(error)) {\n return new Error(\n `IBM i DB2 connection error during ${method}: ${error.message} | Context: ${contextStr}`\n );\n }\n\n if (this.isTimeoutError(error)) {\n return new Error(\n `IBM i DB2 timeout during ${method}: ${error.message} | Context: ${contextStr}`\n );\n }\n\n if (this.isSQLError(error)) {\n return new Error(\n `IBM i DB2 SQL error during ${method}: ${error.message} | Context: ${contextStr}`\n );\n }\n\n // Generic error with context\n return new Error(\n `IBM i DB2 error during ${method}: ${error.message} | Context: ${contextStr}`\n );\n }\n\n private shouldRetryQuery(queryObject: any, method: string): boolean {\n return (\n queryObject.sql?.toLowerCase().includes(\"systables\") ||\n queryObject.sql?.toLowerCase().includes(\"knex_migrations\")\n );\n }\n\n private async retryQuery(\n connection: Connection,\n queryObject: any,\n method: string\n ): Promise<any> {\n this.printDebug(`Retrying ${method} query due to connection error...`);\n try {\n // Wait a moment and retry the query\n await new Promise((resolve) => setTimeout(resolve, 1000));\n if (this.isSelectMethod(method)) {\n await this.executeSelectQuery(connection, queryObject);\n } else {\n await this.executeStatementQuery(connection, queryObject);\n }\n return queryObject;\n } catch (retryError: any) {\n this.printError(`Retry failed: ${retryError.message}`);\n // If retry fails, return empty result to prevent migration corruption\n queryObject.response = { rows: [], rowCount: 0 };\n return queryObject;\n }\n }\n\n /**\n * Extract SQLSTATE from ODBC error if available\n */\n private getSQLState(error: any): string | null {\n // Check for ODBC error format with state property\n if (error?.odbcErrors && Array.isArray(error.odbcErrors)) {\n for (const odbcErr of error.odbcErrors) {\n const state = odbcErr?.state || odbcErr?.SQLSTATE;\n if (state) return String(state).toUpperCase();\n }\n }\n return null;\n }\n\n private isConnectionError(error: any): boolean {\n const sqlState = this.getSQLState(error);\n\n // ODBC SQLSTATE codes for connection errors\n // 08xxx = Connection exception\n if (sqlState) {\n return (\n sqlState.startsWith(\"08\") || // 08001, 08003, 08007, 08S01, etc.\n sqlState === \"40003\" // Transaction rollback due to connection\n );\n }\n\n // Fallback to message parsing\n const errorMessage = (\n error.message ||\n error.toString ||\n error\n ).toLowerCase();\n return (\n errorMessage.includes(\"connection\") &&\n (errorMessage.includes(\"closed\") ||\n errorMessage.includes(\"invalid\") ||\n errorMessage.includes(\"terminated\") ||\n errorMessage.includes(\"not connected\"))\n );\n }\n\n private isTimeoutError(error: any): boolean {\n const sqlState = this.getSQLState(error);\n\n // ODBC SQLSTATE codes for timeout errors\n if (sqlState) {\n return (\n sqlState === \"HYT00\" || // Timeout expired\n sqlState === \"HYT01\" // Connection timeout expired\n );\n }\n\n // Fallback to message parsing\n const errorMessage = (\n error.message ||\n error.toString ||\n error\n ).toLowerCase();\n return (\n errorMessage.includes(\"timeout\") || errorMessage.includes(\"timed out\")\n );\n }\n\n private isSQLError(error: any): boolean {\n const sqlState = this.getSQLState(error);\n\n // ODBC SQLSTATE codes for SQL errors\n if (sqlState) {\n return (\n sqlState.startsWith(\"42\") || // Syntax error or access violation\n sqlState.startsWith(\"22\") || // Data exception\n sqlState.startsWith(\"23\") || // Integrity constraint violation\n sqlState.startsWith(\"21\") // Cardinality violation\n );\n }\n\n // Fallback to message parsing\n const errorMessage = (\n error.message ||\n error.toString ||\n error\n ).toLowerCase();\n return (\n errorMessage.includes(\"sql\") ||\n errorMessage.includes(\"syntax\") ||\n errorMessage.includes(\"table\") ||\n errorMessage.includes(\"column\")\n );\n }\n\n private processSqlMethod(obj: QueryObject): any {\n const { rows, rowCount } = obj.response!;\n\n switch (obj.sqlMethod) {\n case SqlMethod.SELECT:\n return rows;\n case SqlMethod.PLUCK:\n return rows.map(obj.pluck!);\n case SqlMethod.FIRST:\n return rows[0];\n case SqlMethod.INSERT:\n return rows;\n case SqlMethod.DELETE:\n case SqlMethod.DELETE_ALT:\n case SqlMethod.UPDATE:\n // Align with MySQL: return affected rows as a number for DML\n return obj.select ? rows : (rowCount ?? 0);\n case SqlMethod.COUNTER:\n return rowCount;\n default:\n return rows;\n }\n }\n}\n\ninterface DB2PoolConfig {\n min?: number;\n max?: number;\n acquireConnectionTimeout?: number;\n}\n\ninterface DB2ConnectionParams {\n // General Properties\n DSN?: string;\n SIGNON?: 0 | 1 | 2 | 3 | 4;\n SSL?: 0 | 1;\n\n // Server Properties\n CMT?: 0 | 1 | 2 | 3 | 4;\n CONNTYPE?: 0 | 1 | 2;\n DATABASE?: string;\n DBQ?: string;\n MAXDECPREC?: 31 | 63;\n MAXDECSCALE?: number;\n MINDIVSCALE?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;\n NAM?: 0 | 1;\n\n // Data Types Properties\n DFT?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;\n DSP?: 0 | 1 | 2 | 3 | 4;\n DEC?: 0 | 1;\n DECFLOATERROROPTION?: 0 | 1;\n DECFLOATROUNDMODE?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n MAPDECIMALFLOATDESCRIBE?: 1 | 3;\n TFT?: 0 | 1 | 2 | 3 | 4;\n TSP?: 0 | 1 | 2 | 3;\n TSFT?: 0 | 1;\n XMLCURIMPPARSE?: 0 | 1;\n XMLDECLARATION?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;\n\n // Package Properties\n DFTPKGLIB?: string;\n PKG?: string;\n XDYNAMIC?: 0 | 1;\n\n // Performance Properties\n BLOCKFETCH?: 0 | 1;\n BLOCKSIZE?: number;\n COMPRESSION?: 0 | 1;\n CONCURRENCY?: 0 | 1;\n CURSORSENSITIVITY?: 0 | 1 | 2;\n EXTCOLINFO?: 0 | 1;\n LAZYCLOSE?: 0 | 1;\n MAXFIELDLEN?: number;\n PREFETCH?: 0 | 1;\n QRYSTGLMT?: number | \"*NOMAX\";\n QUERYOPTIMIZEGOAL?: 0 | 1 | 2;\n QUERYTIMEOUT?: 0 | 1;\n\n // Language Properties\n LANGUAGEID?:\n | \"AFR\"\n | \"ARA\"\n | \"BEL\"\n | \"BGR\"\n | \"CAT\"\n | \"CHS\"\n | \"CHT\"\n | \"CSY\"\n | \"DAN\"\n | \"DES\"\n | \"DEU\"\n | \"ELL\"\n | \"ENA\"\n | \"ENB\"\n | \"ENG\"\n | \"ENP\"\n | \"ENU\"\n | \"ESP\"\n | \"EST\"\n | \"FAR\"\n | \"FIN\"\n | \"FRA\"\n | \"FRB\"\n | \"FRC\"\n | \"FRS\"\n | \"GAE\"\n | \"HEB\"\n | \"HRV\"\n | \"HUN\"\n | \"ISL\"\n | \"ITA\"\n | \"ITS\"\n | \"JPN\"\n | \"KOR\"\n | \"LAO\"\n | \"LVA\"\n | \"LTU\"\n | \"MKD\"\n | \"NLB\"\n | \"NLD\"\n | \"NON\"\n | \"NOR\"\n | \"PLK\"\n | \"PTB\"\n | \"PTG\"\n | \"RMS\"\n | \"ROM\"\n | \"RUS\"\n | \"SKY\"\n | \"SLO\"\n | \"SQI\"\n | \"SRB\"\n | \"SRL\"\n | \"SVE\"\n | \"THA\"\n | \"TRK\"\n | \"UKR\"\n | \"URD\"\n | \"VIE\";\n SORTTABLE?: string;\n SORTTYPE?: 0 | 1 | 2 | 3;\n SORTWEIGHT?: 0 | 1;\n\n // Catalog Properties\n CATALOGOPTIONS?: number;\n LIBVIEW?: 0 | 1 | 2;\n REMARKS?: 0 | 1;\n SEARCHPATTERN?: 0 | 1;\n\n // Conversion Properties\n ALLOWUNSCHAR?: 0 | 1;\n CCSID?: number;\n GRAPHIC?: 0 | 1 | 2 | 3;\n HEXPARSEROPT?: 0 | 1;\n TRANSLATE?: 0 | 1;\n TRIMCHAR?: 0 | 1;\n UNICODESQL?: 0 | 1;\n XLATEDLL?: string;\n XLATEOPT?: number;\n\n // Diagnostic Properties\n QAQQINILIB?: string;\n SQDIAGCODE?: string;\n TRACE?: number;\n\n // Other Properties\n ALWAYSCALCLEN?: 0 | 1;\n ALLOWPROCCALLS?: 0 | 1;\n CONCURRENTACCESSRESOLUTION?: 0 | 1 | 2 | 3;\n DB2SQLSTATES?: 0 | 1;\n DATETIMETOCHAR?: number;\n DBCSNoTruncError?: 0 | 1;\n DEBUG?: number;\n KEEPALIVE?: 0 | 1 | 2;\n LOGINTIMEOUT?: number;\n TIMEOUT?: number;\n TRUEAUTOCOMMIT?: 0 | 1;\n NEWPWD?: string;\n XALCS?: 0 | 1;\n XALOCKTIMEOUT?: number;\n XATXNTIMEOUT?: number;\n}\n\ninterface DB2ConnectionConfig {\n database: string;\n host: string;\n port: 8471 | 9471 | number;\n user: string;\n password: string;\n driver: \"IBM i Access ODBC Driver\" | string;\n connectionStringParams?: DB2ConnectionParams;\n}\n\nexport interface DB2Config extends Knex.Config {\n client: any;\n connection: DB2ConnectionConfig;\n pool?: DB2PoolConfig;\n ibmi?: {\n multiRowInsert?: \"auto\" | \"sequential\" | \"disabled\";\n sequentialInsertTransactional?: boolean;\n preparedStatementCache?: boolean; // Enable per-connection statement caching\n preparedStatementCacheSize?: number; // Max cached statements per connection (default: 100)\n readUncommitted?: boolean; // Append WITH UR to SELECT queries\n };\n}\n\nexport const DB2Dialect = DB2Client;\nexport { IBMiMigrationRunner, createIBMiMigrationRunner };\nexport default DB2Client;\n","import SchemaCompiler from \"knex/lib/schema/compiler.js\";\n\nclass IBMiSchemaCompiler extends SchemaCompiler {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n hasTable(tableName: string) {\n const upperName = String(tableName).toUpperCase();\n\n // Extract schema and table name if qualified\n let schemaName: string | null = null;\n let actualTableName = upperName;\n\n if (upperName.includes(\".\")) {\n const parts = upperName.split(\".\");\n schemaName = parts[0];\n actualTableName = parts[1];\n }\n\n // Use schema from the builder if available\n const builderSchema = (this.builder as any)._schema;\n if (builderSchema) {\n schemaName = builderSchema.toUpperCase();\n }\n\n let sql: string;\n let bindings: any[];\n\n if (schemaName) {\n sql = `select count(*) as table_count from QSYS2.SYSTABLES where UPPER(TABLE_NAME) = ? AND UPPER(TABLE_SCHEMA) = ?`;\n bindings = [actualTableName, schemaName];\n } else {\n sql = `select count(*) as table_count from QSYS2.SYSTABLES where UPPER(TABLE_NAME) = ?`;\n bindings = [actualTableName];\n }\n\n this.pushQuery({\n sql,\n bindings,\n output: (runner: any, resp: any) => {\n // Handle the response from the ODBC query\n // The first parameter is the runner, the second is the actual response\n if (!resp) {\n return false;\n }\n\n // Check if response is an array with results\n if (Array.isArray(resp) && resp.length > 0) {\n const firstRow = resp[0];\n if (firstRow && typeof firstRow === \"object\") {\n // Look for table_count or any count field\n const count =\n firstRow.table_count ||\n firstRow.TABLE_COUNT ||\n firstRow.count ||\n firstRow.COUNT ||\n 0;\n return count > 0;\n }\n }\n\n // Handle ODBC response format with numeric keys\n if (typeof resp === \"object\" && resp !== null) {\n // Check for ODBC array-like response with numeric indices\n const keys = Object.keys(resp);\n for (const key of keys) {\n if (!isNaN(parseInt(key))) {\n const row = resp[key];\n if (row && typeof row === \"object\") {\n const count =\n row.table_count ||\n row.TABLE_COUNT ||\n row.count ||\n row.COUNT ||\n 0;\n return count > 0;\n }\n }\n }\n\n // Handle response with rows property\n if (resp.rows && Array.isArray(resp.rows) && resp.rows.length > 0) {\n const firstRow = resp.rows[0];\n if (firstRow && typeof firstRow === \"object\") {\n const count =\n firstRow.table_count ||\n firstRow.TABLE_COUNT ||\n firstRow.count ||\n firstRow.COUNT ||\n 0;\n return count > 0;\n }\n }\n }\n\n return false;\n },\n });\n }\n\n toSQL() {\n const sequence = (this.builder as any)._sequence as any[];\n\n for (let i = 0, l = sequence.length; i < l; i++) {\n const query = sequence[i];\n this[query.method].apply(this, query.args);\n }\n\n return this.sequence;\n }\n}\n\nfunction prefixedTableName(prefix: any, table: any) {\n return prefix ? `${prefix}.${table}` : table;\n}\n\nexport default IBMiSchemaCompiler;\n","import TableCompiler from \"knex/lib/schema/tablecompiler.js\";\nimport { Connection } from \"odbc\";\n\nclass IBMiTableCompiler extends TableCompiler {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n createQuery(columns: { sql: any[] }, ifNot: any, like: any) {\n // Note: IBM i DB2 does not support IF NOT EXISTS syntax directly\n // The ifNot parameter should be handled by checking hasTable first\n if (ifNot && this.client?.logger?.warn) {\n this.client.logger.warn(\n 'IBM i DB2: IF NOT EXISTS is not natively supported. Use hasTable() check instead.'\n );\n }\n\n let createStatement = \"\";\n\n if (like) {\n // IBM i DB2 syntax for creating table from existing structure\n createStatement = `create table ${this.tableName()} as (select * from ${this.tableNameLike()}) with no data`;\n } else {\n createStatement =\n \"create table \" +\n this.tableName() +\n (this._formatting ? \" (\\n \" : \" (\") +\n columns.sql.join(this._formatting ? \",\\n \" : \", \") +\n this._addChecks() +\n \")\";\n }\n\n this.pushQuery(createStatement);\n\n if (this.single.comment) {\n this.comment(this.single.comment);\n }\n\n if (like) {\n this.addColumns(columns, this.addColumnsPrefix);\n }\n }\n\n dropUnique(columns: string[], indexName: any) {\n indexName = indexName\n ? this.formatter.wrap(indexName)\n : this._indexCommand(\"unique\", this.tableNameRaw, columns);\n\n this.pushQuery(`drop index ${indexName}`);\n }\n\n unique(\n columns: string[],\n indexName:\n | string\n | { indexName?: string; deferrable?: string; predicate?: any }\n ) {\n let deferrable: string = \"\";\n let predicate: any;\n let finalIndexName: string | undefined;\n\n if (typeof indexName === \"object\" && indexName !== null) {\n deferrable = indexName.deferrable || \"\";\n predicate = indexName.predicate;\n finalIndexName = indexName.indexName;\n } else {\n finalIndexName = indexName;\n }\n\n if (deferrable && deferrable !== \"not deferrable\") {\n this.client.logger.warn?.(\n `IBMi: unique index \\`${finalIndexName}\\` will not be deferrable ${deferrable}.`\n );\n }\n\n const wrappedIndexName = finalIndexName\n ? this.formatter.wrap(finalIndexName)\n : this._indexCommand(\"unique\", this.tableNameRaw, columns);\n columns = this.formatter.columnize(columns);\n\n const predicateQuery = predicate\n ? \" \" + this.client.queryCompiler(predicate).where()\n : \"\";\n\n this.pushQuery(\n `create unique index ${wrappedIndexName} on ${this.tableName()} (${columns})${predicateQuery}`\n );\n }\n\n // All of the columns to \"add\" for the query\n addColumns(columns: any, prefix: any) {\n prefix = prefix || this.addColumnsPrefix;\n\n if (columns.sql.length > 0) {\n const columnSql = columns.sql.map((column) => {\n return prefix + column;\n });\n this.pushQuery({\n sql:\n (this.lowerCase ? \"alter table \" : \"ALTER TABLE \") +\n this.tableName() +\n \" \" +\n columnSql.join(\" \"),\n bindings: columns.bindings,\n });\n }\n }\n\n async commit(connection: Connection) {\n return await connection.commit();\n }\n}\n\nexport default IBMiTableCompiler;\n","import ColumnCompiler from \"knex/lib/schema/columncompiler.js\";\n\nclass IBMiColumnCompiler extends ColumnCompiler {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n increments(options = { primaryKey: true }) {\n return (\n \"int not null generated always as identity (start with 1, increment by 1)\" +\n (this.tableCompiler._canBeAddPrimaryKey(options) ? \" primary key\" : \"\")\n );\n }\n\n // Add more IBM i DB2 specific column types for better support\n bigIncrements(options = { primaryKey: true }) {\n return (\n \"bigint not null generated always as identity (start with 1, increment by 1)\" +\n (this.tableCompiler._canBeAddPrimaryKey(options) ? \" primary key\" : \"\")\n );\n }\n\n varchar(length?: number) {\n return length ? `varchar(${length})` : 'varchar(255)';\n }\n\n char(length?: number) {\n return length ? `char(${length})` : 'char(1)';\n }\n\n text() {\n // IBM i DB2 uses CLOB for large text\n return 'clob(1M)';\n }\n\n mediumtext() {\n return 'clob(16M)';\n }\n\n longtext() {\n return 'clob(2G)';\n }\n\n binary(length?: number) {\n return length ? `binary(${length})` : 'binary(1)';\n }\n\n varbinary(length?: number) {\n return length ? `varbinary(${length})` : 'varbinary(255)';\n }\n\n // IBM i DB2 decimal with precision/scale\n decimal(precision?: number, scale?: number) {\n if (precision && scale) {\n return `decimal(${precision}, ${scale})`;\n } else if (precision) {\n return `decimal(${precision})`;\n }\n return 'decimal(10, 2)';\n }\n\n // IBM i DB2 timestamp\n // Note: IBM i DB2 does not support TIMESTAMP WITH TIME ZONE\n timestamp(options?: any) {\n if (options?.useTz && this.client?.logger?.warn) {\n this.client.logger.warn(\n 'IBM i DB2 does not support TIMESTAMP WITH TIME ZONE. Using plain TIMESTAMP instead.'\n );\n }\n return 'timestamp';\n }\n\n datetime(options?: any) {\n return this.timestamp(options);\n }\n\n // IBM i DB2 date and time types\n date() {\n return 'date';\n }\n\n time() {\n return 'time';\n }\n\n // JSON support (IBM i 7.3+)\n // Note: CHECK constraints with column references are not supported in this context\n // Users should add validation constraints separately if needed\n json() {\n return 'clob(16M)';\n }\n\n jsonb() {\n // IBM i doesn't have native JSONB, use CLOB\n return 'clob(16M)';\n }\n\n // UUID support using CHAR(36)\n uuid() {\n return 'char(36)';\n }\n}\n\nexport default IBMiColumnCompiler;\n","import Transaction from \"knex/lib/execution/transaction.js\";\n\nclass IBMiTransaction extends Transaction {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n begin(connection: any): any {\n try {\n return connection.beginTransaction();\n } catch (error: any) {\n if (this.isConnectionClosed(error)) {\n console.warn(\n \"IBM i DB2: Connection closed during transaction begin, DDL operations may have caused implicit commit\"\n );\n throw new Error(\n \"Connection closed during transaction begin - consider using migrations.disableTransactions: true\"\n );\n }\n throw error;\n }\n }\n\n rollback(connection: any): any {\n try {\n return connection.rollback();\n } catch (error: any) {\n // Treat rollback on a closed connection as success to avoid hangs\n console.warn(\n \"IBM i DB2: Rollback encountered an error (likely closed connection):\",\n error?.message || error\n );\n return Promise.resolve();\n }\n }\n\n commit(connection: any): any {\n try {\n return connection.commit();\n } catch (error: any) {\n if (this.isConnectionClosed(error)) {\n console.warn(\n \"IBM i DB2: Connection closed during commit - DDL operations cause implicit commits\"\n );\n // Re-throw so Knex can surface the expected failure semantics\n throw new Error(\n \"Connection closed during commit - this is expected with DDL operations on IBM i DB2\"\n );\n }\n throw error;\n }\n }\n\n private isConnectionClosed(error: any): boolean {\n const message = String(error?.message || error || \"\").toLowerCase();\n return (\n message.includes(\"connection\") &&\n (message.includes(\"closed\") ||\n message.includes(\"invalid\") ||\n message.includes(\"terminated\") ||\n message.includes(\"not connected\"))\n );\n }\n}\n\nexport default IBMiTransaction;\n","import QueryCompiler from \"knex/lib/query/querycompiler.js\";\nimport { rawOrFn as rawOrFn_ } from \"knex/lib/formatter/wrappingFormatter.js\";\n\nclass IBMiQueryCompiler extends QueryCompiler {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n // Cache for column metadata to improve performance with repeated operations\n private columnCache = new Map<string, string[]>();\n\n // Override select method to add IBM i optimization hints\n select() {\n let sql = super.select.call(this);\n \n // Add WITH UR (uncommitted read) if configured\n const readUncommitted = this.client?.config?.ibmi?.readUncommitted === true;\n if (readUncommitted && typeof sql === 'string') {\n sql = sql + ' WITH UR';\n }\n \n return sql;\n }\n\n private formatTimestampLocal(date: Date): string {\n const pad = (n: number) => String(n).padStart(2, \"0\");\n const y = date.getFullYear();\n const m = pad(date.getMonth() + 1);\n const d = pad(date.getDate());\n const hh = pad(date.getHours());\n const mm = pad(date.getMinutes());\n const ss = pad(date.getSeconds());\n return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;\n }\n insert() {\n const insertValues = this.single.insert || [];\n const { returning } = this.single;\n\n // Handle empty insert values\n if (this.isEmptyInsertValues(insertValues)) {\n if (this.isEmptyObject(insertValues)) {\n return this.buildEmptyInsertResult(returning);\n }\n return \"\";\n }\n\n // Decide multi-row insert strategy (default: allow multi-row single statement)\n const ibmiConfig = this.client?.config?.ibmi || {};\n const multiRowStrategy = ibmiConfig.multiRowInsert || \"auto\"; // 'auto' | 'sequential' | 'disabled'\n\n // When disabled, or sequential strategy with >1 rows, fall back to first row only SQL generation here.\n // Sequential execution of additional rows is handled at runtime in the client (future enhancement).\n const isArrayInsert =\n Array.isArray(insertValues) && insertValues.length > 1;\n // Keep original values for sequential strategy metadata\n const originalValues = isArrayInsert ? insertValues.slice() : insertValues;\n const forceSingleRow =\n multiRowStrategy === \"disabled\" ||\n (multiRowStrategy === \"sequential\" && isArrayInsert);\n\n // If forcing single row, keep legacy single-row path by trimming to first element\n let workingValues: any = insertValues;\n if (forceSingleRow && isArrayInsert) {\n workingValues = [insertValues[0]];\n this.single.insert = workingValues; // mutate for downstream calls\n }\n\n // Get the standard INSERT statement from parent class (will include multi-row SQL if available)\n const standardInsert = super.insert();\n\n // If it's an object with sql property, use that; otherwise use the string directly\n const insertSql =\n typeof standardInsert === \"object\" && standardInsert.sql\n ? standardInsert.sql\n : standardInsert;\n\n // For IBM i, wrap INSERT with FINAL TABLE only when RETURNING is requested\n // Multi-row inserts without RETURNING should use plain INSERT for performance\n const multiRow = isArrayInsert && !forceSingleRow;\n \n // If multi-row insert without returning, use plain INSERT (return rowCount only)\n if (multiRow && !returning) {\n return { sql: insertSql, returning: undefined };\n }\n \n // Warn about potentially large result sets\n if (multiRow && returning === \"*\") {\n if (this.client?.printWarn) {\n this.client.printWarn(\"multi-row insert with returning * may be large\");\n }\n }\n \n // Use FINAL TABLE for single-row or when returning is specified\n const selectColumns = returning\n ? this.formatter.columnize(returning)\n : \"IDENTITY_VAL_LOCAL()\";\n const sql = `select ${selectColumns} from FINAL TABLE(${insertSql})`;\n\n // Add metadata for sequential strategy so runtime can execute remaining rows\n if (multiRowStrategy === \"sequential\" && isArrayInsert) {\n // Build column list using first row keys (sorted to match _prepInsert logic)\n const first = originalValues[0];\n const columns = Object.keys(first).sort();\n return {\n sql,\n returning: undefined,\n _ibmiSequentialInsert: {\n columns,\n rows: originalValues,\n tableName: this.tableName,\n returning: returning || null,\n identityOnly: !returning,\n },\n };\n }\n\n return { sql, returning: undefined };\n }\n\n private isEmptyInsertValues(insertValues: any): boolean {\n return (\n (Array.isArray(insertValues) && insertValues.length === 0) ||\n this.isEmptyObject(insertValues)\n );\n }\n\n private isEmptyObject(insertValues: any): boolean {\n return (\n insertValues !== null &&\n typeof insertValues === \"object\" &&\n !Array.isArray(insertValues) &&\n Object.keys(insertValues).length === 0\n );\n }\n\n private buildEmptyInsertResult(returning: any): {\n sql: string;\n returning: any;\n } {\n const selectColumns = returning\n ? this.formatter.columnize(returning)\n : \"IDENTITY_VAL_LOCAL()\";\n\n const returningSql = returning\n ? this._returning(\"insert\", returning, undefined) + \" \"\n : \"\";\n\n const insertSql = [\n this.with(),\n `insert into ${this.tableName}`,\n returningSql + this._emptyInsertValue,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const sql = `select ${selectColumns} from FINAL TABLE(${insertSql})`;\n\n return { sql, returning };\n }\n\n _buildInsertData(insertValues: string | any[], returningSql: string): string {\n const insertData = this._prepInsert(insertValues);\n\n if (insertData.columns.length > 0) {\n const parts: string[] = [];\n parts.push(\"(\" + this.formatter.columnize(insertData.columns) + \") \");\n if (returningSql) parts.push(returningSql);\n parts.push(\"values \");\n\n const rowsSql: string[] = [];\n for (const row of insertData.values) {\n const placeholders = row.map(() => \"?\").join(\", \");\n rowsSql.push(\"(\" + placeholders + \")\");\n }\n parts.push(rowsSql.join(\", \"));\n return parts.join(\"\");\n }\n\n if (\n Array.isArray(insertValues) &&\n insertValues.length === 1 &&\n insertValues[0]\n ) {\n return (returningSql || \"\") + this._emptyInsertValue;\n }\n return \"\";\n }\n\n private generateCacheKey(data: any): string {\n if (Array.isArray(data) && data.length > 0) {\n // Use the keys of the first object as cache key\n return Object.keys(data[0] || {})\n .sort()\n .join(\"|\");\n }\n if (data && typeof data === \"object\") {\n return Object.keys(data).sort().join(\"|\");\n }\n return \"\";\n }\n\n private buildFromCache(\n data: any,\n cachedColumns: string[]\n ): { columns: any; values: any } {\n const dataArray = Array.isArray(data) ? data : data ? [data] : [];\n const values: any[] = [];\n\n // Build values array using cached column order\n for (const item of dataArray) {\n if (item == null) {\n break;\n }\n const row = cachedColumns.map((column) => item[column] ?? undefined);\n values.push(row);\n }\n\n return {\n columns: cachedColumns,\n values,\n };\n }\n\n _prepInsert(data: any): { columns: any; values: any } {\n // Handle timestamps in knex migrations\n if (typeof data === \"object\" && data?.migration_time) {\n const parsed = new Date(data.migration_time);\n if (!isNaN(parsed.getTime())) {\n data.migration_time = this.formatTimestampLocal(parsed);\n }\n }\n\n const isRaw = rawOrFn_(\n data,\n undefined,\n this.builder,\n this.client,\n this.bindingsHolder\n );\n\n if (isRaw) {\n return isRaw;\n }\n\n // Normalize data to array format\n const dataArray = Array.isArray(data) ? data : data ? [data] : [];\n\n if (dataArray.length === 0) {\n return { columns: [], values: [] };\n }\n\n // Multi-row support: build unified column list from first row, then map all rows\n const firstItem = dataArray[0];\n if (!firstItem || typeof firstItem !== \"object\") {\n return { columns: [], values: [] };\n }\n\n const cacheKey = this.generateCacheKey(firstItem);\n let columns: string[];\n if (cacheKey && this.columnCache.has(cacheKey)) {\n columns = this.columnCache.get(cacheKey)!;\n } else {\n columns = Object.keys(firstItem).sort();\n if (cacheKey && columns.length > 0)\n this.columnCache.set(cacheKey, columns);\n }\n\n const values: any[] = [];\n for (const item of dataArray) {\n if (!item || typeof item !== \"object\") continue;\n values.push(columns.map((c) => item[c] ?? undefined));\n }\n\n return { columns, values };\n }\n\n update(): { sql: string; returning: any; _ibmiUpdateReturning?: any } {\n const withSQL = this.with();\n const updates = this._prepUpdate(this.single.update);\n const where = this.where();\n const order = this.order();\n const limit = this.limit();\n const { returning } = this.single;\n\n // Add IBM i v7r3+ optimization hints for UPDATE\n const optimizationHints = \"\";\n\n // Build the base update statement\n const baseUpdateSql = [\n withSQL,\n `update ${this.single.only ? \"only \" : \"\"}${this.tableName}`,\n \"set\",\n updates.join(\", \"),\n where,\n order,\n limit,\n optimizationHints,\n ]\n .filter(Boolean)\n .join(\" \");\n\n // Handle returning clause\n if (returning) {\n // For tests and toString(), show the expected FINAL TABLE format\n // But add metadata for actual execution using UPDATE + SELECT approach\n const selectColumns = this.formatter.columnize(this.single.returning);\n const expectedSql = `select ${selectColumns} from FINAL TABLE(${baseUpdateSql})`;\n\n return {\n sql: expectedSql,\n returning,\n _ibmiUpdateReturning: {\n updateSql: baseUpdateSql,\n selectColumns,\n whereClause: where,\n tableName: this.tableName,\n },\n };\n }\n\n return { sql: baseUpdateSql, returning };\n }\n\n // Emulate DELETE ... RETURNING by compiling a FINAL TABLE wrapper for display and attaching metadata\n del(): { sql: string; returning: any; _ibmiDeleteReturning?: any } {\n const baseDelete = super.del();\n const { returning } = this.single;\n if (!returning) {\n return { sql: baseDelete as string, returning: undefined };\n }\n const deleteSql =\n typeof baseDelete === \"object\" && (baseDelete as any).sql\n ? (baseDelete as any).sql\n : baseDelete;\n const selectColumns = this.formatter.columnize(returning);\n const expectedSql = `select ${selectColumns} from FINAL TABLE(${deleteSql})`;\n return {\n sql: expectedSql,\n returning,\n _ibmiDeleteReturning: {\n deleteSql,\n selectColumns,\n whereClause: this.where(),\n tableName: this.tableName,\n },\n };\n }\n\n /**\n * Handle returning clause for IBMi DB2 queries\n * Note: IBMi DB2 has limited support for RETURNING clauses\n * @param method - The SQL method (insert, update, delete)\n * @param value - The returning value\n * @param withTrigger - Trigger support (currently unused)\n */\n _returning(method: string, value: any, withTrigger: undefined) {\n switch (method) {\n case \"update\":\n case \"insert\":\n return value ? `${withTrigger ? \" into #out\" : \"\"}` : \"\";\n case \"del\":\n return value ? `${withTrigger ? \" into #out\" : \"\"}` : \"\";\n case \"rowcount\":\n return value ? \"select @@rowcount\" : \"\";\n default:\n return \"\";\n }\n }\n\n private getOptimizationHints(queryType: string, data?: any): string {\n const hints: string[] = [];\n\n // IBM i DB2 doesn't support OPTIMIZE FOR in all contexts\n // Use WITH UR (Uncommitted Read) for better concurrency instead\n if (queryType === \"select\") {\n hints.push(\"WITH UR\"); // Uncommitted Read for better performance on read-heavy workloads\n }\n\n return hints.length > 0 ? \" \" + hints.join(\" \") : \"\";\n }\n\n private getSelectOptimizationHints(sql: string): string {\n const hints: string[] = [];\n\n // Only use WITH UR for read operations on IBM i DB2\n // OPTIMIZE FOR syntax causes errors on this IBM i version\n hints.push(\"WITH UR\");\n\n return hints.length > 0 ? \" \" + hints.join(\" \") : \"\";\n }\n\n columnizeWithPrefix(prefix: string, target: string | string[]) {\n const columns = typeof target === \"string\" ? [target] : target;\n const parts: string[] = [];\n\n for (let i = 0; i < columns.length; i++) {\n if (i > 0) parts.push(\", \");\n parts.push(prefix + this.wrap(columns[i]));\n }\n\n return parts.join(\"\");\n }\n}\n\nexport default IBMiQueryCompiler;\n","import fs from \"fs\";\nimport path from \"path\";\nimport { Knex } from \"knex\";\n\nexport interface IBMiMigrationConfig {\n directory: string;\n tableName: string;\n schemaName?: string;\n extension?: string;\n}\n\nexport class IBMiMigrationRunner {\n private knex: Knex;\n private config: IBMiMigrationConfig;\n\n constructor(knex: Knex, config?: Partial<IBMiMigrationConfig>) {\n this.knex = knex;\n\n // Default configuration\n this.config = {\n directory: \"./migrations\",\n tableName: \"KNEX_MIGRATIONS\",\n schemaName: undefined,\n extension: \"js\",\n ...config,\n };\n }\n\n private getFullTableName(): string {\n return this.config.schemaName\n ? `${this.config.schemaName}.${this.config.tableName}`\n : this.config.tableName;\n }\n\n async latest(): Promise<void> {\n try {\n console.log(\n \"šŸš€ IBM i DB2 Migration Runner - bypassing Knex locking system\"\n );\n\n // Ensure the migration table exists\n const tableName = this.getFullTableName();\n\n const migrationTableExists = await (this.knex as any).schema.hasTable(\n tableName\n );\n if (!migrationTableExists) {\n console.log(`šŸ“ Creating migration table: ${tableName}`);\n await (this.knex as any).schema.createTable(tableName, (table) => {\n table.increments(\"id\").primary();\n table.string(\"name\").unique(); // Prevent duplicate migration names\n table.integer(\"batch\");\n table.timestamp(\"migration_time\");\n });\n console.log(\"āœ… Migration table created\");\n }\n\n // Get completed migrations (IBM i uses uppercase column names)\n const completed = await this.knex(tableName).select(\"NAME\").orderBy(\"ID\");\n const completedNames = completed.map((c: any) => c.NAME);\n console.log(`šŸ“‹ Found ${completedNames.length} completed migrations`);\n\n // Get migration files\n const migrationFiles = this.getMigrationFiles();\n console.log(`šŸ“ Found ${migrationFiles.length} migration files`);\n\n // Find new migrations to run\n const newMigrations = migrationFiles.filter(\n (file) => !completedNames.includes(file)\n );\n\n if (newMigrations.length === 0) {\n console.log(\"āœ… No new migrations to run\");\n return;\n }\n\n console.log(`šŸŽÆ Running ${newMigrations.length} new migrations:`);\n newMigrations.forEach((file) => console.log(` - ${file}`));\n\n // Get next batch number (IBM i uses uppercase column names)\n const batchResult = await this.knex(tableName).max(\"BATCH as max_batch\");\n const nextBatch = (batchResult[0]?.max_batch || 0) + 1;\n console.log(`šŸ“Š Using batch number: ${nextBatch}`);\n\n // Run each migration\n for (const migrationFile of newMigrations) {\n console.log(`\\nšŸ”„ Running migration: ${migrationFile}`);\n\n try {\n // Import the migration\n const migrationPath = this.getMigrationPath(migrationFile);\n const migration = await import(migrationPath);\n\n if (!migration.up || typeof migration.up !== \"function\") {\n throw new Error(`Migration ${migrationFile} has no 'up' function`);\n }\n\n // Execute the migration\n console.log(` ⚔ Executing migration...`);\n await migration.up(this.knex);\n\n // Record the migration\n await this.knex(tableName).insert({\n name: migrationFile,\n batch: nextBatch,\n migration_time: new Date(),\n });\n\n console.log(` āœ… Migration ${migrationFile} completed successfully`);\n } catch (error: any) {\n console.error(\n ` āŒ Migration ${migrationFile} failed:`,\n error.message\n );\n throw error;\n }\n }\n\n console.log(`\\nšŸŽ‰ All migrations completed successfully!`);\n } catch (error: any) {\n console.error(\"āŒ Migration runner failed:\", error.message);\n throw error;\n }\n }\n\n async rollback(steps: number = 1): Promise<void> {\n try {\n console.log(`šŸ”„ Rolling back ${steps} migration batch(es)...`);\n\n const tableName = this.getFullTableName();\n\n // Get the last batch(es) to rollback\n const batchesToRollback = await this.knex(tableName)\n .distinct(\"BATCH\")\n .orderBy(\"BATCH\", \"desc\")\n .limit(steps);\n\n if (batchesToRollback.length === 0) {\n console.log(\"āœ… No migrations to rollback\");\n return;\n }\n\n const batchNumbers = batchesToRollback.map((b: any) => b.BATCH);\n console.log(`šŸ“Š Rolling back batches: ${batchNumbers.join(\", \")}`);\n\n // Get migrations to rollback\n const migrationsToRollback = await this.knex(tableName)\n .select(\"NAME\")\n .whereIn(\"BATCH\", batchNumbers)\n .orderBy(\"ID\", \"desc\");\n\n console.log(`šŸŽÆ Rolling back ${migrationsToRollback.length} migrations:`);\n migrationsToRollback.forEach((m: any) => console.log(` - ${m.NAME}`));\n\n // Rollback each migration\n for (const migrationRecord of migrationsToRollback) {\n const migrationFile = migrationRecord.NAME;\n console.log(`\\nšŸ”„ Rolling back migration: ${migrationFile}`);\n\n try {\n // Import the migration\n const migrationPath = this.getMigrationPath(migrationFile);\n const migration = await import(migrationPath);\n\n if (migration.down && typeof migration.down === \"function\") {\n console.log(` ⚔ Executing rollback...`);\n await migration.down(this.knex);\n } else {\n console.log(\n ` āš ļø Migration ${migrationFile} has no 'down' function, skipping rollback`\n );\n }\n\n // Remove the migration record\n await this.knex(tableName).where(\"NAME\", migrationFile).del();\n\n console.log(\n ` āœ… Migration ${migrationFile} rolled back successfully`\n );\n } catch (error: any) {\n console.error(\n ` āŒ Migration ${migrationFile} rollback failed:`,\n error.message\n );\n throw error;\n }\n }\n\n console.log(`\\nšŸŽ‰ Rollback completed successfully!`);\n } catch (error: any) {\n console.error(\"āŒ Rollback failed:\", error.message);\n throw error;\n }\n }\n\n async currentVersion(): Promise<string | null> {\n try {\n const tableName = this.getFullTableName();\n\n const migrationTableExists = await (this.knex as any).schema.hasTable(\n tableName\n );\n if (!migrationTableExists) {\n return null;\n }\n\n const result = await this.knex(tableName)\n .select(\"NAME\")\n .orderBy(\"ID\", \"desc\")\n .first();\n\n return result?.NAME || null;\n } catch (error: any) {\n console.error(\"āŒ Error getting current version:\", error.message);\n return null;\n }\n }\n\n async listExecuted(): Promise<string[]> {\n try {\n const tableName = this.getFullTableName();\n\n const migrationTableExists = await (this.knex as any).schema.hasTable(\n tableName\n );\n if (!migrationTableExists) {\n return [];\n }\n\n const completed = await this.knex(tableName).select(\"NAME\").orderBy(\"ID\");\n return completed.map((c: any) => c.NAME);\n } catch (error: any) {\n console.error(\"āŒ Error listing executed migrations:\", error.message);\n return [];\n }\n }\n\n async listPending(): Promise<string[]> {\n try {\n const allFiles = this.getMigrationFiles();\n const executed = await this.listExecuted();\n return allFiles.filter((file) => !executed.includes(file));\n } catch (error: any) {\n console.error(\"āŒ Error listing pending migrations:\", error.message);\n return [];\n }\n }\n\n private getMigrationFiles(): string[] {\n const { directory, extension } = this.config;\n\n if (!fs.existsSync(directory)) {\n throw new Error(`Migration directory does not exist: ${directory}`);\n }\n\n // Support multiple extensions by checking for common migration file extensions\n const validExtensions = [\"js\", \"ts\", \"mjs\", \"cjs\"];\n const extensionToCheck = extension || \"js\";\n\n return fs\n .readdirSync(directory)\n .filter((file) => {\n // If a specific extension is configured, use only that\n if (extension && extension !== \"js\") {\n return file.endsWith(`.${extension}`);\n }\n // Otherwise, check for any valid migration extension\n return validExtensions.some((ext) => file.endsWith(`.${ext}`));\n })\n .sort();\n }\n\n private getMigrationPath(filename: string): string {\n return path.resolve(this.config.directory, filename);\n }\n}\n\n// Export a factory function for easy instantiation\nexport function createIBMiMigrationRunner(\n knex: Knex,\n config?: Partial<IBMiMigrationConfig>\n): IBMiMigrationRunner {\n return new IBMiMigrationRunner(knex, config);\n}\n"],"mappings":"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","names":["SchemaCompiler","TableCompiler","ColumnCompiler","Transaction","QueryCompiler","rawOrFn_","knex","fs","path","knex","odbc","process"]}
package/dist/index.mjs CHANGED
@@ -1127,7 +1127,9 @@ var DB2Client = class extends knex.Client {
1127
1127
  statement = cache.get(obj.sql);
1128
1128
  if (statement) {
1129
1129
  usedCache = true;
1130
- this.printDebug(`Using cached statement for: ${obj.sql.substring(0, 50)}...`);
1130
+ this.printDebug(
1131
+ `Using cached statement for: ${obj.sql.substring(0, 50)}...`
1132
+ );
1131
1133
  } else {
1132
1134
  statement = await connection.createStatement();
1133
1135
  await statement.prepare(obj.sql);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/schema/ibmi-compiler.ts","../src/schema/ibmi-tablecompiler.ts","../src/schema/ibmi-columncompiler.ts","../src/execution/ibmi-transaction.ts","../src/query/ibmi-querycompiler.ts","../src/migrations/ibmi-migration-runner.ts"],"sourcesContent":["import process from \"node:process\";\nimport knex, { Knex } from \"knex\";\nimport odbc, { Connection } from \"odbc\";\nimport SchemaCompiler from \"./schema/ibmi-compiler\";\nimport TableCompiler from \"./schema/ibmi-tablecompiler\";\nimport ColumnCompiler from \"./schema/ibmi-columncompiler\";\nimport Transaction from \"./execution/ibmi-transaction\";\nimport QueryCompiler from \"./query/ibmi-querycompiler\";\nimport { Readable } from \"node:stream\";\nimport {\n IBMiMigrationRunner,\n createIBMiMigrationRunner,\n} from \"./migrations/ibmi-migration-runner\";\n\ninterface QueryObject {\n response?: {\n rows: any[];\n rowCount: number;\n };\n sqlMethod: SqlMethod;\n output?: (runner: any, response: any) => any;\n pluck?: (row: any) => any;\n select?: boolean;\n}\n\nenum SqlMethod {\n SELECT = \"select\",\n PLUCK = \"pluck\",\n FIRST = \"first\",\n INSERT = \"insert\",\n DELETE = \"del\",\n DELETE_ALT = \"delete\",\n UPDATE = \"update\",\n COUNTER = \"counter\",\n}\n\n// Simple LRU cache for prepared statements\nclass StatementCache {\n private cache = new Map<string, any>();\n private maxSize: number;\n\n constructor(maxSize: number = 100) {\n this.maxSize = maxSize;\n }\n\n get(sql: string): any | undefined {\n const stmt = this.cache.get(sql);\n if (stmt) {\n // Move to end (most recently used)\n this.cache.delete(sql);\n this.cache.set(sql, stmt);\n }\n return stmt;\n }\n\n set(sql: string, stmt: any): void {\n // Remove oldest if at capacity\n if (this.cache.size >= this.maxSize) {\n const firstKey = this.cache.keys().next().value;\n const oldStmt = this.cache.get(firstKey);\n this.cache.delete(firstKey);\n // Close the evicted statement\n if (oldStmt && typeof oldStmt.close === 'function') {\n oldStmt.close().catch(() => {});\n }\n }\n this.cache.set(sql, stmt);\n }\n\n async clear(): Promise<void> {\n const statements = Array.from(this.cache.values());\n this.cache.clear();\n // Close all cached statements\n await Promise.all(\n statements.map((stmt) =>\n stmt && typeof stmt.close === 'function'\n ? stmt.close().catch(() => {})\n : Promise.resolve()\n )\n );\n }\n\n size(): number {\n return this.cache.size;\n }\n}\n\nclass DB2Client extends knex.Client {\n // Per-connection statement cache (WeakMap so it's GC'd with connections)\n private statementCaches = new WeakMap<Connection, StatementCache>();\n\n constructor(config: Knex.Config<DB2Config>) {\n super(config);\n this.driverName = \"odbc\";\n\n if (this.dialect && !this.config.client) {\n this.printWarn(\n `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.`\n );\n }\n\n const dbClient = this.config.client || this.dialect;\n if (!dbClient) {\n throw new Error(\n `knex: Required configuration option 'client' is missing.`\n );\n }\n\n if (config.version) {\n this.version = config.version;\n }\n\n if (this.driverName && config.connection) {\n this.initializeDriver();\n if (!config.pool || (config.pool && config.pool.max !== 0)) {\n this.initializePool(config);\n }\n }\n\n this.valueForUndefined = this.raw(\"DEFAULT\");\n if (config.useNullAsDefault) {\n this.valueForUndefined = null;\n }\n }\n\n // Helper method to safely stringify objects that might have circular references\n private safeStringify(obj: any, indent: number = 0): string {\n try {\n return JSON.stringify(obj, null, indent);\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"circular\")) {\n return `[Circular structure - ${typeof obj}]`;\n }\n return `[Stringify error - ${typeof obj}]`;\n }\n }\n\n _driver() {\n return odbc;\n }\n\n wrapIdentifierImpl(value: string) {\n // override default wrapper (\")\n // we don't want to use it since\n // it makes identifier case-sensitive in DB2\n\n if (!value) return value;\n\n // Handle migration tables specifically - keep simple for now\n if (\n value.includes(\"KNEX_MIGRATIONS\") ||\n value.includes(\"knex_migrations\")\n ) {\n return value.toUpperCase();\n }\n\n // For now, just return the value as-is to avoid binding issues\n // IBM i DB2 is case-insensitive by default anyway\n return value;\n }\n\n printDebug(message: string) {\n if (process.env.DEBUG === \"true\") {\n if (this.logger.debug) {\n this.logger.debug(\"knex-ibmi: \" + message);\n }\n }\n }\n\n printError(message: string) {\n if (this.logger.error) {\n this.logger.error(\"knex-ibmi: \" + message);\n }\n }\n\n printWarn(message: string) {\n if (process.env.DEBUG === \"true\") {\n if (this.logger.warn) {\n this.logger.warn(\"knex-ibmi: \" + message);\n }\n }\n }\n\n // Get a raw connection, called by the pool manager whenever a new\n // connection needs to be added to the pool.\n async acquireRawConnection() {\n this.printDebug(\"acquiring raw connection\");\n const connectionConfig = this.config.connection as DB2ConnectionConfig;\n\n if (!connectionConfig) {\n throw new Error(\"There is no connection config defined\");\n }\n\n this.printDebug(\n \"connection config: \" + this._getConnectionString(connectionConfig)\n );\n\n // Use simple ODBC connection - Knex manages the pooling\n // This fixes the double-pooling bug where a new ODBC pool was created per connection\n const connection = await this.driver.connect(\n this._getConnectionString(connectionConfig)\n );\n\n return connection;\n }\n\n // Used to explicitly close a connection, called internally by the pool manager\n // when a connection times out or the pool is shutdown.\n async destroyRawConnection(connection: any) {\n this.printDebug(\"destroy connection\");\n \n // Clean up statement cache if it exists\n const cache = this.statementCaches.get(connection);\n if (cache) {\n await cache.clear();\n this.statementCaches.delete(connection);\n }\n \n return await connection.close();\n }\n\n _getConnectionString(connectionConfig: DB2ConnectionConfig) {\n // Apply performance defaults if not explicitly set\n const defaults: DB2ConnectionParams = {\n BLOCKFETCH: 1, // Enable block fetch for better performance\n TRUEAUTOCOMMIT: 0, // Use proper transaction handling\n };\n\n // Merge defaults with user-provided params (user params take precedence)\n const connectionStringParams = {\n ...defaults,\n ...(connectionConfig.connectionStringParams || {}),\n };\n\n const connectionStringExtension = Object.keys(\n connectionStringParams\n ).reduce((result, key) => {\n const value = connectionStringParams[key];\n return `${result}${key}=${value};`;\n }, \"\");\n\n return (\n `DRIVER=${connectionConfig.driver};` +\n `SYSTEM=${connectionConfig.host};` +\n `PORT=${connectionConfig.port || 8471};` +\n `DATABASE=${connectionConfig.database};` +\n `UID=${connectionConfig.user};` +\n `PWD=${connectionConfig.password};` +\n connectionStringExtension\n );\n }\n\n // Runs the query on the specified connection, providing the bindings\n async _query(connection: Connection, obj: any) {\n const queryObject = this.normalizeQueryObject(obj);\n const method = this.determineQueryMethod(queryObject);\n queryObject.sqlMethod = method;\n\n // Special handling for UPDATE with returning clause\n if (queryObject._ibmiUpdateReturning) {\n return await this.executeUpdateReturning(connection, queryObject);\n }\n\n // Sequential multi-row insert execution path\n if (queryObject._ibmiSequentialInsert) {\n return await this.executeSequentialInsert(connection, queryObject);\n }\n\n // DELETE ... RETURNING emulation\n if (queryObject._ibmiDeleteReturning) {\n return await this.executeDeleteReturning(connection, queryObject);\n }\n\n // Debug migration queries (only if DEBUG environment variable is set)\n if (\n process.env.DEBUG === \"true\" &&\n queryObject.sql &&\n (queryObject.sql.toLowerCase().includes(\"create table\") ||\n queryObject.sql.toLowerCase().includes(\"knex_migrations\"))\n ) {\n this.printDebug(\n `Executing ${method} query: ${queryObject.sql.substring(0, 200)}...`\n );\n if (queryObject.bindings?.length) {\n this.printDebug(\n `Bindings: ${this.safeStringify(queryObject.bindings)}`\n );\n }\n }\n\n try {\n const startTime = Date.now();\n if (this.isSelectMethod(method)) {\n await this.executeSelectQuery(connection, queryObject);\n } else {\n await this.executeStatementQuery(connection, queryObject);\n }\n const endTime = Date.now();\n\n if (\n process.env.DEBUG === \"true\" &&\n queryObject.sql &&\n (queryObject.sql.toLowerCase().includes(\"create table\") ||\n queryObject.sql.toLowerCase().includes(\"knex_migrations\"))\n ) {\n this.printDebug(`${method} completed in ${endTime - startTime}ms`);\n }\n\n this.printDebug(`Query completed: ${method} (${endTime - startTime}ms)`);\n return queryObject;\n } catch (error: any) {\n // Enhanced error handling for connection issues\n const wrappedError = this.wrapError(error, method, queryObject);\n\n if (this.isConnectionError(error)) {\n this.printError(\n `Connection error during ${method} query: ${error.message}`\n );\n\n // For critical migration operations, retry once before failing\n if (this.shouldRetryQuery(queryObject, method)) {\n return await this.retryQuery(connection, queryObject, method);\n }\n\n throw wrappedError;\n }\n throw wrappedError;\n }\n }\n\n /**\n * Execute UPDATE with returning clause using transaction + SELECT approach\n * Since IBM i DB2 doesn't support FINAL TABLE with UPDATE, we:\n * 1. Execute the UPDATE statement\n * 2. Execute a SELECT to get the updated values using the same WHERE clause\n */\n private async executeUpdateReturning(\n connection: Connection,\n obj: any\n ): Promise<any> {\n const { _ibmiUpdateReturning } = obj;\n const { updateSql, selectColumns, whereClause, tableName } =\n _ibmiUpdateReturning;\n\n this.printDebug(\n \"Executing UPDATE with returning using transaction approach\"\n );\n\n try {\n // Execute the UPDATE statement\n const updateObj = {\n sql: updateSql,\n bindings: obj.bindings,\n sqlMethod: \"update\",\n };\n\n await this.executeStatementQuery(connection, updateObj);\n\n // Build and execute SELECT to get the updated values\n const selectSql = whereClause\n ? `select ${selectColumns} from ${tableName} ${whereClause}`\n : `select ${selectColumns} from ${tableName}`;\n\n // Extract only WHERE clause bindings for SELECT\n // UPDATE bindings format: [set_values..., where_values...]\n // We need to figure out how many bindings are for SET vs WHERE\n const updateSqlParts = updateSql.split(\" where \");\n const setClausePart = updateSqlParts[0];\n const setBindingCount = (setClausePart.match(/\\?/g) || []).length;\n const whereBindings = obj.bindings\n ? obj.bindings.slice(setBindingCount)\n : [];\n\n const selectObj = {\n sql: selectSql,\n bindings: whereBindings,\n sqlMethod: \"select\",\n response: undefined,\n };\n\n await this.executeSelectQuery(connection, selectObj);\n\n // Return the SELECT results as the final response\n obj.response = selectObj.response;\n obj.sqlMethod = \"update\";\n obj.select = true; // Mark as SELECT behavior to return rows instead of rowCount\n return obj;\n } catch (error: any) {\n this.printError(`UPDATE with returning failed: ${error.message}`);\n throw this.wrapError(error, \"update_returning\", obj);\n }\n }\n\n private async executeSequentialInsert(\n connection: Connection,\n obj: any\n ): Promise<any> {\n const meta = obj._ibmiSequentialInsert;\n const { rows, columns, tableName, returning, identityOnly } = meta;\n this.printDebug(\"Executing sequential multi-row insert\");\n const insertedRows: any[] = [];\n\n const transactional =\n (this.config as any)?.ibmi?.sequentialInsertTransactional === true;\n let beganTx = false;\n if (transactional) {\n try {\n await connection.query(\"BEGIN\");\n beganTx = true;\n } catch (e) {\n this.printWarn(\n \"Could not begin transaction for sequential insert; proceeding without\"\n );\n }\n }\n\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i];\n const colList = columns.join(\", \");\n const placeholders = columns.map(() => \"?\").join(\", \");\n const singleValues = columns.map((c: string) => row[c]);\n const baseInsert = `insert into ${tableName} (${colList}) values (${placeholders})`;\n const selectCols = returning\n ? this.queryCompiler({} as any).formatter.columnize(returning)\n : \"IDENTITY_VAL_LOCAL()\";\n const wrapped = `select ${selectCols} from FINAL TABLE(${baseInsert})`;\n const singleObj = {\n sql: wrapped,\n bindings: singleValues,\n sqlMethod: \"insert\",\n response: undefined,\n };\n await this.executeStatementQuery(connection, singleObj);\n const resp = (singleObj as any).response?.rows;\n if (resp) insertedRows.push(...resp);\n }\n\n if (transactional && beganTx) {\n try {\n await connection.query(\"COMMIT\");\n } catch (commitErr) {\n this.printError(\n \"Commit failed for sequential insert, attempting rollback: \" +\n (commitErr as any)?.message\n );\n try {\n await connection.query(\"ROLLBACK\");\n } catch {\n /* ignore */\n }\n throw commitErr;\n }\n }\n\n obj.response = { rows: insertedRows, rowCount: insertedRows.length };\n obj.sqlMethod = \"insert\";\n obj.select = true;\n return obj;\n }\n\n private async executeDeleteReturning(\n connection: Connection,\n obj: any\n ): Promise<any> {\n const meta = obj._ibmiDeleteReturning;\n const { deleteSql, selectColumns, whereClause, tableName } = meta;\n this.printDebug(\"Executing DELETE with returning emulation\");\n try {\n // SELECT rows first\n const selectSql = whereClause\n ? `select ${selectColumns} from ${tableName} ${whereClause}`\n : `select ${selectColumns} from ${tableName}`;\n const selectObj = {\n sql: selectSql,\n bindings: obj.bindings,\n sqlMethod: \"select\",\n response: undefined,\n };\n await this.executeSelectQuery(connection, selectObj);\n const rowsToReturn = (selectObj as any).response?.rows || [];\n // Execute DELETE\n const deleteObj = {\n sql: deleteSql,\n bindings: obj.bindings,\n sqlMethod: \"del\",\n response: undefined,\n };\n await this.executeStatementQuery(connection, deleteObj);\n obj.response = { rows: rowsToReturn, rowCount: rowsToReturn.length };\n obj.sqlMethod = \"del\";\n obj.select = true;\n return obj;\n } catch (error: any) {\n this.printError(`DELETE with returning failed: ${error.message}`);\n throw this.wrapError(error, \"delete_returning\", obj);\n }\n }\n\n private normalizeQueryObject(obj: any): any {\n if (!obj || typeof obj === \"string\") {\n return { sql: obj };\n }\n return obj;\n }\n\n private determineQueryMethod(obj: any): string {\n return (\n obj.hasOwnProperty(\"method\") && obj.method !== \"raw\"\n ? obj.method\n : obj.sql.split(\" \")[0]\n ).toLowerCase();\n }\n\n private isSelectMethod(method: string): boolean {\n return method === \"select\" || method === \"first\" || method === \"pluck\";\n }\n\n private async executeSelectQuery(\n connection: Connection,\n obj: { sql: string; bindings: any[]; response: unknown }\n ): Promise<void> {\n const rows: Record<any, any>[] = await connection.query(\n obj.sql,\n obj.bindings\n );\n if (rows) {\n obj.response = { rows, rowCount: rows.length };\n }\n }\n\n private async executeStatementQuery(\n connection: Connection,\n obj: any\n ): Promise<void> {\n let statement: any;\n let usedCache = false;\n const cacheEnabled = (this.config as any)?.ibmi?.preparedStatementCache === true;\n \n try {\n // Try to use cached statement if enabled\n if (cacheEnabled) {\n let cache = this.statementCaches.get(connection);\n if (!cache) {\n const cacheSize = (this.config as any)?.ibmi?.preparedStatementCacheSize || 100;\n cache = new StatementCache(cacheSize);\n this.statementCaches.set(connection, cache);\n }\n \n statement = cache.get(obj.sql);\n if (statement) {\n usedCache = true;\n this.printDebug(`Using cached statement for: ${obj.sql.substring(0, 50)}...`);\n } else {\n // Create and cache new statement\n statement = await connection.createStatement();\n await statement.prepare(obj.sql);\n cache.set(obj.sql, statement);\n this.printDebug(`Cached new statement (cache size: ${cache.size()})`);\n }\n } else {\n // No caching - create statement normally\n statement = await connection.createStatement();\n await statement.prepare(obj.sql);\n }\n\n if (obj.bindings) {\n await statement.bind(obj.bindings);\n }\n\n const result = await statement.execute();\n this.printDebug(String(result));\n\n obj.response = this.formatStatementResponse(result);\n } catch (err: any) {\n // Special handling for UPDATE/DELETE queries that affect 0 rows\n // Some ODBC drivers signal 0-row DML via empty error/\"no data\" (SQLSTATE 02000)\n const sql = (obj.sql || \"\").toLowerCase();\n const isDml =\n obj.sqlMethod === SqlMethod.UPDATE ||\n sql.includes(\" update \") ||\n sql.startsWith(\"update\") ||\n obj.sqlMethod === SqlMethod.DELETE ||\n sql.includes(\" delete \") ||\n sql.startsWith(\"delete\");\n\n const odbcErrors = err?.odbcErrors;\n const isEmptyOdbcError =\n Array.isArray(odbcErrors) && odbcErrors.length === 0;\n const hasNoDataState = Array.isArray(odbcErrors)\n ? odbcErrors.some(\n (e: any) =>\n String(e?.state || e?.SQLSTATE || \"\").toUpperCase() === \"02000\"\n )\n : false;\n\n if (\n isDml &&\n (isEmptyOdbcError || hasNoDataState || this.isNoDataError(err))\n ) {\n this.printWarn(\n `ODBC signaled no-data for ${sql.includes(\"update\") ? \"UPDATE\" : \"DELETE\"}; treating as 0 rows affected`\n );\n obj.response = { rows: [], rowCount: 0 };\n return;\n }\n\n this.printError(this.safeStringify(err));\n throw err;\n } finally {\n // Only close statement if it's not cached\n if (!usedCache && statement && typeof statement.close === \"function\") {\n try {\n await statement.close();\n } catch (closeErr) {\n // Ignore close errors, log in debug mode only\n this.printDebug(\n `Error closing statement: ${this.safeStringify(closeErr, 2)}`\n );\n }\n }\n }\n }\n\n private isNoDataError(error: any): boolean {\n if (!error) return false;\n const msg = String(error?.message || error || \"\").toLowerCase();\n // Match common indicators of 0-row DML reported as error\n return (\n msg.includes(\"02000\") ||\n msg.includes(\"no data\") ||\n msg.includes(\"no rows\") ||\n msg.includes(\"0 rows\")\n );\n }\n\n /**\n * Format statement response from ODBC driver\n * Handles special case for IDENTITY_VAL_LOCAL() function\n */\n private formatStatementResponse(result: any): {\n rows: any;\n rowCount: number;\n } {\n const isIdentityQuery = result.statement?.includes(\"IDENTITY_VAL_LOCAL()\");\n\n if (isIdentityQuery && result.columns?.length > 0) {\n return {\n rows: result.map(\n (row: { [x: string]: any }) => row[result.columns[0].name]\n ),\n rowCount: result.count,\n };\n }\n\n // Normalize result for DML (UPDATE/DELETE/INSERT) to surface rowCount consistently\n const rowCount = typeof result?.count === \"number\" ? result.count : 0;\n return {\n rows: result,\n rowCount,\n };\n }\n\n async _stream(\n connection: Connection,\n obj: { sql: string; bindings: any[] },\n stream: any,\n options: {\n fetchSize?: number;\n }\n ) {\n if (!obj.sql) throw new Error(\"A query is required to stream results\");\n\n const optimizedFetchSize =\n options?.fetchSize || this.calculateOptimalFetchSize(obj.sql);\n\n return new Promise((resolve, reject) => {\n let isResolved = false;\n\n const cleanup = () => {\n if (!isResolved) {\n isResolved = true;\n }\n };\n\n stream.on(\"error\", (err: any) => {\n cleanup();\n reject(err);\n });\n\n stream.on(\"end\", () => {\n cleanup();\n resolve(undefined);\n });\n\n connection.query(\n obj.sql,\n obj.bindings,\n {\n cursor: true,\n fetchSize: optimizedFetchSize,\n },\n (error, cursor) => {\n if (error) {\n this.printError(this.safeStringify(error, 2));\n cleanup();\n reject(error);\n return;\n }\n\n const readableStream = this._createCursorStream(cursor);\n readableStream.on(\"error\", (err) => {\n cleanup();\n reject(err);\n });\n readableStream.pipe(stream);\n }\n );\n });\n }\n\n private calculateOptimalFetchSize(sql: string): number {\n const sqlLower = sql.toLowerCase();\n const hasJoins = /\\s+join\\s+/i.test(sql);\n const hasAggregates = /\\s+(count|sum|avg|max|min)\\s*\\(/i.test(sql);\n const hasOrderBy = /\\s+order\\s+by\\s+/i.test(sql);\n const hasGroupBy = /\\s+group\\s+by\\s+/i.test(sql);\n\n // For complex analytical queries, use larger fetch sizes\n if (hasJoins || hasAggregates || hasOrderBy || hasGroupBy) {\n return 500;\n }\n\n // For simple queries, use moderate fetch size\n return 100;\n }\n\n private _createCursorStream(cursor: any): Readable {\n const parentThis = this;\n let isClosed = false;\n\n return new Readable({\n objectMode: true,\n read() {\n if (isClosed) return;\n\n cursor.fetch((error: unknown, result: unknown) => {\n if (error) {\n parentThis.printError(parentThis.safeStringify(error, 2));\n isClosed = true;\n this.emit(\"error\", error);\n return;\n }\n\n if (!cursor.noData) {\n this.push(result);\n } else {\n isClosed = true;\n cursor.close((closeError: unknown) => {\n if (closeError) {\n parentThis.printError(parentThis.safeStringify(closeError, 2));\n }\n if (result) {\n this.push(result);\n }\n this.push(null); // End the stream\n });\n }\n });\n },\n destroy(err, callback) {\n if (!isClosed) {\n isClosed = true;\n cursor.close((closeError: unknown) => {\n if (closeError) {\n parentThis.printDebug(\n \"Error closing cursor during destroy: \" +\n parentThis.safeStringify(closeError)\n );\n }\n callback(err);\n });\n } else {\n callback(err);\n }\n },\n });\n }\n\n transaction(container: any, config: any, outerTx: any): Knex.Transaction {\n return new (Transaction as any)(this, container, config, outerTx);\n }\n\n schemaCompiler(tableBuilder: any) {\n return new (SchemaCompiler as any)(this, tableBuilder);\n }\n\n tableCompiler(tableBuilder: any) {\n return new (TableCompiler as any)(this, tableBuilder);\n }\n\n columnCompiler(tableCompiler: any, columnCompiler: any) {\n return new (ColumnCompiler as any)(this, tableCompiler, columnCompiler);\n }\n\n queryCompiler(builder: Knex.QueryBuilder, bindings?: any[]) {\n return new (QueryCompiler as any)(this, builder, bindings);\n }\n\n // Create IBM i-specific migration runner that bypasses Knex's problematic locking system\n createMigrationRunner(\n config?: Partial<\n import(\"./migrations/ibmi-migration-runner\").IBMiMigrationConfig\n >\n ) {\n // Pass the knex instance from the client context\n const knexInstance = (this as any).context || (this as any);\n return createIBMiMigrationRunner(knexInstance, config);\n }\n\n processResponse(obj: QueryObject | null, runner: any): any {\n if (obj === null) return null;\n\n const { response } = obj;\n\n // If there's a custom output function, use it directly without validation\n // This allows custom queries like hasTable to handle their own response format\n if (obj.output) {\n try {\n const result = obj.output(runner, response);\n return result;\n } catch (error: any) {\n // Enhanced error handling for custom output functions\n const wrappedError = this.wrapError(error, \"custom_output\", obj);\n this.printError(\n `Custom output function failed: ${wrappedError.message}`\n );\n if (this.isConnectionError(error)) {\n throw new Error(\n \"Connection closed during query processing - consider using migrations.disableTransactions: true for DDL operations\"\n );\n }\n throw wrappedError;\n }\n }\n\n // Only validate for standard SQL methods that expect rows structure\n const validationResult = this.validateResponse(obj);\n if (validationResult !== null) return validationResult;\n\n return this.processSqlMethod(obj);\n }\n\n private validateResponse(obj: QueryObject): any {\n if (!obj.response) {\n this.printDebug(\"response undefined \" + this.safeStringify(obj));\n return null;\n }\n\n // For non-select methods, it's fine if rows is empty/undefined as long as rowCount is set.\n // Do not short-circuit here; allow processSqlMethod to normalize the return value.\n\n if (!obj.response.rows) {\n this.printError(\"rows undefined \" + this.safeStringify(obj));\n return null;\n }\n\n return null;\n }\n\n private wrapError(error: any, method: string, queryObject: any): Error {\n const context = {\n method,\n sql: queryObject.sql\n ? queryObject.sql.substring(0, 100) + \"...\"\n : \"unknown\",\n timestamp: new Date().toISOString(),\n };\n\n const contextStr = this.safeStringify(context);\n\n if (this.isConnectionError(error)) {\n return new Error(\n `IBM i DB2 connection error during ${method}: ${error.message} | Context: ${contextStr}`\n );\n }\n\n if (this.isTimeoutError(error)) {\n return new Error(\n `IBM i DB2 timeout during ${method}: ${error.message} | Context: ${contextStr}`\n );\n }\n\n if (this.isSQLError(error)) {\n return new Error(\n `IBM i DB2 SQL error during ${method}: ${error.message} | Context: ${contextStr}`\n );\n }\n\n // Generic error with context\n return new Error(\n `IBM i DB2 error during ${method}: ${error.message} | Context: ${contextStr}`\n );\n }\n\n private shouldRetryQuery(queryObject: any, method: string): boolean {\n return (\n queryObject.sql?.toLowerCase().includes(\"systables\") ||\n queryObject.sql?.toLowerCase().includes(\"knex_migrations\")\n );\n }\n\n private async retryQuery(\n connection: Connection,\n queryObject: any,\n method: string\n ): Promise<any> {\n this.printDebug(`Retrying ${method} query due to connection error...`);\n try {\n // Wait a moment and retry the query\n await new Promise((resolve) => setTimeout(resolve, 1000));\n if (this.isSelectMethod(method)) {\n await this.executeSelectQuery(connection, queryObject);\n } else {\n await this.executeStatementQuery(connection, queryObject);\n }\n return queryObject;\n } catch (retryError: any) {\n this.printError(`Retry failed: ${retryError.message}`);\n // If retry fails, return empty result to prevent migration corruption\n queryObject.response = { rows: [], rowCount: 0 };\n return queryObject;\n }\n }\n\n /**\n * Extract SQLSTATE from ODBC error if available\n */\n private getSQLState(error: any): string | null {\n // Check for ODBC error format with state property\n if (error?.odbcErrors && Array.isArray(error.odbcErrors)) {\n for (const odbcErr of error.odbcErrors) {\n const state = odbcErr?.state || odbcErr?.SQLSTATE;\n if (state) return String(state).toUpperCase();\n }\n }\n return null;\n }\n\n private isConnectionError(error: any): boolean {\n const sqlState = this.getSQLState(error);\n \n // ODBC SQLSTATE codes for connection errors\n // 08xxx = Connection exception\n if (sqlState) {\n return (\n sqlState.startsWith('08') || // 08001, 08003, 08007, 08S01, etc.\n sqlState === '40003' // Transaction rollback due to connection\n );\n }\n\n // Fallback to message parsing\n const errorMessage = (\n error.message ||\n error.toString ||\n error\n ).toLowerCase();\n return (\n errorMessage.includes(\"connection\") &&\n (errorMessage.includes(\"closed\") ||\n errorMessage.includes(\"invalid\") ||\n errorMessage.includes(\"terminated\") ||\n errorMessage.includes(\"not connected\"))\n );\n }\n\n private isTimeoutError(error: any): boolean {\n const sqlState = this.getSQLState(error);\n \n // ODBC SQLSTATE codes for timeout errors\n if (sqlState) {\n return (\n sqlState === 'HYT00' || // Timeout expired\n sqlState === 'HYT01' // Connection timeout expired\n );\n }\n\n // Fallback to message parsing\n const errorMessage = (\n error.message ||\n error.toString ||\n error\n ).toLowerCase();\n return (\n errorMessage.includes(\"timeout\") || errorMessage.includes(\"timed out\")\n );\n }\n\n private isSQLError(error: any): boolean {\n const sqlState = this.getSQLState(error);\n \n // ODBC SQLSTATE codes for SQL errors\n if (sqlState) {\n return (\n sqlState.startsWith('42') || // Syntax error or access violation\n sqlState.startsWith('22') || // Data exception\n sqlState.startsWith('23') || // Integrity constraint violation\n sqlState.startsWith('21') // Cardinality violation\n );\n }\n\n // Fallback to message parsing\n const errorMessage = (\n error.message ||\n error.toString ||\n error\n ).toLowerCase();\n return (\n errorMessage.includes(\"sql\") ||\n errorMessage.includes(\"syntax\") ||\n errorMessage.includes(\"table\") ||\n errorMessage.includes(\"column\")\n );\n }\n\n private processSqlMethod(obj: QueryObject): any {\n const { rows, rowCount } = obj.response!;\n\n switch (obj.sqlMethod) {\n case SqlMethod.SELECT:\n return rows;\n case SqlMethod.PLUCK:\n return rows.map(obj.pluck!);\n case SqlMethod.FIRST:\n return rows[0];\n case SqlMethod.INSERT:\n return rows;\n case SqlMethod.DELETE:\n case SqlMethod.DELETE_ALT:\n case SqlMethod.UPDATE:\n // Align with MySQL: return affected rows as a number for DML\n return obj.select ? rows : (rowCount ?? 0);\n case SqlMethod.COUNTER:\n return rowCount;\n default:\n return rows;\n }\n }\n}\n\ninterface DB2PoolConfig {\n min?: number;\n max?: number;\n acquireConnectionTimeout?: number;\n}\n\ninterface DB2ConnectionParams {\n CMT?: number;\n CONNTYPE?: number;\n DBQ?: string;\n MAXDECPREC?: 31 | 63;\n MAXDECSCALE?: number;\n MINDIVSCALE?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;\n NAM?: 0 | 1;\n DFT?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;\n DSP?: 0 | 1 | 2 | 3 | 4;\n DEC?: 0 | 1;\n DECFLOATERROROPTION?: 0 | 1;\n DECFLOATROUNDMODE?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n MAPDECIMALFLOATDESCRIBE?: 1 | 3;\n TFT?: 0 | 1 | 2 | 3 | 4;\n TSP?: 0 | 1 | 2 | 3;\n TSFT?: 0 | 1;\n XMLCURIMPPARSE?: 0 | 1;\n XMLDECLARATION?: 1 | 2 | 3 | 4;\n ALLOWPROCCALLS?: 0 | 1;\n XDYNAMIC?: 0 | 1;\n DFTPKGLIB?: string;\n PKG?: 0 | 1 | 2;\n BLOCKFETCH?: 0 | 1;\n COMPRESSION?: 0 | 1;\n CONCURRENCY?: 0 | 1;\n CURSORSENSITIVITY?: 0 | 1 | 2;\n EXTCOLINFO?:\n | \"SQL_DESC_AUTO_UNIQUE_VALUE\"\n | \"SQL_DESC_BASE_COLUMN_NAME\"\n | \"SQL_DESC_BASE_TABLE_NAME and SQL_DESC_TABLE_NAME\"\n | \"SQL_DESC_LABEL\"\n | \"SQL_DESC_SCHEMA_NAME\"\n | \"SQL_DESC_SEARCHABLE\"\n | \"SQL_DESC_UNNAMED\"\n | \"SQL_DESC_UPDATABLE\";\n TRUEAUTOCOMMIT?: 0 | 1;\n}\n\ninterface DB2ConnectionConfig {\n database: string;\n host: string;\n port: 8471 | 9471 | number;\n user: string;\n password: string;\n driver: \"IBM i Access ODBC Driver\" | string;\n connectionStringParams?: DB2ConnectionParams;\n}\n\nexport interface DB2Config extends Knex.Config {\n client: any;\n connection: DB2ConnectionConfig;\n pool?: DB2PoolConfig;\n ibmi?: {\n multiRowInsert?: \"auto\" | \"sequential\" | \"disabled\";\n sequentialInsertTransactional?: boolean;\n preparedStatementCache?: boolean; // Enable per-connection statement caching\n preparedStatementCacheSize?: number; // Max cached statements per connection (default: 100)\n readUncommitted?: boolean; // Append WITH UR to SELECT queries\n };\n}\n\nexport const DB2Dialect = DB2Client;\nexport { IBMiMigrationRunner, createIBMiMigrationRunner };\nexport default DB2Client;\n","import SchemaCompiler from \"knex/lib/schema/compiler.js\";\n\nclass IBMiSchemaCompiler extends SchemaCompiler {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n hasTable(tableName: string) {\n const upperName = String(tableName).toUpperCase();\n\n // Extract schema and table name if qualified\n let schemaName: string | null = null;\n let actualTableName = upperName;\n\n if (upperName.includes(\".\")) {\n const parts = upperName.split(\".\");\n schemaName = parts[0];\n actualTableName = parts[1];\n }\n\n // Use schema from the builder if available\n const builderSchema = (this.builder as any)._schema;\n if (builderSchema) {\n schemaName = builderSchema.toUpperCase();\n }\n\n let sql: string;\n let bindings: any[];\n\n if (schemaName) {\n sql = `select count(*) as table_count from QSYS2.SYSTABLES where UPPER(TABLE_NAME) = ? AND UPPER(TABLE_SCHEMA) = ?`;\n bindings = [actualTableName, schemaName];\n } else {\n sql = `select count(*) as table_count from QSYS2.SYSTABLES where UPPER(TABLE_NAME) = ?`;\n bindings = [actualTableName];\n }\n\n this.pushQuery({\n sql,\n bindings,\n output: (runner: any, resp: any) => {\n // Handle the response from the ODBC query\n // The first parameter is the runner, the second is the actual response\n if (!resp) {\n return false;\n }\n\n // Check if response is an array with results\n if (Array.isArray(resp) && resp.length > 0) {\n const firstRow = resp[0];\n if (firstRow && typeof firstRow === \"object\") {\n // Look for table_count or any count field\n const count =\n firstRow.table_count ||\n firstRow.TABLE_COUNT ||\n firstRow.count ||\n firstRow.COUNT ||\n 0;\n return count > 0;\n }\n }\n\n // Handle ODBC response format with numeric keys\n if (typeof resp === \"object\" && resp !== null) {\n // Check for ODBC array-like response with numeric indices\n const keys = Object.keys(resp);\n for (const key of keys) {\n if (!isNaN(parseInt(key))) {\n const row = resp[key];\n if (row && typeof row === \"object\") {\n const count =\n row.table_count ||\n row.TABLE_COUNT ||\n row.count ||\n row.COUNT ||\n 0;\n return count > 0;\n }\n }\n }\n\n // Handle response with rows property\n if (resp.rows && Array.isArray(resp.rows) && resp.rows.length > 0) {\n const firstRow = resp.rows[0];\n if (firstRow && typeof firstRow === \"object\") {\n const count =\n firstRow.table_count ||\n firstRow.TABLE_COUNT ||\n firstRow.count ||\n firstRow.COUNT ||\n 0;\n return count > 0;\n }\n }\n }\n\n return false;\n },\n });\n }\n\n toSQL() {\n const sequence = (this.builder as any)._sequence as any[];\n\n for (let i = 0, l = sequence.length; i < l; i++) {\n const query = sequence[i];\n this[query.method].apply(this, query.args);\n }\n\n return this.sequence;\n }\n}\n\nfunction prefixedTableName(prefix: any, table: any) {\n return prefix ? `${prefix}.${table}` : table;\n}\n\nexport default IBMiSchemaCompiler;\n","import TableCompiler from \"knex/lib/schema/tablecompiler.js\";\nimport { Connection } from \"odbc\";\n\nclass IBMiTableCompiler extends TableCompiler {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n createQuery(columns: { sql: any[] }, ifNot: any, like: any) {\n // Note: IBM i DB2 does not support IF NOT EXISTS syntax directly\n // The ifNot parameter should be handled by checking hasTable first\n if (ifNot && this.client?.logger?.warn) {\n this.client.logger.warn(\n 'IBM i DB2: IF NOT EXISTS is not natively supported. Use hasTable() check instead.'\n );\n }\n\n let createStatement = \"\";\n\n if (like) {\n // IBM i DB2 syntax for creating table from existing structure\n createStatement = `create table ${this.tableName()} as (select * from ${this.tableNameLike()}) with no data`;\n } else {\n createStatement =\n \"create table \" +\n this.tableName() +\n (this._formatting ? \" (\\n \" : \" (\") +\n columns.sql.join(this._formatting ? \",\\n \" : \", \") +\n this._addChecks() +\n \")\";\n }\n\n this.pushQuery(createStatement);\n\n if (this.single.comment) {\n this.comment(this.single.comment);\n }\n\n if (like) {\n this.addColumns(columns, this.addColumnsPrefix);\n }\n }\n\n dropUnique(columns: string[], indexName: any) {\n indexName = indexName\n ? this.formatter.wrap(indexName)\n : this._indexCommand(\"unique\", this.tableNameRaw, columns);\n\n this.pushQuery(`drop index ${indexName}`);\n }\n\n unique(\n columns: string[],\n indexName:\n | string\n | { indexName?: string; deferrable?: string; predicate?: any }\n ) {\n let deferrable: string = \"\";\n let predicate: any;\n let finalIndexName: string | undefined;\n\n if (typeof indexName === \"object\" && indexName !== null) {\n deferrable = indexName.deferrable || \"\";\n predicate = indexName.predicate;\n finalIndexName = indexName.indexName;\n } else {\n finalIndexName = indexName;\n }\n\n if (deferrable && deferrable !== \"not deferrable\") {\n this.client.logger.warn?.(\n `IBMi: unique index \\`${finalIndexName}\\` will not be deferrable ${deferrable}.`\n );\n }\n\n const wrappedIndexName = finalIndexName\n ? this.formatter.wrap(finalIndexName)\n : this._indexCommand(\"unique\", this.tableNameRaw, columns);\n columns = this.formatter.columnize(columns);\n\n const predicateQuery = predicate\n ? \" \" + this.client.queryCompiler(predicate).where()\n : \"\";\n\n this.pushQuery(\n `create unique index ${wrappedIndexName} on ${this.tableName()} (${columns})${predicateQuery}`\n );\n }\n\n // All of the columns to \"add\" for the query\n addColumns(columns: any, prefix: any) {\n prefix = prefix || this.addColumnsPrefix;\n\n if (columns.sql.length > 0) {\n const columnSql = columns.sql.map((column) => {\n return prefix + column;\n });\n this.pushQuery({\n sql:\n (this.lowerCase ? \"alter table \" : \"ALTER TABLE \") +\n this.tableName() +\n \" \" +\n columnSql.join(\" \"),\n bindings: columns.bindings,\n });\n }\n }\n\n async commit(connection: Connection) {\n return await connection.commit();\n }\n}\n\nexport default IBMiTableCompiler;\n","import ColumnCompiler from \"knex/lib/schema/columncompiler.js\";\n\nclass IBMiColumnCompiler extends ColumnCompiler {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n increments(options = { primaryKey: true }) {\n return (\n \"int not null generated always as identity (start with 1, increment by 1)\" +\n (this.tableCompiler._canBeAddPrimaryKey(options) ? \" primary key\" : \"\")\n );\n }\n\n // Add more IBM i DB2 specific column types for better support\n bigIncrements(options = { primaryKey: true }) {\n return (\n \"bigint not null generated always as identity (start with 1, increment by 1)\" +\n (this.tableCompiler._canBeAddPrimaryKey(options) ? \" primary key\" : \"\")\n );\n }\n\n varchar(length?: number) {\n return length ? `varchar(${length})` : 'varchar(255)';\n }\n\n char(length?: number) {\n return length ? `char(${length})` : 'char(1)';\n }\n\n text() {\n // IBM i DB2 uses CLOB for large text\n return 'clob(1M)';\n }\n\n mediumtext() {\n return 'clob(16M)';\n }\n\n longtext() {\n return 'clob(2G)';\n }\n\n binary(length?: number) {\n return length ? `binary(${length})` : 'binary(1)';\n }\n\n varbinary(length?: number) {\n return length ? `varbinary(${length})` : 'varbinary(255)';\n }\n\n // IBM i DB2 decimal with precision/scale\n decimal(precision?: number, scale?: number) {\n if (precision && scale) {\n return `decimal(${precision}, ${scale})`;\n } else if (precision) {\n return `decimal(${precision})`;\n }\n return 'decimal(10, 2)';\n }\n\n // IBM i DB2 timestamp\n // Note: IBM i DB2 does not support TIMESTAMP WITH TIME ZONE\n timestamp(options?: any) {\n if (options?.useTz && this.client?.logger?.warn) {\n this.client.logger.warn(\n 'IBM i DB2 does not support TIMESTAMP WITH TIME ZONE. Using plain TIMESTAMP instead.'\n );\n }\n return 'timestamp';\n }\n\n datetime(options?: any) {\n return this.timestamp(options);\n }\n\n // IBM i DB2 date and time types\n date() {\n return 'date';\n }\n\n time() {\n return 'time';\n }\n\n // JSON support (IBM i 7.3+)\n // Note: CHECK constraints with column references are not supported in this context\n // Users should add validation constraints separately if needed\n json() {\n return 'clob(16M)';\n }\n\n jsonb() {\n // IBM i doesn't have native JSONB, use CLOB\n return 'clob(16M)';\n }\n\n // UUID support using CHAR(36)\n uuid() {\n return 'char(36)';\n }\n}\n\nexport default IBMiColumnCompiler;\n","import Transaction from \"knex/lib/execution/transaction.js\";\n\nclass IBMiTransaction extends Transaction {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n begin(connection: any): any {\n try {\n return connection.beginTransaction();\n } catch (error: any) {\n if (this.isConnectionClosed(error)) {\n console.warn(\n \"IBM i DB2: Connection closed during transaction begin, DDL operations may have caused implicit commit\"\n );\n throw new Error(\n \"Connection closed during transaction begin - consider using migrations.disableTransactions: true\"\n );\n }\n throw error;\n }\n }\n\n rollback(connection: any): any {\n try {\n return connection.rollback();\n } catch (error: any) {\n // Treat rollback on a closed connection as success to avoid hangs\n console.warn(\n \"IBM i DB2: Rollback encountered an error (likely closed connection):\",\n error?.message || error\n );\n return Promise.resolve();\n }\n }\n\n commit(connection: any): any {\n try {\n return connection.commit();\n } catch (error: any) {\n if (this.isConnectionClosed(error)) {\n console.warn(\n \"IBM i DB2: Connection closed during commit - DDL operations cause implicit commits\"\n );\n // Re-throw so Knex can surface the expected failure semantics\n throw new Error(\n \"Connection closed during commit - this is expected with DDL operations on IBM i DB2\"\n );\n }\n throw error;\n }\n }\n\n private isConnectionClosed(error: any): boolean {\n const message = String(error?.message || error || \"\").toLowerCase();\n return (\n message.includes(\"connection\") &&\n (message.includes(\"closed\") ||\n message.includes(\"invalid\") ||\n message.includes(\"terminated\") ||\n message.includes(\"not connected\"))\n );\n }\n}\n\nexport default IBMiTransaction;\n","import QueryCompiler from \"knex/lib/query/querycompiler.js\";\nimport { rawOrFn as rawOrFn_ } from \"knex/lib/formatter/wrappingFormatter.js\";\n\nclass IBMiQueryCompiler extends QueryCompiler {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n // Cache for column metadata to improve performance with repeated operations\n private columnCache = new Map<string, string[]>();\n\n // Override select method to add IBM i optimization hints\n select() {\n let sql = super.select.call(this);\n \n // Add WITH UR (uncommitted read) if configured\n const readUncommitted = this.client?.config?.ibmi?.readUncommitted === true;\n if (readUncommitted && typeof sql === 'string') {\n sql = sql + ' WITH UR';\n }\n \n return sql;\n }\n\n private formatTimestampLocal(date: Date): string {\n const pad = (n: number) => String(n).padStart(2, \"0\");\n const y = date.getFullYear();\n const m = pad(date.getMonth() + 1);\n const d = pad(date.getDate());\n const hh = pad(date.getHours());\n const mm = pad(date.getMinutes());\n const ss = pad(date.getSeconds());\n return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;\n }\n insert() {\n const insertValues = this.single.insert || [];\n const { returning } = this.single;\n\n // Handle empty insert values\n if (this.isEmptyInsertValues(insertValues)) {\n if (this.isEmptyObject(insertValues)) {\n return this.buildEmptyInsertResult(returning);\n }\n return \"\";\n }\n\n // Decide multi-row insert strategy (default: allow multi-row single statement)\n const ibmiConfig = this.client?.config?.ibmi || {};\n const multiRowStrategy = ibmiConfig.multiRowInsert || \"auto\"; // 'auto' | 'sequential' | 'disabled'\n\n // When disabled, or sequential strategy with >1 rows, fall back to first row only SQL generation here.\n // Sequential execution of additional rows is handled at runtime in the client (future enhancement).\n const isArrayInsert =\n Array.isArray(insertValues) && insertValues.length > 1;\n // Keep original values for sequential strategy metadata\n const originalValues = isArrayInsert ? insertValues.slice() : insertValues;\n const forceSingleRow =\n multiRowStrategy === \"disabled\" ||\n (multiRowStrategy === \"sequential\" && isArrayInsert);\n\n // If forcing single row, keep legacy single-row path by trimming to first element\n let workingValues: any = insertValues;\n if (forceSingleRow && isArrayInsert) {\n workingValues = [insertValues[0]];\n this.single.insert = workingValues; // mutate for downstream calls\n }\n\n // Get the standard INSERT statement from parent class (will include multi-row SQL if available)\n const standardInsert = super.insert();\n\n // If it's an object with sql property, use that; otherwise use the string directly\n const insertSql =\n typeof standardInsert === \"object\" && standardInsert.sql\n ? standardInsert.sql\n : standardInsert;\n\n // For IBM i, wrap INSERT with FINAL TABLE only when RETURNING is requested\n // Multi-row inserts without RETURNING should use plain INSERT for performance\n const multiRow = isArrayInsert && !forceSingleRow;\n \n // If multi-row insert without returning, use plain INSERT (return rowCount only)\n if (multiRow && !returning) {\n return { sql: insertSql, returning: undefined };\n }\n \n // Warn about potentially large result sets\n if (multiRow && returning === \"*\") {\n if (this.client?.printWarn) {\n this.client.printWarn(\"multi-row insert with returning * may be large\");\n }\n }\n \n // Use FINAL TABLE for single-row or when returning is specified\n const selectColumns = returning\n ? this.formatter.columnize(returning)\n : \"IDENTITY_VAL_LOCAL()\";\n const sql = `select ${selectColumns} from FINAL TABLE(${insertSql})`;\n\n // Add metadata for sequential strategy so runtime can execute remaining rows\n if (multiRowStrategy === \"sequential\" && isArrayInsert) {\n // Build column list using first row keys (sorted to match _prepInsert logic)\n const first = originalValues[0];\n const columns = Object.keys(first).sort();\n return {\n sql,\n returning: undefined,\n _ibmiSequentialInsert: {\n columns,\n rows: originalValues,\n tableName: this.tableName,\n returning: returning || null,\n identityOnly: !returning,\n },\n };\n }\n\n return { sql, returning: undefined };\n }\n\n private isEmptyInsertValues(insertValues: any): boolean {\n return (\n (Array.isArray(insertValues) && insertValues.length === 0) ||\n this.isEmptyObject(insertValues)\n );\n }\n\n private isEmptyObject(insertValues: any): boolean {\n return (\n insertValues !== null &&\n typeof insertValues === \"object\" &&\n !Array.isArray(insertValues) &&\n Object.keys(insertValues).length === 0\n );\n }\n\n private buildEmptyInsertResult(returning: any): {\n sql: string;\n returning: any;\n } {\n const selectColumns = returning\n ? this.formatter.columnize(returning)\n : \"IDENTITY_VAL_LOCAL()\";\n\n const returningSql = returning\n ? this._returning(\"insert\", returning, undefined) + \" \"\n : \"\";\n\n const insertSql = [\n this.with(),\n `insert into ${this.tableName}`,\n returningSql + this._emptyInsertValue,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const sql = `select ${selectColumns} from FINAL TABLE(${insertSql})`;\n\n return { sql, returning };\n }\n\n _buildInsertData(insertValues: string | any[], returningSql: string): string {\n const insertData = this._prepInsert(insertValues);\n\n if (insertData.columns.length > 0) {\n const parts: string[] = [];\n parts.push(\"(\" + this.formatter.columnize(insertData.columns) + \") \");\n if (returningSql) parts.push(returningSql);\n parts.push(\"values \");\n\n const rowsSql: string[] = [];\n for (const row of insertData.values) {\n const placeholders = row.map(() => \"?\").join(\", \");\n rowsSql.push(\"(\" + placeholders + \")\");\n }\n parts.push(rowsSql.join(\", \"));\n return parts.join(\"\");\n }\n\n if (\n Array.isArray(insertValues) &&\n insertValues.length === 1 &&\n insertValues[0]\n ) {\n return (returningSql || \"\") + this._emptyInsertValue;\n }\n return \"\";\n }\n\n private generateCacheKey(data: any): string {\n if (Array.isArray(data) && data.length > 0) {\n // Use the keys of the first object as cache key\n return Object.keys(data[0] || {})\n .sort()\n .join(\"|\");\n }\n if (data && typeof data === \"object\") {\n return Object.keys(data).sort().join(\"|\");\n }\n return \"\";\n }\n\n private buildFromCache(\n data: any,\n cachedColumns: string[]\n ): { columns: any; values: any } {\n const dataArray = Array.isArray(data) ? data : data ? [data] : [];\n const values: any[] = [];\n\n // Build values array using cached column order\n for (const item of dataArray) {\n if (item == null) {\n break;\n }\n const row = cachedColumns.map((column) => item[column] ?? undefined);\n values.push(row);\n }\n\n return {\n columns: cachedColumns,\n values,\n };\n }\n\n _prepInsert(data: any): { columns: any; values: any } {\n // Handle timestamps in knex migrations\n if (typeof data === \"object\" && data?.migration_time) {\n const parsed = new Date(data.migration_time);\n if (!isNaN(parsed.getTime())) {\n data.migration_time = this.formatTimestampLocal(parsed);\n }\n }\n\n const isRaw = rawOrFn_(\n data,\n undefined,\n this.builder,\n this.client,\n this.bindingsHolder\n );\n\n if (isRaw) {\n return isRaw;\n }\n\n // Normalize data to array format\n const dataArray = Array.isArray(data) ? data : data ? [data] : [];\n\n if (dataArray.length === 0) {\n return { columns: [], values: [] };\n }\n\n // Multi-row support: build unified column list from first row, then map all rows\n const firstItem = dataArray[0];\n if (!firstItem || typeof firstItem !== \"object\") {\n return { columns: [], values: [] };\n }\n\n const cacheKey = this.generateCacheKey(firstItem);\n let columns: string[];\n if (cacheKey && this.columnCache.has(cacheKey)) {\n columns = this.columnCache.get(cacheKey)!;\n } else {\n columns = Object.keys(firstItem).sort();\n if (cacheKey && columns.length > 0)\n this.columnCache.set(cacheKey, columns);\n }\n\n const values: any[] = [];\n for (const item of dataArray) {\n if (!item || typeof item !== \"object\") continue;\n values.push(columns.map((c) => item[c] ?? undefined));\n }\n\n return { columns, values };\n }\n\n update(): { sql: string; returning: any; _ibmiUpdateReturning?: any } {\n const withSQL = this.with();\n const updates = this._prepUpdate(this.single.update);\n const where = this.where();\n const order = this.order();\n const limit = this.limit();\n const { returning } = this.single;\n\n // Add IBM i v7r3+ optimization hints for UPDATE\n const optimizationHints = \"\";\n\n // Build the base update statement\n const baseUpdateSql = [\n withSQL,\n `update ${this.single.only ? \"only \" : \"\"}${this.tableName}`,\n \"set\",\n updates.join(\", \"),\n where,\n order,\n limit,\n optimizationHints,\n ]\n .filter(Boolean)\n .join(\" \");\n\n // Handle returning clause\n if (returning) {\n // For tests and toString(), show the expected FINAL TABLE format\n // But add metadata for actual execution using UPDATE + SELECT approach\n const selectColumns = this.formatter.columnize(this.single.returning);\n const expectedSql = `select ${selectColumns} from FINAL TABLE(${baseUpdateSql})`;\n\n return {\n sql: expectedSql,\n returning,\n _ibmiUpdateReturning: {\n updateSql: baseUpdateSql,\n selectColumns,\n whereClause: where,\n tableName: this.tableName,\n },\n };\n }\n\n return { sql: baseUpdateSql, returning };\n }\n\n // Emulate DELETE ... RETURNING by compiling a FINAL TABLE wrapper for display and attaching metadata\n del(): { sql: string; returning: any; _ibmiDeleteReturning?: any } {\n const baseDelete = super.del();\n const { returning } = this.single;\n if (!returning) {\n return { sql: baseDelete as string, returning: undefined };\n }\n const deleteSql =\n typeof baseDelete === \"object\" && (baseDelete as any).sql\n ? (baseDelete as any).sql\n : baseDelete;\n const selectColumns = this.formatter.columnize(returning);\n const expectedSql = `select ${selectColumns} from FINAL TABLE(${deleteSql})`;\n return {\n sql: expectedSql,\n returning,\n _ibmiDeleteReturning: {\n deleteSql,\n selectColumns,\n whereClause: this.where(),\n tableName: this.tableName,\n },\n };\n }\n\n /**\n * Handle returning clause for IBMi DB2 queries\n * Note: IBMi DB2 has limited support for RETURNING clauses\n * @param method - The SQL method (insert, update, delete)\n * @param value - The returning value\n * @param withTrigger - Trigger support (currently unused)\n */\n _returning(method: string, value: any, withTrigger: undefined) {\n switch (method) {\n case \"update\":\n case \"insert\":\n return value ? `${withTrigger ? \" into #out\" : \"\"}` : \"\";\n case \"del\":\n return value ? `${withTrigger ? \" into #out\" : \"\"}` : \"\";\n case \"rowcount\":\n return value ? \"select @@rowcount\" : \"\";\n default:\n return \"\";\n }\n }\n\n private getOptimizationHints(queryType: string, data?: any): string {\n const hints: string[] = [];\n\n // IBM i DB2 doesn't support OPTIMIZE FOR in all contexts\n // Use WITH UR (Uncommitted Read) for better concurrency instead\n if (queryType === \"select\") {\n hints.push(\"WITH UR\"); // Uncommitted Read for better performance on read-heavy workloads\n }\n\n return hints.length > 0 ? \" \" + hints.join(\" \") : \"\";\n }\n\n private getSelectOptimizationHints(sql: string): string {\n const hints: string[] = [];\n\n // Only use WITH UR for read operations on IBM i DB2\n // OPTIMIZE FOR syntax causes errors on this IBM i version\n hints.push(\"WITH UR\");\n\n return hints.length > 0 ? \" \" + hints.join(\" \") : \"\";\n }\n\n columnizeWithPrefix(prefix: string, target: string | string[]) {\n const columns = typeof target === \"string\" ? [target] : target;\n const parts: string[] = [];\n\n for (let i = 0; i < columns.length; i++) {\n if (i > 0) parts.push(\", \");\n parts.push(prefix + this.wrap(columns[i]));\n }\n\n return parts.join(\"\");\n }\n}\n\nexport default IBMiQueryCompiler;\n","import fs from \"fs\";\nimport path from \"path\";\nimport { Knex } from \"knex\";\n\nexport interface IBMiMigrationConfig {\n directory: string;\n tableName: string;\n schemaName?: string;\n extension?: string;\n}\n\nexport class IBMiMigrationRunner {\n private knex: Knex;\n private config: IBMiMigrationConfig;\n\n constructor(knex: Knex, config?: Partial<IBMiMigrationConfig>) {\n this.knex = knex;\n\n // Default configuration\n this.config = {\n directory: \"./migrations\",\n tableName: \"KNEX_MIGRATIONS\",\n schemaName: undefined,\n extension: \"js\",\n ...config,\n };\n }\n\n private getFullTableName(): string {\n return this.config.schemaName\n ? `${this.config.schemaName}.${this.config.tableName}`\n : this.config.tableName;\n }\n\n async latest(): Promise<void> {\n try {\n console.log(\n \"šŸš€ IBM i DB2 Migration Runner - bypassing Knex locking system\"\n );\n\n // Ensure the migration table exists\n const tableName = this.getFullTableName();\n\n const migrationTableExists = await (this.knex as any).schema.hasTable(\n tableName\n );\n if (!migrationTableExists) {\n console.log(`šŸ“ Creating migration table: ${tableName}`);\n await (this.knex as any).schema.createTable(tableName, (table) => {\n table.increments(\"id\").primary();\n table.string(\"name\").unique(); // Prevent duplicate migration names\n table.integer(\"batch\");\n table.timestamp(\"migration_time\");\n });\n console.log(\"āœ… Migration table created\");\n }\n\n // Get completed migrations (IBM i uses uppercase column names)\n const completed = await this.knex(tableName).select(\"NAME\").orderBy(\"ID\");\n const completedNames = completed.map((c: any) => c.NAME);\n console.log(`šŸ“‹ Found ${completedNames.length} completed migrations`);\n\n // Get migration files\n const migrationFiles = this.getMigrationFiles();\n console.log(`šŸ“ Found ${migrationFiles.length} migration files`);\n\n // Find new migrations to run\n const newMigrations = migrationFiles.filter(\n (file) => !completedNames.includes(file)\n );\n\n if (newMigrations.length === 0) {\n console.log(\"āœ… No new migrations to run\");\n return;\n }\n\n console.log(`šŸŽÆ Running ${newMigrations.length} new migrations:`);\n newMigrations.forEach((file) => console.log(` - ${file}`));\n\n // Get next batch number (IBM i uses uppercase column names)\n const batchResult = await this.knex(tableName).max(\"BATCH as max_batch\");\n const nextBatch = (batchResult[0]?.max_batch || 0) + 1;\n console.log(`šŸ“Š Using batch number: ${nextBatch}`);\n\n // Run each migration\n for (const migrationFile of newMigrations) {\n console.log(`\\nšŸ”„ Running migration: ${migrationFile}`);\n\n try {\n // Import the migration\n const migrationPath = this.getMigrationPath(migrationFile);\n const migration = await import(migrationPath);\n\n if (!migration.up || typeof migration.up !== \"function\") {\n throw new Error(`Migration ${migrationFile} has no 'up' function`);\n }\n\n // Execute the migration\n console.log(` ⚔ Executing migration...`);\n await migration.up(this.knex);\n\n // Record the migration\n await this.knex(tableName).insert({\n name: migrationFile,\n batch: nextBatch,\n migration_time: new Date(),\n });\n\n console.log(` āœ… Migration ${migrationFile} completed successfully`);\n } catch (error: any) {\n console.error(\n ` āŒ Migration ${migrationFile} failed:`,\n error.message\n );\n throw error;\n }\n }\n\n console.log(`\\nšŸŽ‰ All migrations completed successfully!`);\n } catch (error: any) {\n console.error(\"āŒ Migration runner failed:\", error.message);\n throw error;\n }\n }\n\n async rollback(steps: number = 1): Promise<void> {\n try {\n console.log(`šŸ”„ Rolling back ${steps} migration batch(es)...`);\n\n const tableName = this.getFullTableName();\n\n // Get the last batch(es) to rollback\n const batchesToRollback = await this.knex(tableName)\n .distinct(\"BATCH\")\n .orderBy(\"BATCH\", \"desc\")\n .limit(steps);\n\n if (batchesToRollback.length === 0) {\n console.log(\"āœ… No migrations to rollback\");\n return;\n }\n\n const batchNumbers = batchesToRollback.map((b: any) => b.BATCH);\n console.log(`šŸ“Š Rolling back batches: ${batchNumbers.join(\", \")}`);\n\n // Get migrations to rollback\n const migrationsToRollback = await this.knex(tableName)\n .select(\"NAME\")\n .whereIn(\"BATCH\", batchNumbers)\n .orderBy(\"ID\", \"desc\");\n\n console.log(`šŸŽÆ Rolling back ${migrationsToRollback.length} migrations:`);\n migrationsToRollback.forEach((m: any) => console.log(` - ${m.NAME}`));\n\n // Rollback each migration\n for (const migrationRecord of migrationsToRollback) {\n const migrationFile = migrationRecord.NAME;\n console.log(`\\nšŸ”„ Rolling back migration: ${migrationFile}`);\n\n try {\n // Import the migration\n const migrationPath = this.getMigrationPath(migrationFile);\n const migration = await import(migrationPath);\n\n if (migration.down && typeof migration.down === \"function\") {\n console.log(` ⚔ Executing rollback...`);\n await migration.down(this.knex);\n } else {\n console.log(\n ` āš ļø Migration ${migrationFile} has no 'down' function, skipping rollback`\n );\n }\n\n // Remove the migration record\n await this.knex(tableName).where(\"NAME\", migrationFile).del();\n\n console.log(\n ` āœ… Migration ${migrationFile} rolled back successfully`\n );\n } catch (error: any) {\n console.error(\n ` āŒ Migration ${migrationFile} rollback failed:`,\n error.message\n );\n throw error;\n }\n }\n\n console.log(`\\nšŸŽ‰ Rollback completed successfully!`);\n } catch (error: any) {\n console.error(\"āŒ Rollback failed:\", error.message);\n throw error;\n }\n }\n\n async currentVersion(): Promise<string | null> {\n try {\n const tableName = this.getFullTableName();\n\n const migrationTableExists = await (this.knex as any).schema.hasTable(\n tableName\n );\n if (!migrationTableExists) {\n return null;\n }\n\n const result = await this.knex(tableName)\n .select(\"NAME\")\n .orderBy(\"ID\", \"desc\")\n .first();\n\n return result?.NAME || null;\n } catch (error: any) {\n console.error(\"āŒ Error getting current version:\", error.message);\n return null;\n }\n }\n\n async listExecuted(): Promise<string[]> {\n try {\n const tableName = this.getFullTableName();\n\n const migrationTableExists = await (this.knex as any).schema.hasTable(\n tableName\n );\n if (!migrationTableExists) {\n return [];\n }\n\n const completed = await this.knex(tableName).select(\"NAME\").orderBy(\"ID\");\n return completed.map((c: any) => c.NAME);\n } catch (error: any) {\n console.error(\"āŒ Error listing executed migrations:\", error.message);\n return [];\n }\n }\n\n async listPending(): Promise<string[]> {\n try {\n const allFiles = this.getMigrationFiles();\n const executed = await this.listExecuted();\n return allFiles.filter((file) => !executed.includes(file));\n } catch (error: any) {\n console.error(\"āŒ Error listing pending migrations:\", error.message);\n return [];\n }\n }\n\n private getMigrationFiles(): string[] {\n const { directory, extension } = this.config;\n\n if (!fs.existsSync(directory)) {\n throw new Error(`Migration directory does not exist: ${directory}`);\n }\n\n // Support multiple extensions by checking for common migration file extensions\n const validExtensions = [\"js\", \"ts\", \"mjs\", \"cjs\"];\n const extensionToCheck = extension || \"js\";\n\n return fs\n .readdirSync(directory)\n .filter((file) => {\n // If a specific extension is configured, use only that\n if (extension && extension !== \"js\") {\n return file.endsWith(`.${extension}`);\n }\n // Otherwise, check for any valid migration extension\n return validExtensions.some((ext) => file.endsWith(`.${ext}`));\n })\n .sort();\n }\n\n private getMigrationPath(filename: string): string {\n return path.resolve(this.config.directory, filename);\n }\n}\n\n// Export a factory function for easy instantiation\nexport function createIBMiMigrationRunner(\n knex: Knex,\n config?: Partial<IBMiMigrationConfig>\n): IBMiMigrationRunner {\n return new IBMiMigrationRunner(knex, config);\n}\n"],"mappings":"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","names":["knex"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/schema/ibmi-compiler.ts","../src/schema/ibmi-tablecompiler.ts","../src/schema/ibmi-columncompiler.ts","../src/execution/ibmi-transaction.ts","../src/query/ibmi-querycompiler.ts","../src/migrations/ibmi-migration-runner.ts"],"sourcesContent":["import process from \"node:process\";\nimport knex, { Knex } from \"knex\";\nimport odbc, { Connection } from \"odbc\";\nimport SchemaCompiler from \"./schema/ibmi-compiler\";\nimport TableCompiler from \"./schema/ibmi-tablecompiler\";\nimport ColumnCompiler from \"./schema/ibmi-columncompiler\";\nimport Transaction from \"./execution/ibmi-transaction\";\nimport QueryCompiler from \"./query/ibmi-querycompiler\";\nimport { Readable } from \"node:stream\";\nimport {\n IBMiMigrationRunner,\n createIBMiMigrationRunner,\n} from \"./migrations/ibmi-migration-runner\";\n\ninterface QueryObject {\n response?: {\n rows: any[];\n rowCount: number;\n };\n sqlMethod: SqlMethod;\n output?: (runner: any, response: any) => any;\n pluck?: (row: any) => any;\n select?: boolean;\n}\n\nenum SqlMethod {\n SELECT = \"select\",\n PLUCK = \"pluck\",\n FIRST = \"first\",\n INSERT = \"insert\",\n DELETE = \"del\",\n DELETE_ALT = \"delete\",\n UPDATE = \"update\",\n COUNTER = \"counter\",\n}\n\n// Simple LRU cache for prepared statements\nclass StatementCache {\n private cache = new Map<string, any>();\n private maxSize: number;\n\n constructor(maxSize: number = 100) {\n this.maxSize = maxSize;\n }\n\n get(sql: string): any | undefined {\n const stmt = this.cache.get(sql);\n if (stmt) {\n // Move to end (most recently used)\n this.cache.delete(sql);\n this.cache.set(sql, stmt);\n }\n return stmt;\n }\n\n set(sql: string, stmt: any): void {\n // Remove oldest if at capacity\n if (this.cache.size >= this.maxSize) {\n const firstKey = this.cache.keys().next().value;\n const oldStmt = this.cache.get(firstKey);\n this.cache.delete(firstKey);\n // Close the evicted statement\n if (oldStmt && typeof oldStmt.close === \"function\") {\n oldStmt.close().catch(() => {});\n }\n }\n this.cache.set(sql, stmt);\n }\n\n async clear(): Promise<void> {\n const statements = Array.from(this.cache.values());\n this.cache.clear();\n // Close all cached statements\n await Promise.all(\n statements.map((stmt) =>\n stmt && typeof stmt.close === \"function\"\n ? stmt.close().catch(() => {})\n : Promise.resolve()\n )\n );\n }\n\n size(): number {\n return this.cache.size;\n }\n}\n\nclass DB2Client extends knex.Client {\n // Per-connection statement cache (WeakMap so it's GC'd with connections)\n private statementCaches = new WeakMap<Connection, StatementCache>();\n\n constructor(config: Knex.Config<DB2Config>) {\n super(config);\n this.driverName = \"odbc\";\n\n if (this.dialect && !this.config.client) {\n this.printWarn(\n `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.`\n );\n }\n\n const dbClient = this.config.client || this.dialect;\n if (!dbClient) {\n throw new Error(\n `knex: Required configuration option 'client' is missing.`\n );\n }\n\n if (config.version) {\n this.version = config.version;\n }\n\n if (this.driverName && config.connection) {\n this.initializeDriver();\n if (!config.pool || (config.pool && config.pool.max !== 0)) {\n this.initializePool(config);\n }\n }\n\n this.valueForUndefined = this.raw(\"DEFAULT\");\n if (config.useNullAsDefault) {\n this.valueForUndefined = null;\n }\n }\n\n // Helper method to safely stringify objects that might have circular references\n private safeStringify(obj: any, indent: number = 0): string {\n try {\n return JSON.stringify(obj, null, indent);\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"circular\")) {\n return `[Circular structure - ${typeof obj}]`;\n }\n return `[Stringify error - ${typeof obj}]`;\n }\n }\n\n _driver() {\n return odbc;\n }\n\n wrapIdentifierImpl(value: string) {\n // override default wrapper (\")\n // we don't want to use it since\n // it makes identifier case-sensitive in DB2\n\n if (!value) return value;\n\n // Handle migration tables specifically - keep simple for now\n if (\n value.includes(\"KNEX_MIGRATIONS\") ||\n value.includes(\"knex_migrations\")\n ) {\n return value.toUpperCase();\n }\n\n // For now, just return the value as-is to avoid binding issues\n // IBM i DB2 is case-insensitive by default anyway\n return value;\n }\n\n printDebug(message: string) {\n if (process.env.DEBUG === \"true\") {\n if (this.logger.debug) {\n this.logger.debug(\"knex-ibmi: \" + message);\n }\n }\n }\n\n printError(message: string) {\n if (this.logger.error) {\n this.logger.error(\"knex-ibmi: \" + message);\n }\n }\n\n printWarn(message: string) {\n if (process.env.DEBUG === \"true\") {\n if (this.logger.warn) {\n this.logger.warn(\"knex-ibmi: \" + message);\n }\n }\n }\n\n // Get a raw connection, called by the pool manager whenever a new\n // connection needs to be added to the pool.\n async acquireRawConnection() {\n this.printDebug(\"acquiring raw connection\");\n const connectionConfig = this.config.connection as DB2ConnectionConfig;\n\n if (!connectionConfig) {\n throw new Error(\"There is no connection config defined\");\n }\n\n this.printDebug(\n \"connection config: \" + this._getConnectionString(connectionConfig)\n );\n\n // Use simple ODBC connection - Knex manages the pooling\n // This fixes the double-pooling bug where a new ODBC pool was created per connection\n const connection = await this.driver.connect(\n this._getConnectionString(connectionConfig)\n );\n\n return connection;\n }\n\n // Used to explicitly close a connection, called internally by the pool manager\n // when a connection times out or the pool is shutdown.\n async destroyRawConnection(connection: any) {\n this.printDebug(\"destroy connection\");\n\n // Clean up statement cache if it exists\n const cache = this.statementCaches.get(connection);\n if (cache) {\n await cache.clear();\n this.statementCaches.delete(connection);\n }\n\n return await connection.close();\n }\n\n _getConnectionString(connectionConfig: DB2ConnectionConfig) {\n // Apply performance defaults if not explicitly set\n const defaults: DB2ConnectionParams = {\n BLOCKFETCH: 1, // Enable block fetch for better performance\n TRUEAUTOCOMMIT: 0, // Use proper transaction handling\n };\n\n // Merge defaults with user-provided params (user params take precedence)\n const connectionStringParams = {\n ...defaults,\n ...(connectionConfig.connectionStringParams || {}),\n };\n\n const connectionStringExtension = Object.keys(\n connectionStringParams\n ).reduce((result, key) => {\n const value = connectionStringParams[key];\n return `${result}${key}=${value};`;\n }, \"\");\n\n return (\n `DRIVER=${connectionConfig.driver};` +\n `SYSTEM=${connectionConfig.host};` +\n `PORT=${connectionConfig.port || 8471};` +\n `DATABASE=${connectionConfig.database};` +\n `UID=${connectionConfig.user};` +\n `PWD=${connectionConfig.password};` +\n connectionStringExtension\n );\n }\n\n // Runs the query on the specified connection, providing the bindings\n async _query(connection: Connection, obj: any) {\n const queryObject = this.normalizeQueryObject(obj);\n const method = this.determineQueryMethod(queryObject);\n queryObject.sqlMethod = method;\n\n // Special handling for UPDATE with returning clause\n if (queryObject._ibmiUpdateReturning) {\n return await this.executeUpdateReturning(connection, queryObject);\n }\n\n // Sequential multi-row insert execution path\n if (queryObject._ibmiSequentialInsert) {\n return await this.executeSequentialInsert(connection, queryObject);\n }\n\n // DELETE ... RETURNING emulation\n if (queryObject._ibmiDeleteReturning) {\n return await this.executeDeleteReturning(connection, queryObject);\n }\n\n // Debug migration queries (only if DEBUG environment variable is set)\n if (\n process.env.DEBUG === \"true\" &&\n queryObject.sql &&\n (queryObject.sql.toLowerCase().includes(\"create table\") ||\n queryObject.sql.toLowerCase().includes(\"knex_migrations\"))\n ) {\n this.printDebug(\n `Executing ${method} query: ${queryObject.sql.substring(0, 200)}...`\n );\n if (queryObject.bindings?.length) {\n this.printDebug(\n `Bindings: ${this.safeStringify(queryObject.bindings)}`\n );\n }\n }\n\n try {\n const startTime = Date.now();\n if (this.isSelectMethod(method)) {\n await this.executeSelectQuery(connection, queryObject);\n } else {\n await this.executeStatementQuery(connection, queryObject);\n }\n const endTime = Date.now();\n\n if (\n process.env.DEBUG === \"true\" &&\n queryObject.sql &&\n (queryObject.sql.toLowerCase().includes(\"create table\") ||\n queryObject.sql.toLowerCase().includes(\"knex_migrations\"))\n ) {\n this.printDebug(`${method} completed in ${endTime - startTime}ms`);\n }\n\n this.printDebug(`Query completed: ${method} (${endTime - startTime}ms)`);\n return queryObject;\n } catch (error: any) {\n // Enhanced error handling for connection issues\n const wrappedError = this.wrapError(error, method, queryObject);\n\n if (this.isConnectionError(error)) {\n this.printError(\n `Connection error during ${method} query: ${error.message}`\n );\n\n // For critical migration operations, retry once before failing\n if (this.shouldRetryQuery(queryObject, method)) {\n return await this.retryQuery(connection, queryObject, method);\n }\n\n throw wrappedError;\n }\n throw wrappedError;\n }\n }\n\n /**\n * Execute UPDATE with returning clause using transaction + SELECT approach\n * Since IBM i DB2 doesn't support FINAL TABLE with UPDATE, we:\n * 1. Execute the UPDATE statement\n * 2. Execute a SELECT to get the updated values using the same WHERE clause\n */\n private async executeUpdateReturning(\n connection: Connection,\n obj: any\n ): Promise<any> {\n const { _ibmiUpdateReturning } = obj;\n const { updateSql, selectColumns, whereClause, tableName } =\n _ibmiUpdateReturning;\n\n this.printDebug(\n \"Executing UPDATE with returning using transaction approach\"\n );\n\n try {\n // Execute the UPDATE statement\n const updateObj = {\n sql: updateSql,\n bindings: obj.bindings,\n sqlMethod: \"update\",\n };\n\n await this.executeStatementQuery(connection, updateObj);\n\n // Build and execute SELECT to get the updated values\n const selectSql = whereClause\n ? `select ${selectColumns} from ${tableName} ${whereClause}`\n : `select ${selectColumns} from ${tableName}`;\n\n // Extract only WHERE clause bindings for SELECT\n // UPDATE bindings format: [set_values..., where_values...]\n // We need to figure out how many bindings are for SET vs WHERE\n const updateSqlParts = updateSql.split(\" where \");\n const setClausePart = updateSqlParts[0];\n const setBindingCount = (setClausePart.match(/\\?/g) || []).length;\n const whereBindings = obj.bindings\n ? obj.bindings.slice(setBindingCount)\n : [];\n\n const selectObj = {\n sql: selectSql,\n bindings: whereBindings,\n sqlMethod: \"select\",\n response: undefined,\n };\n\n await this.executeSelectQuery(connection, selectObj);\n\n // Return the SELECT results as the final response\n obj.response = selectObj.response;\n obj.sqlMethod = \"update\";\n obj.select = true; // Mark as SELECT behavior to return rows instead of rowCount\n return obj;\n } catch (error: any) {\n this.printError(`UPDATE with returning failed: ${error.message}`);\n throw this.wrapError(error, \"update_returning\", obj);\n }\n }\n\n private async executeSequentialInsert(\n connection: Connection,\n obj: any\n ): Promise<any> {\n const meta = obj._ibmiSequentialInsert;\n const { rows, columns, tableName, returning, identityOnly } = meta;\n this.printDebug(\"Executing sequential multi-row insert\");\n const insertedRows: any[] = [];\n\n const transactional =\n (this.config as any)?.ibmi?.sequentialInsertTransactional === true;\n let beganTx = false;\n if (transactional) {\n try {\n await connection.query(\"BEGIN\");\n beganTx = true;\n } catch (e) {\n this.printWarn(\n \"Could not begin transaction for sequential insert; proceeding without\"\n );\n }\n }\n\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i];\n const colList = columns.join(\", \");\n const placeholders = columns.map(() => \"?\").join(\", \");\n const singleValues = columns.map((c: string) => row[c]);\n const baseInsert = `insert into ${tableName} (${colList}) values (${placeholders})`;\n const selectCols = returning\n ? this.queryCompiler({} as any).formatter.columnize(returning)\n : \"IDENTITY_VAL_LOCAL()\";\n const wrapped = `select ${selectCols} from FINAL TABLE(${baseInsert})`;\n const singleObj = {\n sql: wrapped,\n bindings: singleValues,\n sqlMethod: \"insert\",\n response: undefined,\n };\n await this.executeStatementQuery(connection, singleObj);\n const resp = (singleObj as any).response?.rows;\n if (resp) insertedRows.push(...resp);\n }\n\n if (transactional && beganTx) {\n try {\n await connection.query(\"COMMIT\");\n } catch (commitErr) {\n this.printError(\n \"Commit failed for sequential insert, attempting rollback: \" +\n (commitErr as any)?.message\n );\n try {\n await connection.query(\"ROLLBACK\");\n } catch {\n /* ignore */\n }\n throw commitErr;\n }\n }\n\n obj.response = { rows: insertedRows, rowCount: insertedRows.length };\n obj.sqlMethod = \"insert\";\n obj.select = true;\n return obj;\n }\n\n private async executeDeleteReturning(\n connection: Connection,\n obj: any\n ): Promise<any> {\n const meta = obj._ibmiDeleteReturning;\n const { deleteSql, selectColumns, whereClause, tableName } = meta;\n this.printDebug(\"Executing DELETE with returning emulation\");\n try {\n // SELECT rows first\n const selectSql = whereClause\n ? `select ${selectColumns} from ${tableName} ${whereClause}`\n : `select ${selectColumns} from ${tableName}`;\n const selectObj = {\n sql: selectSql,\n bindings: obj.bindings,\n sqlMethod: \"select\",\n response: undefined,\n };\n await this.executeSelectQuery(connection, selectObj);\n const rowsToReturn = (selectObj as any).response?.rows || [];\n // Execute DELETE\n const deleteObj = {\n sql: deleteSql,\n bindings: obj.bindings,\n sqlMethod: \"del\",\n response: undefined,\n };\n await this.executeStatementQuery(connection, deleteObj);\n obj.response = { rows: rowsToReturn, rowCount: rowsToReturn.length };\n obj.sqlMethod = \"del\";\n obj.select = true;\n return obj;\n } catch (error: any) {\n this.printError(`DELETE with returning failed: ${error.message}`);\n throw this.wrapError(error, \"delete_returning\", obj);\n }\n }\n\n private normalizeQueryObject(obj: any): any {\n if (!obj || typeof obj === \"string\") {\n return { sql: obj };\n }\n return obj;\n }\n\n private determineQueryMethod(obj: any): string {\n return (\n obj.hasOwnProperty(\"method\") && obj.method !== \"raw\"\n ? obj.method\n : obj.sql.split(\" \")[0]\n ).toLowerCase();\n }\n\n private isSelectMethod(method: string): boolean {\n return method === \"select\" || method === \"first\" || method === \"pluck\";\n }\n\n private async executeSelectQuery(\n connection: Connection,\n obj: { sql: string; bindings: any[]; response: unknown }\n ): Promise<void> {\n const rows: Record<any, any>[] = await connection.query(\n obj.sql,\n obj.bindings\n );\n if (rows) {\n obj.response = { rows, rowCount: rows.length };\n }\n }\n\n private async executeStatementQuery(\n connection: Connection,\n obj: any\n ): Promise<void> {\n let statement: any;\n let usedCache = false;\n const cacheEnabled =\n (this.config as any)?.ibmi?.preparedStatementCache === true;\n\n try {\n // Try to use cached statement if enabled\n if (cacheEnabled) {\n let cache = this.statementCaches.get(connection);\n if (!cache) {\n const cacheSize =\n (this.config as any)?.ibmi?.preparedStatementCacheSize || 100;\n cache = new StatementCache(cacheSize);\n this.statementCaches.set(connection, cache);\n }\n\n statement = cache.get(obj.sql);\n if (statement) {\n usedCache = true;\n this.printDebug(\n `Using cached statement for: ${obj.sql.substring(0, 50)}...`\n );\n } else {\n // Create and cache new statement\n statement = await connection.createStatement();\n await statement.prepare(obj.sql);\n cache.set(obj.sql, statement);\n this.printDebug(`Cached new statement (cache size: ${cache.size()})`);\n }\n } else {\n // No caching - create statement normally\n statement = await connection.createStatement();\n await statement.prepare(obj.sql);\n }\n\n if (obj.bindings) {\n await statement.bind(obj.bindings);\n }\n\n const result = await statement.execute();\n this.printDebug(String(result));\n\n obj.response = this.formatStatementResponse(result);\n } catch (err: any) {\n // Special handling for UPDATE/DELETE queries that affect 0 rows\n // Some ODBC drivers signal 0-row DML via empty error/\"no data\" (SQLSTATE 02000)\n const sql = (obj.sql || \"\").toLowerCase();\n const isDml =\n obj.sqlMethod === SqlMethod.UPDATE ||\n sql.includes(\" update \") ||\n sql.startsWith(\"update\") ||\n obj.sqlMethod === SqlMethod.DELETE ||\n sql.includes(\" delete \") ||\n sql.startsWith(\"delete\");\n\n const odbcErrors = err?.odbcErrors;\n const isEmptyOdbcError =\n Array.isArray(odbcErrors) && odbcErrors.length === 0;\n const hasNoDataState = Array.isArray(odbcErrors)\n ? odbcErrors.some(\n (e: any) =>\n String(e?.state || e?.SQLSTATE || \"\").toUpperCase() === \"02000\"\n )\n : false;\n\n if (\n isDml &&\n (isEmptyOdbcError || hasNoDataState || this.isNoDataError(err))\n ) {\n this.printWarn(\n `ODBC signaled no-data for ${sql.includes(\"update\") ? \"UPDATE\" : \"DELETE\"}; treating as 0 rows affected`\n );\n obj.response = { rows: [], rowCount: 0 };\n return;\n }\n\n this.printError(this.safeStringify(err));\n throw err;\n } finally {\n // Only close statement if it's not cached\n if (!usedCache && statement && typeof statement.close === \"function\") {\n try {\n await statement.close();\n } catch (closeErr) {\n // Ignore close errors, log in debug mode only\n this.printDebug(\n `Error closing statement: ${this.safeStringify(closeErr, 2)}`\n );\n }\n }\n }\n }\n\n private isNoDataError(error: any): boolean {\n if (!error) return false;\n const msg = String(error?.message || error || \"\").toLowerCase();\n // Match common indicators of 0-row DML reported as error\n return (\n msg.includes(\"02000\") ||\n msg.includes(\"no data\") ||\n msg.includes(\"no rows\") ||\n msg.includes(\"0 rows\")\n );\n }\n\n /**\n * Format statement response from ODBC driver\n * Handles special case for IDENTITY_VAL_LOCAL() function\n */\n private formatStatementResponse(result: any): {\n rows: any;\n rowCount: number;\n } {\n const isIdentityQuery = result.statement?.includes(\"IDENTITY_VAL_LOCAL()\");\n\n if (isIdentityQuery && result.columns?.length > 0) {\n return {\n rows: result.map(\n (row: { [x: string]: any }) => row[result.columns[0].name]\n ),\n rowCount: result.count,\n };\n }\n\n // Normalize result for DML (UPDATE/DELETE/INSERT) to surface rowCount consistently\n const rowCount = typeof result?.count === \"number\" ? result.count : 0;\n return {\n rows: result,\n rowCount,\n };\n }\n\n async _stream(\n connection: Connection,\n obj: { sql: string; bindings: any[] },\n stream: any,\n options: {\n fetchSize?: number;\n }\n ) {\n if (!obj.sql) throw new Error(\"A query is required to stream results\");\n\n const optimizedFetchSize =\n options?.fetchSize || this.calculateOptimalFetchSize(obj.sql);\n\n return new Promise((resolve, reject) => {\n let isResolved = false;\n\n const cleanup = () => {\n if (!isResolved) {\n isResolved = true;\n }\n };\n\n stream.on(\"error\", (err: any) => {\n cleanup();\n reject(err);\n });\n\n stream.on(\"end\", () => {\n cleanup();\n resolve(undefined);\n });\n\n connection.query(\n obj.sql,\n obj.bindings,\n {\n cursor: true,\n fetchSize: optimizedFetchSize,\n },\n (error, cursor) => {\n if (error) {\n this.printError(this.safeStringify(error, 2));\n cleanup();\n reject(error);\n return;\n }\n\n const readableStream = this._createCursorStream(cursor);\n readableStream.on(\"error\", (err) => {\n cleanup();\n reject(err);\n });\n readableStream.pipe(stream);\n }\n );\n });\n }\n\n private calculateOptimalFetchSize(sql: string): number {\n const sqlLower = sql.toLowerCase();\n const hasJoins = /\\s+join\\s+/i.test(sql);\n const hasAggregates = /\\s+(count|sum|avg|max|min)\\s*\\(/i.test(sql);\n const hasOrderBy = /\\s+order\\s+by\\s+/i.test(sql);\n const hasGroupBy = /\\s+group\\s+by\\s+/i.test(sql);\n\n // For complex analytical queries, use larger fetch sizes\n if (hasJoins || hasAggregates || hasOrderBy || hasGroupBy) {\n return 500;\n }\n\n // For simple queries, use moderate fetch size\n return 100;\n }\n\n private _createCursorStream(cursor: any): Readable {\n const parentThis = this;\n let isClosed = false;\n\n return new Readable({\n objectMode: true,\n read() {\n if (isClosed) return;\n\n cursor.fetch((error: unknown, result: unknown) => {\n if (error) {\n parentThis.printError(parentThis.safeStringify(error, 2));\n isClosed = true;\n this.emit(\"error\", error);\n return;\n }\n\n if (!cursor.noData) {\n this.push(result);\n } else {\n isClosed = true;\n cursor.close((closeError: unknown) => {\n if (closeError) {\n parentThis.printError(parentThis.safeStringify(closeError, 2));\n }\n if (result) {\n this.push(result);\n }\n this.push(null); // End the stream\n });\n }\n });\n },\n destroy(err, callback) {\n if (!isClosed) {\n isClosed = true;\n cursor.close((closeError: unknown) => {\n if (closeError) {\n parentThis.printDebug(\n \"Error closing cursor during destroy: \" +\n parentThis.safeStringify(closeError)\n );\n }\n callback(err);\n });\n } else {\n callback(err);\n }\n },\n });\n }\n\n transaction(container: any, config: any, outerTx: any): Knex.Transaction {\n return new (Transaction as any)(this, container, config, outerTx);\n }\n\n schemaCompiler(tableBuilder: any) {\n return new (SchemaCompiler as any)(this, tableBuilder);\n }\n\n tableCompiler(tableBuilder: any) {\n return new (TableCompiler as any)(this, tableBuilder);\n }\n\n columnCompiler(tableCompiler: any, columnCompiler: any) {\n return new (ColumnCompiler as any)(this, tableCompiler, columnCompiler);\n }\n\n queryCompiler(builder: Knex.QueryBuilder, bindings?: any[]) {\n return new (QueryCompiler as any)(this, builder, bindings);\n }\n\n // Create IBM i-specific migration runner that bypasses Knex's problematic locking system\n createMigrationRunner(\n config?: Partial<\n import(\"./migrations/ibmi-migration-runner\").IBMiMigrationConfig\n >\n ) {\n // Pass the knex instance from the client context\n const knexInstance = (this as any).context || (this as any);\n return createIBMiMigrationRunner(knexInstance, config);\n }\n\n processResponse(obj: QueryObject | null, runner: any): any {\n if (obj === null) return null;\n\n const { response } = obj;\n\n // If there's a custom output function, use it directly without validation\n // This allows custom queries like hasTable to handle their own response format\n if (obj.output) {\n try {\n const result = obj.output(runner, response);\n return result;\n } catch (error: any) {\n // Enhanced error handling for custom output functions\n const wrappedError = this.wrapError(error, \"custom_output\", obj);\n this.printError(\n `Custom output function failed: ${wrappedError.message}`\n );\n if (this.isConnectionError(error)) {\n throw new Error(\n \"Connection closed during query processing - consider using migrations.disableTransactions: true for DDL operations\"\n );\n }\n throw wrappedError;\n }\n }\n\n // Only validate for standard SQL methods that expect rows structure\n const validationResult = this.validateResponse(obj);\n if (validationResult !== null) return validationResult;\n\n return this.processSqlMethod(obj);\n }\n\n private validateResponse(obj: QueryObject): any {\n if (!obj.response) {\n this.printDebug(\"response undefined \" + this.safeStringify(obj));\n return null;\n }\n\n // For non-select methods, it's fine if rows is empty/undefined as long as rowCount is set.\n // Do not short-circuit here; allow processSqlMethod to normalize the return value.\n\n if (!obj.response.rows) {\n this.printError(\"rows undefined \" + this.safeStringify(obj));\n return null;\n }\n\n return null;\n }\n\n private wrapError(error: any, method: string, queryObject: any): Error {\n const context = {\n method,\n sql: queryObject.sql\n ? queryObject.sql.substring(0, 100) + \"...\"\n : \"unknown\",\n timestamp: new Date().toISOString(),\n };\n\n const contextStr = this.safeStringify(context);\n\n if (this.isConnectionError(error)) {\n return new Error(\n `IBM i DB2 connection error during ${method}: ${error.message} | Context: ${contextStr}`\n );\n }\n\n if (this.isTimeoutError(error)) {\n return new Error(\n `IBM i DB2 timeout during ${method}: ${error.message} | Context: ${contextStr}`\n );\n }\n\n if (this.isSQLError(error)) {\n return new Error(\n `IBM i DB2 SQL error during ${method}: ${error.message} | Context: ${contextStr}`\n );\n }\n\n // Generic error with context\n return new Error(\n `IBM i DB2 error during ${method}: ${error.message} | Context: ${contextStr}`\n );\n }\n\n private shouldRetryQuery(queryObject: any, method: string): boolean {\n return (\n queryObject.sql?.toLowerCase().includes(\"systables\") ||\n queryObject.sql?.toLowerCase().includes(\"knex_migrations\")\n );\n }\n\n private async retryQuery(\n connection: Connection,\n queryObject: any,\n method: string\n ): Promise<any> {\n this.printDebug(`Retrying ${method} query due to connection error...`);\n try {\n // Wait a moment and retry the query\n await new Promise((resolve) => setTimeout(resolve, 1000));\n if (this.isSelectMethod(method)) {\n await this.executeSelectQuery(connection, queryObject);\n } else {\n await this.executeStatementQuery(connection, queryObject);\n }\n return queryObject;\n } catch (retryError: any) {\n this.printError(`Retry failed: ${retryError.message}`);\n // If retry fails, return empty result to prevent migration corruption\n queryObject.response = { rows: [], rowCount: 0 };\n return queryObject;\n }\n }\n\n /**\n * Extract SQLSTATE from ODBC error if available\n */\n private getSQLState(error: any): string | null {\n // Check for ODBC error format with state property\n if (error?.odbcErrors && Array.isArray(error.odbcErrors)) {\n for (const odbcErr of error.odbcErrors) {\n const state = odbcErr?.state || odbcErr?.SQLSTATE;\n if (state) return String(state).toUpperCase();\n }\n }\n return null;\n }\n\n private isConnectionError(error: any): boolean {\n const sqlState = this.getSQLState(error);\n\n // ODBC SQLSTATE codes for connection errors\n // 08xxx = Connection exception\n if (sqlState) {\n return (\n sqlState.startsWith(\"08\") || // 08001, 08003, 08007, 08S01, etc.\n sqlState === \"40003\" // Transaction rollback due to connection\n );\n }\n\n // Fallback to message parsing\n const errorMessage = (\n error.message ||\n error.toString ||\n error\n ).toLowerCase();\n return (\n errorMessage.includes(\"connection\") &&\n (errorMessage.includes(\"closed\") ||\n errorMessage.includes(\"invalid\") ||\n errorMessage.includes(\"terminated\") ||\n errorMessage.includes(\"not connected\"))\n );\n }\n\n private isTimeoutError(error: any): boolean {\n const sqlState = this.getSQLState(error);\n\n // ODBC SQLSTATE codes for timeout errors\n if (sqlState) {\n return (\n sqlState === \"HYT00\" || // Timeout expired\n sqlState === \"HYT01\" // Connection timeout expired\n );\n }\n\n // Fallback to message parsing\n const errorMessage = (\n error.message ||\n error.toString ||\n error\n ).toLowerCase();\n return (\n errorMessage.includes(\"timeout\") || errorMessage.includes(\"timed out\")\n );\n }\n\n private isSQLError(error: any): boolean {\n const sqlState = this.getSQLState(error);\n\n // ODBC SQLSTATE codes for SQL errors\n if (sqlState) {\n return (\n sqlState.startsWith(\"42\") || // Syntax error or access violation\n sqlState.startsWith(\"22\") || // Data exception\n sqlState.startsWith(\"23\") || // Integrity constraint violation\n sqlState.startsWith(\"21\") // Cardinality violation\n );\n }\n\n // Fallback to message parsing\n const errorMessage = (\n error.message ||\n error.toString ||\n error\n ).toLowerCase();\n return (\n errorMessage.includes(\"sql\") ||\n errorMessage.includes(\"syntax\") ||\n errorMessage.includes(\"table\") ||\n errorMessage.includes(\"column\")\n );\n }\n\n private processSqlMethod(obj: QueryObject): any {\n const { rows, rowCount } = obj.response!;\n\n switch (obj.sqlMethod) {\n case SqlMethod.SELECT:\n return rows;\n case SqlMethod.PLUCK:\n return rows.map(obj.pluck!);\n case SqlMethod.FIRST:\n return rows[0];\n case SqlMethod.INSERT:\n return rows;\n case SqlMethod.DELETE:\n case SqlMethod.DELETE_ALT:\n case SqlMethod.UPDATE:\n // Align with MySQL: return affected rows as a number for DML\n return obj.select ? rows : (rowCount ?? 0);\n case SqlMethod.COUNTER:\n return rowCount;\n default:\n return rows;\n }\n }\n}\n\ninterface DB2PoolConfig {\n min?: number;\n max?: number;\n acquireConnectionTimeout?: number;\n}\n\ninterface DB2ConnectionParams {\n // General Properties\n DSN?: string;\n SIGNON?: 0 | 1 | 2 | 3 | 4;\n SSL?: 0 | 1;\n\n // Server Properties\n CMT?: 0 | 1 | 2 | 3 | 4;\n CONNTYPE?: 0 | 1 | 2;\n DATABASE?: string;\n DBQ?: string;\n MAXDECPREC?: 31 | 63;\n MAXDECSCALE?: number;\n MINDIVSCALE?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;\n NAM?: 0 | 1;\n\n // Data Types Properties\n DFT?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;\n DSP?: 0 | 1 | 2 | 3 | 4;\n DEC?: 0 | 1;\n DECFLOATERROROPTION?: 0 | 1;\n DECFLOATROUNDMODE?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n MAPDECIMALFLOATDESCRIBE?: 1 | 3;\n TFT?: 0 | 1 | 2 | 3 | 4;\n TSP?: 0 | 1 | 2 | 3;\n TSFT?: 0 | 1;\n XMLCURIMPPARSE?: 0 | 1;\n XMLDECLARATION?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;\n\n // Package Properties\n DFTPKGLIB?: string;\n PKG?: string;\n XDYNAMIC?: 0 | 1;\n\n // Performance Properties\n BLOCKFETCH?: 0 | 1;\n BLOCKSIZE?: number;\n COMPRESSION?: 0 | 1;\n CONCURRENCY?: 0 | 1;\n CURSORSENSITIVITY?: 0 | 1 | 2;\n EXTCOLINFO?: 0 | 1;\n LAZYCLOSE?: 0 | 1;\n MAXFIELDLEN?: number;\n PREFETCH?: 0 | 1;\n QRYSTGLMT?: number | \"*NOMAX\";\n QUERYOPTIMIZEGOAL?: 0 | 1 | 2;\n QUERYTIMEOUT?: 0 | 1;\n\n // Language Properties\n LANGUAGEID?:\n | \"AFR\"\n | \"ARA\"\n | \"BEL\"\n | \"BGR\"\n | \"CAT\"\n | \"CHS\"\n | \"CHT\"\n | \"CSY\"\n | \"DAN\"\n | \"DES\"\n | \"DEU\"\n | \"ELL\"\n | \"ENA\"\n | \"ENB\"\n | \"ENG\"\n | \"ENP\"\n | \"ENU\"\n | \"ESP\"\n | \"EST\"\n | \"FAR\"\n | \"FIN\"\n | \"FRA\"\n | \"FRB\"\n | \"FRC\"\n | \"FRS\"\n | \"GAE\"\n | \"HEB\"\n | \"HRV\"\n | \"HUN\"\n | \"ISL\"\n | \"ITA\"\n | \"ITS\"\n | \"JPN\"\n | \"KOR\"\n | \"LAO\"\n | \"LVA\"\n | \"LTU\"\n | \"MKD\"\n | \"NLB\"\n | \"NLD\"\n | \"NON\"\n | \"NOR\"\n | \"PLK\"\n | \"PTB\"\n | \"PTG\"\n | \"RMS\"\n | \"ROM\"\n | \"RUS\"\n | \"SKY\"\n | \"SLO\"\n | \"SQI\"\n | \"SRB\"\n | \"SRL\"\n | \"SVE\"\n | \"THA\"\n | \"TRK\"\n | \"UKR\"\n | \"URD\"\n | \"VIE\";\n SORTTABLE?: string;\n SORTTYPE?: 0 | 1 | 2 | 3;\n SORTWEIGHT?: 0 | 1;\n\n // Catalog Properties\n CATALOGOPTIONS?: number;\n LIBVIEW?: 0 | 1 | 2;\n REMARKS?: 0 | 1;\n SEARCHPATTERN?: 0 | 1;\n\n // Conversion Properties\n ALLOWUNSCHAR?: 0 | 1;\n CCSID?: number;\n GRAPHIC?: 0 | 1 | 2 | 3;\n HEXPARSEROPT?: 0 | 1;\n TRANSLATE?: 0 | 1;\n TRIMCHAR?: 0 | 1;\n UNICODESQL?: 0 | 1;\n XLATEDLL?: string;\n XLATEOPT?: number;\n\n // Diagnostic Properties\n QAQQINILIB?: string;\n SQDIAGCODE?: string;\n TRACE?: number;\n\n // Other Properties\n ALWAYSCALCLEN?: 0 | 1;\n ALLOWPROCCALLS?: 0 | 1;\n CONCURRENTACCESSRESOLUTION?: 0 | 1 | 2 | 3;\n DB2SQLSTATES?: 0 | 1;\n DATETIMETOCHAR?: number;\n DBCSNoTruncError?: 0 | 1;\n DEBUG?: number;\n KEEPALIVE?: 0 | 1 | 2;\n LOGINTIMEOUT?: number;\n TIMEOUT?: number;\n TRUEAUTOCOMMIT?: 0 | 1;\n NEWPWD?: string;\n XALCS?: 0 | 1;\n XALOCKTIMEOUT?: number;\n XATXNTIMEOUT?: number;\n}\n\ninterface DB2ConnectionConfig {\n database: string;\n host: string;\n port: 8471 | 9471 | number;\n user: string;\n password: string;\n driver: \"IBM i Access ODBC Driver\" | string;\n connectionStringParams?: DB2ConnectionParams;\n}\n\nexport interface DB2Config extends Knex.Config {\n client: any;\n connection: DB2ConnectionConfig;\n pool?: DB2PoolConfig;\n ibmi?: {\n multiRowInsert?: \"auto\" | \"sequential\" | \"disabled\";\n sequentialInsertTransactional?: boolean;\n preparedStatementCache?: boolean; // Enable per-connection statement caching\n preparedStatementCacheSize?: number; // Max cached statements per connection (default: 100)\n readUncommitted?: boolean; // Append WITH UR to SELECT queries\n };\n}\n\nexport const DB2Dialect = DB2Client;\nexport { IBMiMigrationRunner, createIBMiMigrationRunner };\nexport default DB2Client;\n","import SchemaCompiler from \"knex/lib/schema/compiler.js\";\n\nclass IBMiSchemaCompiler extends SchemaCompiler {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n hasTable(tableName: string) {\n const upperName = String(tableName).toUpperCase();\n\n // Extract schema and table name if qualified\n let schemaName: string | null = null;\n let actualTableName = upperName;\n\n if (upperName.includes(\".\")) {\n const parts = upperName.split(\".\");\n schemaName = parts[0];\n actualTableName = parts[1];\n }\n\n // Use schema from the builder if available\n const builderSchema = (this.builder as any)._schema;\n if (builderSchema) {\n schemaName = builderSchema.toUpperCase();\n }\n\n let sql: string;\n let bindings: any[];\n\n if (schemaName) {\n sql = `select count(*) as table_count from QSYS2.SYSTABLES where UPPER(TABLE_NAME) = ? AND UPPER(TABLE_SCHEMA) = ?`;\n bindings = [actualTableName, schemaName];\n } else {\n sql = `select count(*) as table_count from QSYS2.SYSTABLES where UPPER(TABLE_NAME) = ?`;\n bindings = [actualTableName];\n }\n\n this.pushQuery({\n sql,\n bindings,\n output: (runner: any, resp: any) => {\n // Handle the response from the ODBC query\n // The first parameter is the runner, the second is the actual response\n if (!resp) {\n return false;\n }\n\n // Check if response is an array with results\n if (Array.isArray(resp) && resp.length > 0) {\n const firstRow = resp[0];\n if (firstRow && typeof firstRow === \"object\") {\n // Look for table_count or any count field\n const count =\n firstRow.table_count ||\n firstRow.TABLE_COUNT ||\n firstRow.count ||\n firstRow.COUNT ||\n 0;\n return count > 0;\n }\n }\n\n // Handle ODBC response format with numeric keys\n if (typeof resp === \"object\" && resp !== null) {\n // Check for ODBC array-like response with numeric indices\n const keys = Object.keys(resp);\n for (const key of keys) {\n if (!isNaN(parseInt(key))) {\n const row = resp[key];\n if (row && typeof row === \"object\") {\n const count =\n row.table_count ||\n row.TABLE_COUNT ||\n row.count ||\n row.COUNT ||\n 0;\n return count > 0;\n }\n }\n }\n\n // Handle response with rows property\n if (resp.rows && Array.isArray(resp.rows) && resp.rows.length > 0) {\n const firstRow = resp.rows[0];\n if (firstRow && typeof firstRow === \"object\") {\n const count =\n firstRow.table_count ||\n firstRow.TABLE_COUNT ||\n firstRow.count ||\n firstRow.COUNT ||\n 0;\n return count > 0;\n }\n }\n }\n\n return false;\n },\n });\n }\n\n toSQL() {\n const sequence = (this.builder as any)._sequence as any[];\n\n for (let i = 0, l = sequence.length; i < l; i++) {\n const query = sequence[i];\n this[query.method].apply(this, query.args);\n }\n\n return this.sequence;\n }\n}\n\nfunction prefixedTableName(prefix: any, table: any) {\n return prefix ? `${prefix}.${table}` : table;\n}\n\nexport default IBMiSchemaCompiler;\n","import TableCompiler from \"knex/lib/schema/tablecompiler.js\";\nimport { Connection } from \"odbc\";\n\nclass IBMiTableCompiler extends TableCompiler {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n createQuery(columns: { sql: any[] }, ifNot: any, like: any) {\n // Note: IBM i DB2 does not support IF NOT EXISTS syntax directly\n // The ifNot parameter should be handled by checking hasTable first\n if (ifNot && this.client?.logger?.warn) {\n this.client.logger.warn(\n 'IBM i DB2: IF NOT EXISTS is not natively supported. Use hasTable() check instead.'\n );\n }\n\n let createStatement = \"\";\n\n if (like) {\n // IBM i DB2 syntax for creating table from existing structure\n createStatement = `create table ${this.tableName()} as (select * from ${this.tableNameLike()}) with no data`;\n } else {\n createStatement =\n \"create table \" +\n this.tableName() +\n (this._formatting ? \" (\\n \" : \" (\") +\n columns.sql.join(this._formatting ? \",\\n \" : \", \") +\n this._addChecks() +\n \")\";\n }\n\n this.pushQuery(createStatement);\n\n if (this.single.comment) {\n this.comment(this.single.comment);\n }\n\n if (like) {\n this.addColumns(columns, this.addColumnsPrefix);\n }\n }\n\n dropUnique(columns: string[], indexName: any) {\n indexName = indexName\n ? this.formatter.wrap(indexName)\n : this._indexCommand(\"unique\", this.tableNameRaw, columns);\n\n this.pushQuery(`drop index ${indexName}`);\n }\n\n unique(\n columns: string[],\n indexName:\n | string\n | { indexName?: string; deferrable?: string; predicate?: any }\n ) {\n let deferrable: string = \"\";\n let predicate: any;\n let finalIndexName: string | undefined;\n\n if (typeof indexName === \"object\" && indexName !== null) {\n deferrable = indexName.deferrable || \"\";\n predicate = indexName.predicate;\n finalIndexName = indexName.indexName;\n } else {\n finalIndexName = indexName;\n }\n\n if (deferrable && deferrable !== \"not deferrable\") {\n this.client.logger.warn?.(\n `IBMi: unique index \\`${finalIndexName}\\` will not be deferrable ${deferrable}.`\n );\n }\n\n const wrappedIndexName = finalIndexName\n ? this.formatter.wrap(finalIndexName)\n : this._indexCommand(\"unique\", this.tableNameRaw, columns);\n columns = this.formatter.columnize(columns);\n\n const predicateQuery = predicate\n ? \" \" + this.client.queryCompiler(predicate).where()\n : \"\";\n\n this.pushQuery(\n `create unique index ${wrappedIndexName} on ${this.tableName()} (${columns})${predicateQuery}`\n );\n }\n\n // All of the columns to \"add\" for the query\n addColumns(columns: any, prefix: any) {\n prefix = prefix || this.addColumnsPrefix;\n\n if (columns.sql.length > 0) {\n const columnSql = columns.sql.map((column) => {\n return prefix + column;\n });\n this.pushQuery({\n sql:\n (this.lowerCase ? \"alter table \" : \"ALTER TABLE \") +\n this.tableName() +\n \" \" +\n columnSql.join(\" \"),\n bindings: columns.bindings,\n });\n }\n }\n\n async commit(connection: Connection) {\n return await connection.commit();\n }\n}\n\nexport default IBMiTableCompiler;\n","import ColumnCompiler from \"knex/lib/schema/columncompiler.js\";\n\nclass IBMiColumnCompiler extends ColumnCompiler {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n increments(options = { primaryKey: true }) {\n return (\n \"int not null generated always as identity (start with 1, increment by 1)\" +\n (this.tableCompiler._canBeAddPrimaryKey(options) ? \" primary key\" : \"\")\n );\n }\n\n // Add more IBM i DB2 specific column types for better support\n bigIncrements(options = { primaryKey: true }) {\n return (\n \"bigint not null generated always as identity (start with 1, increment by 1)\" +\n (this.tableCompiler._canBeAddPrimaryKey(options) ? \" primary key\" : \"\")\n );\n }\n\n varchar(length?: number) {\n return length ? `varchar(${length})` : 'varchar(255)';\n }\n\n char(length?: number) {\n return length ? `char(${length})` : 'char(1)';\n }\n\n text() {\n // IBM i DB2 uses CLOB for large text\n return 'clob(1M)';\n }\n\n mediumtext() {\n return 'clob(16M)';\n }\n\n longtext() {\n return 'clob(2G)';\n }\n\n binary(length?: number) {\n return length ? `binary(${length})` : 'binary(1)';\n }\n\n varbinary(length?: number) {\n return length ? `varbinary(${length})` : 'varbinary(255)';\n }\n\n // IBM i DB2 decimal with precision/scale\n decimal(precision?: number, scale?: number) {\n if (precision && scale) {\n return `decimal(${precision}, ${scale})`;\n } else if (precision) {\n return `decimal(${precision})`;\n }\n return 'decimal(10, 2)';\n }\n\n // IBM i DB2 timestamp\n // Note: IBM i DB2 does not support TIMESTAMP WITH TIME ZONE\n timestamp(options?: any) {\n if (options?.useTz && this.client?.logger?.warn) {\n this.client.logger.warn(\n 'IBM i DB2 does not support TIMESTAMP WITH TIME ZONE. Using plain TIMESTAMP instead.'\n );\n }\n return 'timestamp';\n }\n\n datetime(options?: any) {\n return this.timestamp(options);\n }\n\n // IBM i DB2 date and time types\n date() {\n return 'date';\n }\n\n time() {\n return 'time';\n }\n\n // JSON support (IBM i 7.3+)\n // Note: CHECK constraints with column references are not supported in this context\n // Users should add validation constraints separately if needed\n json() {\n return 'clob(16M)';\n }\n\n jsonb() {\n // IBM i doesn't have native JSONB, use CLOB\n return 'clob(16M)';\n }\n\n // UUID support using CHAR(36)\n uuid() {\n return 'char(36)';\n }\n}\n\nexport default IBMiColumnCompiler;\n","import Transaction from \"knex/lib/execution/transaction.js\";\n\nclass IBMiTransaction extends Transaction {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n begin(connection: any): any {\n try {\n return connection.beginTransaction();\n } catch (error: any) {\n if (this.isConnectionClosed(error)) {\n console.warn(\n \"IBM i DB2: Connection closed during transaction begin, DDL operations may have caused implicit commit\"\n );\n throw new Error(\n \"Connection closed during transaction begin - consider using migrations.disableTransactions: true\"\n );\n }\n throw error;\n }\n }\n\n rollback(connection: any): any {\n try {\n return connection.rollback();\n } catch (error: any) {\n // Treat rollback on a closed connection as success to avoid hangs\n console.warn(\n \"IBM i DB2: Rollback encountered an error (likely closed connection):\",\n error?.message || error\n );\n return Promise.resolve();\n }\n }\n\n commit(connection: any): any {\n try {\n return connection.commit();\n } catch (error: any) {\n if (this.isConnectionClosed(error)) {\n console.warn(\n \"IBM i DB2: Connection closed during commit - DDL operations cause implicit commits\"\n );\n // Re-throw so Knex can surface the expected failure semantics\n throw new Error(\n \"Connection closed during commit - this is expected with DDL operations on IBM i DB2\"\n );\n }\n throw error;\n }\n }\n\n private isConnectionClosed(error: any): boolean {\n const message = String(error?.message || error || \"\").toLowerCase();\n return (\n message.includes(\"connection\") &&\n (message.includes(\"closed\") ||\n message.includes(\"invalid\") ||\n message.includes(\"terminated\") ||\n message.includes(\"not connected\"))\n );\n }\n}\n\nexport default IBMiTransaction;\n","import QueryCompiler from \"knex/lib/query/querycompiler.js\";\nimport { rawOrFn as rawOrFn_ } from \"knex/lib/formatter/wrappingFormatter.js\";\n\nclass IBMiQueryCompiler extends QueryCompiler {\n // Use type assertion to work around ESM import interface issues\n [key: string]: any;\n\n // Cache for column metadata to improve performance with repeated operations\n private columnCache = new Map<string, string[]>();\n\n // Override select method to add IBM i optimization hints\n select() {\n let sql = super.select.call(this);\n \n // Add WITH UR (uncommitted read) if configured\n const readUncommitted = this.client?.config?.ibmi?.readUncommitted === true;\n if (readUncommitted && typeof sql === 'string') {\n sql = sql + ' WITH UR';\n }\n \n return sql;\n }\n\n private formatTimestampLocal(date: Date): string {\n const pad = (n: number) => String(n).padStart(2, \"0\");\n const y = date.getFullYear();\n const m = pad(date.getMonth() + 1);\n const d = pad(date.getDate());\n const hh = pad(date.getHours());\n const mm = pad(date.getMinutes());\n const ss = pad(date.getSeconds());\n return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;\n }\n insert() {\n const insertValues = this.single.insert || [];\n const { returning } = this.single;\n\n // Handle empty insert values\n if (this.isEmptyInsertValues(insertValues)) {\n if (this.isEmptyObject(insertValues)) {\n return this.buildEmptyInsertResult(returning);\n }\n return \"\";\n }\n\n // Decide multi-row insert strategy (default: allow multi-row single statement)\n const ibmiConfig = this.client?.config?.ibmi || {};\n const multiRowStrategy = ibmiConfig.multiRowInsert || \"auto\"; // 'auto' | 'sequential' | 'disabled'\n\n // When disabled, or sequential strategy with >1 rows, fall back to first row only SQL generation here.\n // Sequential execution of additional rows is handled at runtime in the client (future enhancement).\n const isArrayInsert =\n Array.isArray(insertValues) && insertValues.length > 1;\n // Keep original values for sequential strategy metadata\n const originalValues = isArrayInsert ? insertValues.slice() : insertValues;\n const forceSingleRow =\n multiRowStrategy === \"disabled\" ||\n (multiRowStrategy === \"sequential\" && isArrayInsert);\n\n // If forcing single row, keep legacy single-row path by trimming to first element\n let workingValues: any = insertValues;\n if (forceSingleRow && isArrayInsert) {\n workingValues = [insertValues[0]];\n this.single.insert = workingValues; // mutate for downstream calls\n }\n\n // Get the standard INSERT statement from parent class (will include multi-row SQL if available)\n const standardInsert = super.insert();\n\n // If it's an object with sql property, use that; otherwise use the string directly\n const insertSql =\n typeof standardInsert === \"object\" && standardInsert.sql\n ? standardInsert.sql\n : standardInsert;\n\n // For IBM i, wrap INSERT with FINAL TABLE only when RETURNING is requested\n // Multi-row inserts without RETURNING should use plain INSERT for performance\n const multiRow = isArrayInsert && !forceSingleRow;\n \n // If multi-row insert without returning, use plain INSERT (return rowCount only)\n if (multiRow && !returning) {\n return { sql: insertSql, returning: undefined };\n }\n \n // Warn about potentially large result sets\n if (multiRow && returning === \"*\") {\n if (this.client?.printWarn) {\n this.client.printWarn(\"multi-row insert with returning * may be large\");\n }\n }\n \n // Use FINAL TABLE for single-row or when returning is specified\n const selectColumns = returning\n ? this.formatter.columnize(returning)\n : \"IDENTITY_VAL_LOCAL()\";\n const sql = `select ${selectColumns} from FINAL TABLE(${insertSql})`;\n\n // Add metadata for sequential strategy so runtime can execute remaining rows\n if (multiRowStrategy === \"sequential\" && isArrayInsert) {\n // Build column list using first row keys (sorted to match _prepInsert logic)\n const first = originalValues[0];\n const columns = Object.keys(first).sort();\n return {\n sql,\n returning: undefined,\n _ibmiSequentialInsert: {\n columns,\n rows: originalValues,\n tableName: this.tableName,\n returning: returning || null,\n identityOnly: !returning,\n },\n };\n }\n\n return { sql, returning: undefined };\n }\n\n private isEmptyInsertValues(insertValues: any): boolean {\n return (\n (Array.isArray(insertValues) && insertValues.length === 0) ||\n this.isEmptyObject(insertValues)\n );\n }\n\n private isEmptyObject(insertValues: any): boolean {\n return (\n insertValues !== null &&\n typeof insertValues === \"object\" &&\n !Array.isArray(insertValues) &&\n Object.keys(insertValues).length === 0\n );\n }\n\n private buildEmptyInsertResult(returning: any): {\n sql: string;\n returning: any;\n } {\n const selectColumns = returning\n ? this.formatter.columnize(returning)\n : \"IDENTITY_VAL_LOCAL()\";\n\n const returningSql = returning\n ? this._returning(\"insert\", returning, undefined) + \" \"\n : \"\";\n\n const insertSql = [\n this.with(),\n `insert into ${this.tableName}`,\n returningSql + this._emptyInsertValue,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const sql = `select ${selectColumns} from FINAL TABLE(${insertSql})`;\n\n return { sql, returning };\n }\n\n _buildInsertData(insertValues: string | any[], returningSql: string): string {\n const insertData = this._prepInsert(insertValues);\n\n if (insertData.columns.length > 0) {\n const parts: string[] = [];\n parts.push(\"(\" + this.formatter.columnize(insertData.columns) + \") \");\n if (returningSql) parts.push(returningSql);\n parts.push(\"values \");\n\n const rowsSql: string[] = [];\n for (const row of insertData.values) {\n const placeholders = row.map(() => \"?\").join(\", \");\n rowsSql.push(\"(\" + placeholders + \")\");\n }\n parts.push(rowsSql.join(\", \"));\n return parts.join(\"\");\n }\n\n if (\n Array.isArray(insertValues) &&\n insertValues.length === 1 &&\n insertValues[0]\n ) {\n return (returningSql || \"\") + this._emptyInsertValue;\n }\n return \"\";\n }\n\n private generateCacheKey(data: any): string {\n if (Array.isArray(data) && data.length > 0) {\n // Use the keys of the first object as cache key\n return Object.keys(data[0] || {})\n .sort()\n .join(\"|\");\n }\n if (data && typeof data === \"object\") {\n return Object.keys(data).sort().join(\"|\");\n }\n return \"\";\n }\n\n private buildFromCache(\n data: any,\n cachedColumns: string[]\n ): { columns: any; values: any } {\n const dataArray = Array.isArray(data) ? data : data ? [data] : [];\n const values: any[] = [];\n\n // Build values array using cached column order\n for (const item of dataArray) {\n if (item == null) {\n break;\n }\n const row = cachedColumns.map((column) => item[column] ?? undefined);\n values.push(row);\n }\n\n return {\n columns: cachedColumns,\n values,\n };\n }\n\n _prepInsert(data: any): { columns: any; values: any } {\n // Handle timestamps in knex migrations\n if (typeof data === \"object\" && data?.migration_time) {\n const parsed = new Date(data.migration_time);\n if (!isNaN(parsed.getTime())) {\n data.migration_time = this.formatTimestampLocal(parsed);\n }\n }\n\n const isRaw = rawOrFn_(\n data,\n undefined,\n this.builder,\n this.client,\n this.bindingsHolder\n );\n\n if (isRaw) {\n return isRaw;\n }\n\n // Normalize data to array format\n const dataArray = Array.isArray(data) ? data : data ? [data] : [];\n\n if (dataArray.length === 0) {\n return { columns: [], values: [] };\n }\n\n // Multi-row support: build unified column list from first row, then map all rows\n const firstItem = dataArray[0];\n if (!firstItem || typeof firstItem !== \"object\") {\n return { columns: [], values: [] };\n }\n\n const cacheKey = this.generateCacheKey(firstItem);\n let columns: string[];\n if (cacheKey && this.columnCache.has(cacheKey)) {\n columns = this.columnCache.get(cacheKey)!;\n } else {\n columns = Object.keys(firstItem).sort();\n if (cacheKey && columns.length > 0)\n this.columnCache.set(cacheKey, columns);\n }\n\n const values: any[] = [];\n for (const item of dataArray) {\n if (!item || typeof item !== \"object\") continue;\n values.push(columns.map((c) => item[c] ?? undefined));\n }\n\n return { columns, values };\n }\n\n update(): { sql: string; returning: any; _ibmiUpdateReturning?: any } {\n const withSQL = this.with();\n const updates = this._prepUpdate(this.single.update);\n const where = this.where();\n const order = this.order();\n const limit = this.limit();\n const { returning } = this.single;\n\n // Add IBM i v7r3+ optimization hints for UPDATE\n const optimizationHints = \"\";\n\n // Build the base update statement\n const baseUpdateSql = [\n withSQL,\n `update ${this.single.only ? \"only \" : \"\"}${this.tableName}`,\n \"set\",\n updates.join(\", \"),\n where,\n order,\n limit,\n optimizationHints,\n ]\n .filter(Boolean)\n .join(\" \");\n\n // Handle returning clause\n if (returning) {\n // For tests and toString(), show the expected FINAL TABLE format\n // But add metadata for actual execution using UPDATE + SELECT approach\n const selectColumns = this.formatter.columnize(this.single.returning);\n const expectedSql = `select ${selectColumns} from FINAL TABLE(${baseUpdateSql})`;\n\n return {\n sql: expectedSql,\n returning,\n _ibmiUpdateReturning: {\n updateSql: baseUpdateSql,\n selectColumns,\n whereClause: where,\n tableName: this.tableName,\n },\n };\n }\n\n return { sql: baseUpdateSql, returning };\n }\n\n // Emulate DELETE ... RETURNING by compiling a FINAL TABLE wrapper for display and attaching metadata\n del(): { sql: string; returning: any; _ibmiDeleteReturning?: any } {\n const baseDelete = super.del();\n const { returning } = this.single;\n if (!returning) {\n return { sql: baseDelete as string, returning: undefined };\n }\n const deleteSql =\n typeof baseDelete === \"object\" && (baseDelete as any).sql\n ? (baseDelete as any).sql\n : baseDelete;\n const selectColumns = this.formatter.columnize(returning);\n const expectedSql = `select ${selectColumns} from FINAL TABLE(${deleteSql})`;\n return {\n sql: expectedSql,\n returning,\n _ibmiDeleteReturning: {\n deleteSql,\n selectColumns,\n whereClause: this.where(),\n tableName: this.tableName,\n },\n };\n }\n\n /**\n * Handle returning clause for IBMi DB2 queries\n * Note: IBMi DB2 has limited support for RETURNING clauses\n * @param method - The SQL method (insert, update, delete)\n * @param value - The returning value\n * @param withTrigger - Trigger support (currently unused)\n */\n _returning(method: string, value: any, withTrigger: undefined) {\n switch (method) {\n case \"update\":\n case \"insert\":\n return value ? `${withTrigger ? \" into #out\" : \"\"}` : \"\";\n case \"del\":\n return value ? `${withTrigger ? \" into #out\" : \"\"}` : \"\";\n case \"rowcount\":\n return value ? \"select @@rowcount\" : \"\";\n default:\n return \"\";\n }\n }\n\n private getOptimizationHints(queryType: string, data?: any): string {\n const hints: string[] = [];\n\n // IBM i DB2 doesn't support OPTIMIZE FOR in all contexts\n // Use WITH UR (Uncommitted Read) for better concurrency instead\n if (queryType === \"select\") {\n hints.push(\"WITH UR\"); // Uncommitted Read for better performance on read-heavy workloads\n }\n\n return hints.length > 0 ? \" \" + hints.join(\" \") : \"\";\n }\n\n private getSelectOptimizationHints(sql: string): string {\n const hints: string[] = [];\n\n // Only use WITH UR for read operations on IBM i DB2\n // OPTIMIZE FOR syntax causes errors on this IBM i version\n hints.push(\"WITH UR\");\n\n return hints.length > 0 ? \" \" + hints.join(\" \") : \"\";\n }\n\n columnizeWithPrefix(prefix: string, target: string | string[]) {\n const columns = typeof target === \"string\" ? [target] : target;\n const parts: string[] = [];\n\n for (let i = 0; i < columns.length; i++) {\n if (i > 0) parts.push(\", \");\n parts.push(prefix + this.wrap(columns[i]));\n }\n\n return parts.join(\"\");\n }\n}\n\nexport default IBMiQueryCompiler;\n","import fs from \"fs\";\nimport path from \"path\";\nimport { Knex } from \"knex\";\n\nexport interface IBMiMigrationConfig {\n directory: string;\n tableName: string;\n schemaName?: string;\n extension?: string;\n}\n\nexport class IBMiMigrationRunner {\n private knex: Knex;\n private config: IBMiMigrationConfig;\n\n constructor(knex: Knex, config?: Partial<IBMiMigrationConfig>) {\n this.knex = knex;\n\n // Default configuration\n this.config = {\n directory: \"./migrations\",\n tableName: \"KNEX_MIGRATIONS\",\n schemaName: undefined,\n extension: \"js\",\n ...config,\n };\n }\n\n private getFullTableName(): string {\n return this.config.schemaName\n ? `${this.config.schemaName}.${this.config.tableName}`\n : this.config.tableName;\n }\n\n async latest(): Promise<void> {\n try {\n console.log(\n \"šŸš€ IBM i DB2 Migration Runner - bypassing Knex locking system\"\n );\n\n // Ensure the migration table exists\n const tableName = this.getFullTableName();\n\n const migrationTableExists = await (this.knex as any).schema.hasTable(\n tableName\n );\n if (!migrationTableExists) {\n console.log(`šŸ“ Creating migration table: ${tableName}`);\n await (this.knex as any).schema.createTable(tableName, (table) => {\n table.increments(\"id\").primary();\n table.string(\"name\").unique(); // Prevent duplicate migration names\n table.integer(\"batch\");\n table.timestamp(\"migration_time\");\n });\n console.log(\"āœ… Migration table created\");\n }\n\n // Get completed migrations (IBM i uses uppercase column names)\n const completed = await this.knex(tableName).select(\"NAME\").orderBy(\"ID\");\n const completedNames = completed.map((c: any) => c.NAME);\n console.log(`šŸ“‹ Found ${completedNames.length} completed migrations`);\n\n // Get migration files\n const migrationFiles = this.getMigrationFiles();\n console.log(`šŸ“ Found ${migrationFiles.length} migration files`);\n\n // Find new migrations to run\n const newMigrations = migrationFiles.filter(\n (file) => !completedNames.includes(file)\n );\n\n if (newMigrations.length === 0) {\n console.log(\"āœ… No new migrations to run\");\n return;\n }\n\n console.log(`šŸŽÆ Running ${newMigrations.length} new migrations:`);\n newMigrations.forEach((file) => console.log(` - ${file}`));\n\n // Get next batch number (IBM i uses uppercase column names)\n const batchResult = await this.knex(tableName).max(\"BATCH as max_batch\");\n const nextBatch = (batchResult[0]?.max_batch || 0) + 1;\n console.log(`šŸ“Š Using batch number: ${nextBatch}`);\n\n // Run each migration\n for (const migrationFile of newMigrations) {\n console.log(`\\nšŸ”„ Running migration: ${migrationFile}`);\n\n try {\n // Import the migration\n const migrationPath = this.getMigrationPath(migrationFile);\n const migration = await import(migrationPath);\n\n if (!migration.up || typeof migration.up !== \"function\") {\n throw new Error(`Migration ${migrationFile} has no 'up' function`);\n }\n\n // Execute the migration\n console.log(` ⚔ Executing migration...`);\n await migration.up(this.knex);\n\n // Record the migration\n await this.knex(tableName).insert({\n name: migrationFile,\n batch: nextBatch,\n migration_time: new Date(),\n });\n\n console.log(` āœ… Migration ${migrationFile} completed successfully`);\n } catch (error: any) {\n console.error(\n ` āŒ Migration ${migrationFile} failed:`,\n error.message\n );\n throw error;\n }\n }\n\n console.log(`\\nšŸŽ‰ All migrations completed successfully!`);\n } catch (error: any) {\n console.error(\"āŒ Migration runner failed:\", error.message);\n throw error;\n }\n }\n\n async rollback(steps: number = 1): Promise<void> {\n try {\n console.log(`šŸ”„ Rolling back ${steps} migration batch(es)...`);\n\n const tableName = this.getFullTableName();\n\n // Get the last batch(es) to rollback\n const batchesToRollback = await this.knex(tableName)\n .distinct(\"BATCH\")\n .orderBy(\"BATCH\", \"desc\")\n .limit(steps);\n\n if (batchesToRollback.length === 0) {\n console.log(\"āœ… No migrations to rollback\");\n return;\n }\n\n const batchNumbers = batchesToRollback.map((b: any) => b.BATCH);\n console.log(`šŸ“Š Rolling back batches: ${batchNumbers.join(\", \")}`);\n\n // Get migrations to rollback\n const migrationsToRollback = await this.knex(tableName)\n .select(\"NAME\")\n .whereIn(\"BATCH\", batchNumbers)\n .orderBy(\"ID\", \"desc\");\n\n console.log(`šŸŽÆ Rolling back ${migrationsToRollback.length} migrations:`);\n migrationsToRollback.forEach((m: any) => console.log(` - ${m.NAME}`));\n\n // Rollback each migration\n for (const migrationRecord of migrationsToRollback) {\n const migrationFile = migrationRecord.NAME;\n console.log(`\\nšŸ”„ Rolling back migration: ${migrationFile}`);\n\n try {\n // Import the migration\n const migrationPath = this.getMigrationPath(migrationFile);\n const migration = await import(migrationPath);\n\n if (migration.down && typeof migration.down === \"function\") {\n console.log(` ⚔ Executing rollback...`);\n await migration.down(this.knex);\n } else {\n console.log(\n ` āš ļø Migration ${migrationFile} has no 'down' function, skipping rollback`\n );\n }\n\n // Remove the migration record\n await this.knex(tableName).where(\"NAME\", migrationFile).del();\n\n console.log(\n ` āœ… Migration ${migrationFile} rolled back successfully`\n );\n } catch (error: any) {\n console.error(\n ` āŒ Migration ${migrationFile} rollback failed:`,\n error.message\n );\n throw error;\n }\n }\n\n console.log(`\\nšŸŽ‰ Rollback completed successfully!`);\n } catch (error: any) {\n console.error(\"āŒ Rollback failed:\", error.message);\n throw error;\n }\n }\n\n async currentVersion(): Promise<string | null> {\n try {\n const tableName = this.getFullTableName();\n\n const migrationTableExists = await (this.knex as any).schema.hasTable(\n tableName\n );\n if (!migrationTableExists) {\n return null;\n }\n\n const result = await this.knex(tableName)\n .select(\"NAME\")\n .orderBy(\"ID\", \"desc\")\n .first();\n\n return result?.NAME || null;\n } catch (error: any) {\n console.error(\"āŒ Error getting current version:\", error.message);\n return null;\n }\n }\n\n async listExecuted(): Promise<string[]> {\n try {\n const tableName = this.getFullTableName();\n\n const migrationTableExists = await (this.knex as any).schema.hasTable(\n tableName\n );\n if (!migrationTableExists) {\n return [];\n }\n\n const completed = await this.knex(tableName).select(\"NAME\").orderBy(\"ID\");\n return completed.map((c: any) => c.NAME);\n } catch (error: any) {\n console.error(\"āŒ Error listing executed migrations:\", error.message);\n return [];\n }\n }\n\n async listPending(): Promise<string[]> {\n try {\n const allFiles = this.getMigrationFiles();\n const executed = await this.listExecuted();\n return allFiles.filter((file) => !executed.includes(file));\n } catch (error: any) {\n console.error(\"āŒ Error listing pending migrations:\", error.message);\n return [];\n }\n }\n\n private getMigrationFiles(): string[] {\n const { directory, extension } = this.config;\n\n if (!fs.existsSync(directory)) {\n throw new Error(`Migration directory does not exist: ${directory}`);\n }\n\n // Support multiple extensions by checking for common migration file extensions\n const validExtensions = [\"js\", \"ts\", \"mjs\", \"cjs\"];\n const extensionToCheck = extension || \"js\";\n\n return fs\n .readdirSync(directory)\n .filter((file) => {\n // If a specific extension is configured, use only that\n if (extension && extension !== \"js\") {\n return file.endsWith(`.${extension}`);\n }\n // Otherwise, check for any valid migration extension\n return validExtensions.some((ext) => file.endsWith(`.${ext}`));\n })\n .sort();\n }\n\n private getMigrationPath(filename: string): string {\n return path.resolve(this.config.directory, filename);\n }\n}\n\n// Export a factory function for easy instantiation\nexport function createIBMiMigrationRunner(\n knex: Knex,\n config?: Partial<IBMiMigrationConfig>\n): IBMiMigrationRunner {\n return new IBMiMigrationRunner(knex, config);\n}\n"],"mappings":"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","names":["knex"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bdkinc/knex-ibmi",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Knex dialect for IBMi",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",