@bdkinc/knex-ibmi 0.5.11 → 0.5.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +476 -476
- package/dist/index.d.mts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +16 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +74 -74
package/dist/index.mjs.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\";\r\nimport { Buffer } from \"node:buffer\";\r\nimport knex, { Knex } from \"knex\";\r\nimport odbc, { Connection } from \"odbc\";\r\nimport SchemaCompiler from \"./schema/ibmi-compiler\";\r\nimport TableCompiler from \"./schema/ibmi-tablecompiler\";\r\nimport ColumnCompiler from \"./schema/ibmi-columncompiler\";\r\nimport Transaction from \"./execution/ibmi-transaction\";\r\nimport QueryCompiler from \"./query/ibmi-querycompiler\";\r\nimport { Readable } from \"node:stream\";\r\nimport {\r\n IBMiMigrationRunner,\r\n createIBMiMigrationRunner,\r\n} from \"./migrations/ibmi-migration-runner\";\r\n\r\ninterface QueryObject {\r\n response?: {\r\n rows: any[];\r\n rowCount: number;\r\n };\r\n sqlMethod: SqlMethod;\r\n output?: (runner: any, response: any) => any;\r\n pluck?: (row: any) => any;\r\n select?: boolean;\r\n}\r\n\r\nenum SqlMethod {\r\n SELECT = \"select\",\r\n PLUCK = \"pluck\",\r\n FIRST = \"first\",\r\n INSERT = \"insert\",\r\n DELETE = \"del\",\r\n DELETE_ALT = \"delete\",\r\n UPDATE = \"update\",\r\n COUNTER = \"counter\",\r\n}\r\n\r\n// Simple LRU cache for prepared statements\r\nclass StatementCache {\r\n private cache = new Map<string, any>();\r\n private maxSize: number;\r\n\r\n constructor(maxSize: number = 100) {\r\n this.maxSize = maxSize;\r\n }\r\n\r\n get(sql: string): any | undefined {\r\n const stmt = this.cache.get(sql);\r\n if (stmt) {\r\n // Move to end (most recently used)\r\n this.cache.delete(sql);\r\n this.cache.set(sql, stmt);\r\n }\r\n return stmt;\r\n }\r\n\r\n set(sql: string, stmt: any): void {\r\n // Remove oldest if at capacity\r\n if (this.cache.size >= this.maxSize) {\r\n const firstKey = this.cache.keys().next().value as string | undefined;\r\n if (firstKey !== undefined) {\r\n const oldStmt = this.cache.get(firstKey);\r\n this.cache.delete(firstKey);\r\n // Close the evicted statement\r\n if (oldStmt && typeof oldStmt.close === \"function\") {\r\n oldStmt.close().catch(() => {});\r\n }\r\n }\r\n }\r\n this.cache.set(sql, stmt);\r\n }\r\n\r\n async clear(): Promise<void> {\r\n const statements = Array.from(this.cache.values());\r\n this.cache.clear();\r\n // Close all cached statements\r\n await Promise.all(\r\n statements.map((stmt) =>\r\n stmt && typeof stmt.close === \"function\"\r\n ? stmt.close().catch(() => {})\r\n : Promise.resolve(),\r\n ),\r\n );\r\n }\r\n\r\n size(): number {\r\n return this.cache.size;\r\n }\r\n}\r\n\r\nclass DB2Client extends knex.Client {\r\n // Per-connection statement cache (WeakMap so it's GC'd with connections)\r\n private statementCaches = new WeakMap<Connection, StatementCache>();\r\n private normalizeBigintToString: boolean;\r\n\r\n constructor(config: Knex.Config<DB2Config>) {\r\n super(config);\r\n this.driverName = \"odbc\";\r\n\r\n if (this.dialect && !this.config.client) {\r\n this.printWarn(\r\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.`,\r\n );\r\n }\r\n\r\n const dbClient = this.config.client || this.dialect;\r\n if (!dbClient) {\r\n throw new Error(\r\n `knex: Required configuration option 'client' is missing.`,\r\n );\r\n }\r\n\r\n if (config.version) {\r\n this.version = config.version;\r\n }\r\n\r\n if (this.driverName && config.connection) {\r\n this.initializeDriver();\r\n if (!config.pool || (config.pool && config.pool.max !== 0)) {\r\n this.initializePool(config);\r\n }\r\n }\r\n\r\n this.valueForUndefined = this.raw(\"DEFAULT\");\r\n if (config.useNullAsDefault) {\r\n this.valueForUndefined = null;\r\n }\r\n\r\n const ibmiConfig = (config as any)?.ibmi;\r\n this.normalizeBigintToString =\r\n ibmiConfig?.normalizeBigintToString !== false;\r\n }\r\n\r\n // Helper method to safely stringify objects that might have circular references\r\n private safeStringify(obj: any, indent: number = 0): string {\r\n try {\r\n return JSON.stringify(obj, null, indent);\r\n } catch (error) {\r\n if (error instanceof Error && error.message.includes(\"circular\")) {\r\n return `[Circular structure - ${typeof obj}]`;\r\n }\r\n return `[Stringify error - ${typeof obj}]`;\r\n }\r\n }\r\n\r\n _driver() {\r\n return odbc;\r\n }\r\n\r\n wrapIdentifierImpl(value: string) {\r\n // override default wrapper (\")\r\n // we don't want to use it since\r\n // it makes identifier case-sensitive in DB2\r\n\r\n if (!value) return value;\r\n\r\n // Handle migration tables specifically - keep simple for now\r\n if (\r\n value.includes(\"KNEX_MIGRATIONS\") ||\r\n value.includes(\"knex_migrations\")\r\n ) {\r\n return value.toUpperCase();\r\n }\r\n\r\n // For now, just return the value as-is to avoid binding issues\r\n // IBM i DB2 is case-insensitive by default anyway\r\n return value;\r\n }\r\n\r\n printDebug(message: string) {\r\n if (process.env.DEBUG === \"true\") {\r\n if (this.logger.debug) {\r\n this.logger.debug(\"knex-ibmi: \" + message);\r\n }\r\n }\r\n }\r\n\r\n printError(message: string) {\r\n if (this.logger.error) {\r\n this.logger.error(\"knex-ibmi: \" + message);\r\n }\r\n }\r\n\r\n printWarn(message: string) {\r\n if (process.env.DEBUG === \"true\") {\r\n if (this.logger.warn) {\r\n this.logger.warn(\"knex-ibmi: \" + message);\r\n }\r\n }\r\n }\r\n\r\n // Get a raw connection, called by the pool manager whenever a new\r\n // connection needs to be added to the pool.\r\n async acquireRawConnection() {\r\n this.printDebug(\"acquiring raw connection\");\r\n const connectionConfig = this.config.connection as DB2ConnectionConfig;\r\n\r\n if (!connectionConfig) {\r\n throw new Error(\"There is no connection config defined\");\r\n }\r\n\r\n this.printDebug(\r\n \"connection config: \" + this._getConnectionString(connectionConfig),\r\n );\r\n\r\n // Use simple ODBC connection - Knex manages the pooling\r\n // This fixes the double-pooling bug where a new ODBC pool was created per connection\r\n const connection = await this.driver.connect(\r\n this._getConnectionString(connectionConfig),\r\n );\r\n\r\n return connection;\r\n }\r\n\r\n // Used to explicitly close a connection, called internally by the pool manager\r\n // when a connection times out or the pool is shutdown.\r\n async destroyRawConnection(connection: any) {\r\n this.printDebug(\"destroy connection\");\r\n\r\n // Clean up statement cache if it exists\r\n const cache = this.statementCaches.get(connection);\r\n if (cache) {\r\n await cache.clear();\r\n this.statementCaches.delete(connection);\r\n }\r\n\r\n return await connection.close();\r\n }\r\n\r\n // Knex pool validation hook.\r\n // If this returns false, Knex/tarn will destroy the resource and create a new one.\r\n // This is critical for recovering after IBM i restarts / network drops.\r\n async validateConnection(connection: any): Promise<boolean> {\r\n try {\r\n // node-odbc exposes `connected` getter on Connection wrapper\r\n return Boolean(connection && connection.connected);\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n _getConnectionString(connectionConfig: DB2ConnectionConfig) {\r\n const userParams = connectionConfig.connectionStringParams || {};\r\n\r\n // Use user-provided parameters directly without applying defaults\r\n // Let the ODBC driver use its own defaults unless explicitly overridden\r\n //\r\n // Driver Defaults (for reference):\r\n // - CMT: 2 (Read uncommitted / *CHG)\r\n // - TRUEAUTOCOMMIT: 0 (*NONE isolation level)\r\n // - BLOCKFETCH: 0 (disabled)\r\n //\r\n // Reference: https://www.ibm.com/docs/en/i/7.4.0?topic=details-connection-string-keywords\r\n const connectionStringParams: Record<string, unknown> = { ...userParams };\r\n\r\n const connectionStringExtension = Object.keys(\r\n connectionStringParams,\r\n ).reduce((result, key) => {\r\n const value = connectionStringParams[key];\r\n return `${result}${key}=${value};`;\r\n }, \"\");\r\n\r\n return (\r\n `DRIVER=${connectionConfig.driver};` +\r\n `SYSTEM=${connectionConfig.host};` +\r\n `PORT=${connectionConfig.port || 8471};` +\r\n `DATABASE=${connectionConfig.database};` +\r\n `UID=${connectionConfig.user};` +\r\n `PWD=${connectionConfig.password};` +\r\n connectionStringExtension\r\n );\r\n }\r\n\r\n // Runs the query on the specified connection, providing the bindings\r\n async _query(connection: Connection, obj: any) {\r\n const queryObject = this.normalizeQueryObject(obj);\r\n const method = this.determineQueryMethod(queryObject);\r\n queryObject.sqlMethod = method;\r\n\r\n // Special handling for UPDATE with returning clause\r\n if (queryObject._ibmiUpdateReturning) {\r\n return await this.executeUpdateReturning(connection, queryObject);\r\n }\r\n\r\n // Sequential multi-row insert execution path\r\n if (queryObject._ibmiSequentialInsert) {\r\n return await this.executeSequentialInsert(connection, queryObject);\r\n }\r\n\r\n // DELETE ... RETURNING emulation\r\n if (queryObject._ibmiDeleteReturning) {\r\n return await this.executeDeleteReturning(connection, queryObject);\r\n }\r\n\r\n // Debug migration queries (only if DEBUG environment variable is set)\r\n if (\r\n process.env.DEBUG === \"true\" &&\r\n queryObject.sql &&\r\n (queryObject.sql.toLowerCase().includes(\"create table\") ||\r\n queryObject.sql.toLowerCase().includes(\"knex_migrations\"))\r\n ) {\r\n this.printDebug(\r\n `Executing ${method} query: ${queryObject.sql.substring(0, 200)}...`,\r\n );\r\n if (queryObject.bindings?.length) {\r\n this.printDebug(\r\n `Bindings: ${this.safeStringify(queryObject.bindings)}`,\r\n );\r\n }\r\n }\r\n\r\n try {\r\n const startTime = Date.now();\r\n if (this.isSelectMethod(method)) {\r\n await this.executeSelectQuery(connection, queryObject);\r\n } else {\r\n await this.executeStatementQuery(connection, queryObject);\r\n }\r\n const endTime = Date.now();\r\n\r\n if (\r\n process.env.DEBUG === \"true\" &&\r\n queryObject.sql &&\r\n (queryObject.sql.toLowerCase().includes(\"create table\") ||\r\n queryObject.sql.toLowerCase().includes(\"knex_migrations\"))\r\n ) {\r\n this.printDebug(`${method} completed in ${endTime - startTime}ms`);\r\n }\r\n\r\n this.printDebug(`Query completed: ${method} (${endTime - startTime}ms)`);\r\n return queryObject;\r\n } catch (error: any) {\r\n // Enhanced error handling for connection issues\r\n const wrappedError = this.wrapError(error, method, queryObject);\r\n\r\n if (this.isConnectionError(error)) {\r\n // Mark this connection as unusable so Knex/tarn destroys it.\r\n // Without this, dead ODBC connections can remain in the pool indefinitely.\r\n (connection as any).__knex__disposed = error;\r\n\r\n this.printError(\r\n `Connection error during ${method} query: ${error.message}`,\r\n );\r\n\r\n // For critical migration operations, retry once before failing\r\n if (this.shouldRetryQuery(queryObject, method)) {\r\n return await this.retryQuery(connection, queryObject, method);\r\n }\r\n\r\n throw wrappedError;\r\n }\r\n throw wrappedError;\r\n }\r\n }\r\n\r\n /**\r\n * Execute UPDATE with returning clause using UPDATE + SELECT approach.\r\n * Since IBM i DB2 doesn't support FINAL TABLE with UPDATE, we:\r\n * 1. Execute the UPDATE statement\r\n * 2. Execute a SELECT to get the updated values using the same WHERE clause\r\n *\r\n * @warning RACE CONDITION: In concurrent environments, rows may change between\r\n * the UPDATE and SELECT operations. If another transaction modifies, inserts,\r\n * or deletes rows matching the WHERE clause between these two statements,\r\n * the returned results may not accurately reflect what was updated.\r\n * For strict consistency requirements, consider:\r\n * - Using serializable transaction isolation level\r\n * - Implementing optimistic locking at the application level\r\n * - Avoiding `.returning()` on UPDATE and fetching data separately\r\n */\r\n private async executeUpdateReturning(\r\n connection: Connection,\r\n obj: any,\r\n ): Promise<any> {\r\n const { _ibmiUpdateReturning } = obj;\r\n const {\r\n updateSql,\r\n selectColumns,\r\n whereClause,\r\n tableName,\r\n setBindingCount,\r\n } = _ibmiUpdateReturning;\r\n\r\n this.printDebug(\r\n \"Executing UPDATE with returning using transaction approach\",\r\n );\r\n\r\n try {\r\n // Execute the UPDATE statement\r\n const updateObj = {\r\n sql: updateSql,\r\n bindings: obj.bindings,\r\n sqlMethod: \"update\",\r\n };\r\n\r\n await this.executeStatementQuery(connection, updateObj);\r\n\r\n // Build and execute SELECT to get the updated values\r\n const selectSql = whereClause\r\n ? `select ${selectColumns} from ${tableName} ${whereClause}`\r\n : `select ${selectColumns} from ${tableName}`;\r\n\r\n // Extract only WHERE clause bindings for SELECT\r\n // UPDATE bindings format: [set_values..., where_values...]\r\n // We need to figure out how many bindings are for SET vs WHERE\r\n const inferredSetBindingCount =\r\n typeof setBindingCount === \"number\"\r\n ? setBindingCount\r\n : ((updateSql.split(\" where \")[0].match(/\\?/g) || [])\r\n .length as number);\r\n const whereBindings = obj.bindings\r\n ? obj.bindings.slice(inferredSetBindingCount)\r\n : [];\r\n\r\n const selectObj = {\r\n sql: selectSql,\r\n bindings: whereBindings,\r\n sqlMethod: \"select\",\r\n response: undefined,\r\n };\r\n\r\n await this.executeSelectQuery(connection, selectObj);\r\n\r\n // Return the SELECT results as the final response\r\n obj.response = selectObj.response;\r\n obj.sqlMethod = \"update\";\r\n obj.select = true; // Mark as SELECT behavior to return rows instead of rowCount\r\n return obj;\r\n } catch (error: any) {\r\n this.printError(`UPDATE with returning failed: ${error.message}`);\r\n throw this.wrapError(error, \"update_returning\", obj);\r\n }\r\n }\r\n\r\n private async executeSequentialInsert(\r\n connection: Connection,\r\n obj: any,\r\n ): Promise<any> {\r\n const meta = obj._ibmiSequentialInsert;\r\n const { rows, columns, tableName, returning } = meta;\r\n this.printDebug(\"Executing sequential multi-row insert\");\r\n const insertedRows: any[] = [];\r\n\r\n const transactional =\r\n (this.config as any)?.ibmi?.sequentialInsertTransactional === true;\r\n let beganTx = false;\r\n if (transactional) {\r\n try {\r\n await connection.query(\"BEGIN\");\r\n beganTx = true;\r\n } catch (_e) {\r\n this.printWarn(\r\n \"Could not begin transaction for sequential insert; proceeding without\",\r\n );\r\n }\r\n }\r\n\r\n for (let i = 0; i < rows.length; i++) {\r\n const row = rows[i];\r\n const colList = columns.join(\", \");\r\n const placeholders = columns.map(() => \"?\").join(\", \");\r\n const singleValues = columns.map((c: string) => row[c]);\r\n const baseInsert = `insert into ${tableName} (${colList}) values (${placeholders})`;\r\n const selectCols = returning\r\n ? this.queryCompiler({} as any).formatter.columnize(returning)\r\n : \"IDENTITY_VAL_LOCAL()\";\r\n const wrapped = `select ${selectCols} from FINAL TABLE(${baseInsert})`;\r\n const singleObj = {\r\n sql: wrapped,\r\n bindings: singleValues,\r\n sqlMethod: \"insert\",\r\n response: undefined,\r\n };\r\n await this.executeStatementQuery(connection, singleObj);\r\n const resp = (singleObj as any).response?.rows;\r\n if (resp) insertedRows.push(...resp);\r\n }\r\n\r\n if (transactional && beganTx) {\r\n try {\r\n await connection.query(\"COMMIT\");\r\n } catch (commitErr) {\r\n this.printError(\r\n \"Commit failed for sequential insert, attempting rollback: \" +\r\n (commitErr as any)?.message,\r\n );\r\n try {\r\n await connection.query(\"ROLLBACK\");\r\n } catch {\r\n /* ignore */\r\n }\r\n throw commitErr;\r\n }\r\n }\r\n\r\n obj.response = { rows: insertedRows, rowCount: insertedRows.length };\r\n obj.sqlMethod = \"insert\";\r\n obj.select = true;\r\n return obj;\r\n }\r\n\r\n private async executeDeleteReturning(\r\n connection: Connection,\r\n obj: any,\r\n ): Promise<any> {\r\n const meta = obj._ibmiDeleteReturning;\r\n const { deleteSql, selectColumns, whereClause, tableName } = meta;\r\n this.printDebug(\"Executing DELETE with returning emulation\");\r\n try {\r\n // SELECT rows first\r\n const selectSql = whereClause\r\n ? `select ${selectColumns} from ${tableName} ${whereClause}`\r\n : `select ${selectColumns} from ${tableName}`;\r\n const selectObj = {\r\n sql: selectSql,\r\n bindings: obj.bindings,\r\n sqlMethod: \"select\",\r\n response: undefined,\r\n };\r\n await this.executeSelectQuery(connection, selectObj);\r\n const rowsToReturn = (selectObj as any).response?.rows || [];\r\n // Execute DELETE\r\n const deleteObj = {\r\n sql: deleteSql,\r\n bindings: obj.bindings,\r\n sqlMethod: \"del\",\r\n response: undefined,\r\n };\r\n await this.executeStatementQuery(connection, deleteObj);\r\n obj.response = { rows: rowsToReturn, rowCount: rowsToReturn.length };\r\n obj.sqlMethod = \"del\";\r\n obj.select = true;\r\n return obj;\r\n } catch (error: any) {\r\n this.printError(`DELETE with returning failed: ${error.message}`);\r\n throw this.wrapError(error, \"delete_returning\", obj);\r\n }\r\n }\r\n\r\n private normalizeQueryObject(obj: any): any {\r\n if (!obj || typeof obj === \"string\") {\r\n return { sql: obj };\r\n }\r\n return obj;\r\n }\r\n\r\n private determineQueryMethod(obj: any): string {\r\n return (\r\n obj.hasOwnProperty(\"method\") && obj.method !== \"raw\"\r\n ? obj.method\r\n : obj.sql.split(\" \")[0]\r\n ).toLowerCase();\r\n }\r\n\r\n private isSelectMethod(method: string): boolean {\r\n return method === \"select\" || method === \"first\" || method === \"pluck\";\r\n }\r\n\r\n private async executeSelectQuery(\r\n connection: Connection,\r\n obj: { sql: string; bindings: any[]; response: unknown },\r\n ): Promise<void> {\r\n const rows: Record<any, any>[] = await connection.query(\r\n obj.sql,\r\n obj.bindings,\r\n );\r\n if (rows) {\r\n const normalizedRows = this.maybeNormalizeBigint(rows);\r\n obj.response = { rows: normalizedRows, rowCount: normalizedRows.length };\r\n }\r\n }\r\n\r\n private async executeStatementQuery(\r\n connection: Connection,\r\n obj: any,\r\n ): Promise<void> {\r\n let statement: any;\r\n let usedCache = false;\r\n const cacheEnabled =\r\n (this.config as any)?.ibmi?.preparedStatementCache === true;\r\n\r\n try {\r\n // Try to use cached statement if enabled\r\n if (cacheEnabled) {\r\n let cache = this.statementCaches.get(connection);\r\n if (!cache) {\r\n const cacheSize =\r\n (this.config as any)?.ibmi?.preparedStatementCacheSize || 100;\r\n cache = new StatementCache(cacheSize);\r\n this.statementCaches.set(connection, cache);\r\n }\r\n\r\n statement = cache.get(obj.sql);\r\n if (statement) {\r\n usedCache = true;\r\n this.printDebug(\r\n `Using cached statement for: ${obj.sql.substring(0, 50)}...`,\r\n );\r\n } else {\r\n // Create and cache new statement\r\n statement = await connection.createStatement();\r\n await statement.prepare(obj.sql);\r\n cache.set(obj.sql, statement);\r\n this.printDebug(`Cached new statement (cache size: ${cache.size()})`);\r\n }\r\n } else {\r\n // No caching - create statement normally\r\n statement = await connection.createStatement();\r\n await statement.prepare(obj.sql);\r\n }\r\n\r\n if (obj.bindings) {\r\n await statement.bind(obj.bindings);\r\n }\r\n\r\n const result = await statement.execute();\r\n this.printDebug(String(result));\r\n\r\n obj.response = this.formatStatementResponse(result);\r\n } catch (err: any) {\r\n // Special handling for UPDATE/DELETE queries that affect 0 rows\r\n // Some ODBC drivers signal 0-row DML via empty error/\"no data\" (SQLSTATE 02000)\r\n const sql = (obj.sql || \"\").toLowerCase();\r\n const isDml =\r\n obj.sqlMethod === SqlMethod.UPDATE ||\r\n sql.includes(\" update \") ||\r\n sql.startsWith(\"update\") ||\r\n obj.sqlMethod === SqlMethod.DELETE ||\r\n sql.includes(\" delete \") ||\r\n sql.startsWith(\"delete\");\r\n\r\n const odbcErrors = err?.odbcErrors;\r\n const isEmptyOdbcError =\r\n Array.isArray(odbcErrors) && odbcErrors.length === 0;\r\n const hasNoDataState = Array.isArray(odbcErrors)\r\n ? odbcErrors.some(\r\n (e: any) =>\r\n String(e?.state || e?.SQLSTATE || \"\").toUpperCase() === \"02000\",\r\n )\r\n : false;\r\n\r\n if (\r\n isDml &&\r\n (isEmptyOdbcError || hasNoDataState || this.isNoDataError(err))\r\n ) {\r\n this.printWarn(\r\n `ODBC signaled no-data for ${sql.includes(\"update\") ? \"UPDATE\" : \"DELETE\"}; treating as 0 rows affected`,\r\n );\r\n obj.response = { rows: [], rowCount: 0 };\r\n return;\r\n }\r\n\r\n this.printError(this.safeStringify(err));\r\n throw err;\r\n } finally {\r\n // Only close statement if it's not cached\r\n if (!usedCache && statement && typeof statement.close === \"function\") {\r\n try {\r\n await statement.close();\r\n } catch (closeErr) {\r\n // Ignore close errors, log in debug mode only\r\n this.printDebug(\r\n `Error closing statement: ${this.safeStringify(closeErr, 2)}`,\r\n );\r\n }\r\n }\r\n }\r\n }\r\n\r\n private isNoDataError(error: any): boolean {\r\n if (!error) return false;\r\n const msg = String(error?.message || error || \"\").toLowerCase();\r\n // Match common indicators of 0-row DML reported as error\r\n return (\r\n msg.includes(\"02000\") ||\r\n msg.includes(\"no data\") ||\r\n msg.includes(\"no rows\") ||\r\n msg.includes(\"0 rows\")\r\n );\r\n }\r\n\r\n private shouldNormalizeBigintValues(): boolean {\r\n return this.normalizeBigintToString;\r\n }\r\n\r\n private maybeNormalizeBigint<T>(value: T): T {\r\n if (value === null || value === undefined) {\r\n return value;\r\n }\r\n\r\n if (!this.shouldNormalizeBigintValues()) {\r\n return value;\r\n }\r\n\r\n return this.normalizeBigintValue(value);\r\n }\r\n\r\n private normalizeBigintValue(\r\n value: any,\r\n seen: WeakSet<object> = new WeakSet(),\r\n ): any {\r\n if (typeof value === \"bigint\") {\r\n return value.toString();\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n for (let i = 0; i < value.length; i++) {\r\n value[i] = this.normalizeBigintValue(value[i], seen);\r\n }\r\n return value;\r\n }\r\n\r\n if (value && typeof value === \"object\") {\r\n if (\r\n value instanceof Date ||\r\n Buffer.isBuffer(value) ||\r\n ArrayBuffer.isView(value)\r\n ) {\r\n return value;\r\n }\r\n\r\n const obj = value as Record<string, any>;\r\n\r\n if (seen.has(obj)) {\r\n return value;\r\n }\r\n\r\n seen.add(obj);\r\n\r\n for (const key of Object.keys(obj)) {\r\n obj[key] = this.normalizeBigintValue(obj[key], seen);\r\n }\r\n\r\n return value;\r\n }\r\n\r\n return value;\r\n }\r\n\r\n /**\r\n * Format statement response from ODBC driver\r\n * Handles special case for IDENTITY_VAL_LOCAL() function\r\n */\r\n private formatStatementResponse(result: any): {\r\n rows: any;\r\n rowCount: number;\r\n } {\r\n const isIdentityQuery = result.statement?.includes(\"IDENTITY_VAL_LOCAL()\");\r\n\r\n if (isIdentityQuery && result.columns?.length > 0) {\r\n const identityRows = result.map(\r\n (row: { [x: string]: any }) => row[result.columns[0].name],\r\n );\r\n const normalizedIdentityRows = this.maybeNormalizeBigint(identityRows);\r\n return {\r\n rows: normalizedIdentityRows,\r\n rowCount: result.count,\r\n };\r\n }\r\n\r\n // Normalize result for DML (UPDATE/DELETE/INSERT) to surface rowCount consistently\r\n const rowCount = typeof result?.count === \"number\" ? result.count : 0;\r\n return {\r\n rows: this.maybeNormalizeBigint(result),\r\n rowCount,\r\n };\r\n }\r\n\r\n async _stream(\r\n connection: Connection,\r\n obj: { sql: string; bindings: any[] },\r\n stream: any,\r\n options: {\r\n fetchSize?: number;\r\n },\r\n ) {\r\n if (!obj.sql) throw new Error(\"A query is required to stream results\");\r\n\r\n const optimizedFetchSize =\r\n options?.fetchSize || this.calculateOptimalFetchSize(obj.sql);\r\n\r\n return new Promise((resolve, reject) => {\r\n let isResolved = false;\r\n\r\n const cleanup = () => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n }\r\n };\r\n\r\n stream.on(\"error\", (err: any) => {\r\n cleanup();\r\n reject(err);\r\n });\r\n\r\n stream.on(\"end\", () => {\r\n cleanup();\r\n resolve(undefined);\r\n });\r\n\r\n connection.query(\r\n obj.sql,\r\n obj.bindings,\r\n {\r\n cursor: true,\r\n fetchSize: optimizedFetchSize,\r\n },\r\n (error, cursor) => {\r\n if (error) {\r\n if (this.isConnectionError(error)) {\r\n (connection as any).__knex__disposed = error;\r\n }\r\n this.printError(this.safeStringify(error, 2));\r\n cleanup();\r\n reject(error);\r\n return;\r\n }\r\n\r\n const readableStream = this._createCursorStream(cursor);\r\n readableStream.on(\"error\", (err) => {\r\n if (this.isConnectionError(err)) {\r\n (connection as any).__knex__disposed = err;\r\n }\r\n cleanup();\r\n reject(err);\r\n });\r\n readableStream.pipe(stream);\r\n },\r\n );\r\n });\r\n }\r\n\r\n private calculateOptimalFetchSize(sql: string): number {\r\n const hasJoins = /\\s+join\\s+/i.test(sql);\r\n const hasAggregates = /\\s+(count|sum|avg|max|min)\\s*\\(/i.test(sql);\r\n const hasOrderBy = /\\s+order\\s+by\\s+/i.test(sql);\r\n const hasGroupBy = /\\s+group\\s+by\\s+/i.test(sql);\r\n\r\n // For complex analytical queries, use larger fetch sizes\r\n if (hasJoins || hasAggregates || hasOrderBy || hasGroupBy) {\r\n return 500;\r\n }\r\n\r\n // For simple queries, use moderate fetch size\r\n return 100;\r\n }\r\n\r\n private _createCursorStream(cursor: any): Readable {\r\n const parentThis = this;\r\n let isClosed = false;\r\n\r\n return new Readable({\r\n objectMode: true,\r\n read() {\r\n if (isClosed) return;\r\n\r\n cursor.fetch((error: unknown, result: unknown) => {\r\n if (error) {\r\n parentThis.printError(parentThis.safeStringify(error, 2));\r\n isClosed = true;\r\n this.emit(\"error\", error);\r\n return;\r\n }\r\n\r\n if (!cursor.noData) {\r\n this.push(parentThis.maybeNormalizeBigint(result));\r\n } else {\r\n isClosed = true;\r\n cursor.close((closeError: unknown) => {\r\n if (closeError) {\r\n parentThis.printError(parentThis.safeStringify(closeError, 2));\r\n }\r\n if (result) {\r\n this.push(parentThis.maybeNormalizeBigint(result));\r\n }\r\n this.push(null); // End the stream\r\n });\r\n }\r\n });\r\n },\r\n destroy(err, callback) {\r\n if (!isClosed) {\r\n isClosed = true;\r\n cursor.close((closeError: unknown) => {\r\n if (closeError) {\r\n parentThis.printDebug(\r\n \"Error closing cursor during destroy: \" +\r\n parentThis.safeStringify(closeError),\r\n );\r\n }\r\n callback(err);\r\n });\r\n } else {\r\n callback(err);\r\n }\r\n },\r\n });\r\n }\r\n\r\n transaction(container: any, config: any, outerTx: any): Knex.Transaction {\r\n return new (Transaction as any)(this, container, config, outerTx);\r\n }\r\n\r\n schemaCompiler(tableBuilder: any) {\r\n return new (SchemaCompiler as any)(this, tableBuilder);\r\n }\r\n\r\n tableCompiler(tableBuilder: any) {\r\n return new (TableCompiler as any)(this, tableBuilder);\r\n }\r\n\r\n columnCompiler(tableCompiler: any, columnCompiler: any) {\r\n return new (ColumnCompiler as any)(this, tableCompiler, columnCompiler);\r\n }\r\n\r\n queryCompiler(builder: Knex.QueryBuilder, bindings?: any[]) {\r\n return new (QueryCompiler as any)(this, builder, bindings);\r\n }\r\n\r\n // Create IBM i-specific migration runner that bypasses Knex's problematic locking system\r\n createMigrationRunner(\r\n config?: Partial<\r\n import(\"./migrations/ibmi-migration-runner\").IBMiMigrationConfig\r\n >,\r\n ) {\r\n // Pass the knex instance from the client context\r\n const knexInstance = (this as any).context || (this as any);\r\n return createIBMiMigrationRunner(knexInstance, config);\r\n }\r\n\r\n processResponse(obj: QueryObject | null, runner: any): any {\r\n if (obj === null) return null;\r\n\r\n const { response } = obj;\r\n\r\n // If there's a custom output function, use it directly without validation\r\n // This allows custom queries like hasTable to handle their own response format\r\n if (obj.output) {\r\n try {\r\n const result = obj.output(runner, response);\r\n return result;\r\n } catch (error: any) {\r\n // Enhanced error handling for custom output functions\r\n const wrappedError = this.wrapError(error, \"custom_output\", obj);\r\n this.printError(\r\n `Custom output function failed: ${wrappedError.message}`,\r\n );\r\n if (this.isConnectionError(error)) {\r\n throw new Error(\r\n \"Connection closed during query processing - consider using migrations.disableTransactions: true for DDL operations\",\r\n );\r\n }\r\n throw wrappedError;\r\n }\r\n }\r\n\r\n if (response) {\r\n this.maybeNormalizeBigint(response.rows);\r\n }\r\n\r\n // Only validate for standard SQL methods that expect rows structure\r\n const validationResult = this.validateResponse(obj);\r\n if (validationResult !== null) return validationResult;\r\n\r\n return this.processSqlMethod(obj);\r\n }\r\n\r\n private validateResponse(obj: QueryObject): any {\r\n if (!obj.response) {\r\n this.printDebug(\"response undefined \" + this.safeStringify(obj));\r\n return this.processSqlMethod({\r\n ...obj,\r\n response: { rows: [], rowCount: 0 },\r\n } as QueryObject);\r\n }\r\n\r\n if (!obj.response.rows) {\r\n const usesRowCountOnly =\r\n !obj.select &&\r\n (obj.sqlMethod === SqlMethod.DELETE ||\r\n obj.sqlMethod === SqlMethod.DELETE_ALT ||\r\n obj.sqlMethod === SqlMethod.UPDATE ||\r\n obj.sqlMethod === SqlMethod.COUNTER);\r\n\r\n if (usesRowCountOnly) {\r\n return null;\r\n }\r\n\r\n this.printWarn(\"rows undefined \" + this.safeStringify(obj));\r\n return this.processSqlMethod({\r\n ...obj,\r\n response: {\r\n ...obj.response,\r\n rows: [],\r\n rowCount: obj.response.rowCount ?? 0,\r\n },\r\n } as QueryObject);\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private wrapError(error: any, method: string, queryObject: any): Error {\r\n const context = {\r\n method,\r\n sql: queryObject.sql\r\n ? queryObject.sql.substring(0, 100) + \"...\"\r\n : \"unknown\",\r\n timestamp: new Date().toISOString(),\r\n };\r\n\r\n const contextStr = this.safeStringify(context);\r\n\r\n if (this.isConnectionError(error)) {\r\n return new Error(\r\n `IBM i DB2 connection error during ${method}: ${error.message} | Context: ${contextStr}`,\r\n );\r\n }\r\n\r\n if (this.isTimeoutError(error)) {\r\n return new Error(\r\n `IBM i DB2 timeout during ${method}: ${error.message} | Context: ${contextStr}`,\r\n );\r\n }\r\n\r\n if (this.isSQLError(error)) {\r\n return new Error(\r\n `IBM i DB2 SQL error during ${method}: ${error.message} | Context: ${contextStr}`,\r\n );\r\n }\r\n\r\n // Generic error with context\r\n return new Error(\r\n `IBM i DB2 error during ${method}: ${error.message} | Context: ${contextStr}`,\r\n );\r\n }\r\n\r\n private shouldRetryQuery(queryObject: any, _method: string): boolean {\r\n return (\r\n queryObject.sql?.toLowerCase().includes(\"systables\") ||\r\n queryObject.sql?.toLowerCase().includes(\"knex_migrations\")\r\n );\r\n }\r\n\r\n private async retryQuery(\r\n connection: Connection,\r\n queryObject: any,\r\n method: string,\r\n ): Promise<any> {\r\n this.printDebug(`Retrying ${method} query due to connection error...`);\r\n try {\r\n // Wait a moment and retry the query\r\n await new Promise((resolve) => setTimeout(resolve, 1000));\r\n if (this.isSelectMethod(method)) {\r\n await this.executeSelectQuery(connection, queryObject);\r\n } else {\r\n await this.executeStatementQuery(connection, queryObject);\r\n }\r\n return queryObject;\r\n } catch (retryError: any) {\r\n this.printError(`Retry failed: ${retryError.message}`);\r\n throw this.wrapError(retryError, `${method}_retry`, queryObject);\r\n }\r\n }\r\n\r\n /**\r\n * Extract SQLSTATE from ODBC error if available\r\n */\r\n private getSQLState(error: any): string | null {\r\n // Check for ODBC error format with state property\r\n if (error?.odbcErrors && Array.isArray(error.odbcErrors)) {\r\n for (const odbcErr of error.odbcErrors) {\r\n const state = odbcErr?.state || odbcErr?.SQLSTATE;\r\n if (state) return String(state).toUpperCase();\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n private isConnectionError(error: any): boolean {\r\n const sqlState = this.getSQLState(error);\r\n\r\n // ODBC SQLSTATE codes for connection errors\r\n // 08xxx = Connection exception\r\n if (sqlState) {\r\n return (\r\n sqlState.startsWith(\"08\") || // 08001, 08003, 08007, 08S01, etc.\r\n sqlState === \"40003\" // Transaction rollback due to connection\r\n );\r\n }\r\n\r\n // Fallback to message parsing\r\n const errorMessage = (error.message || String(error)).toLowerCase();\r\n return (\r\n errorMessage.includes(\"connection\") &&\r\n (errorMessage.includes(\"closed\") ||\r\n errorMessage.includes(\"invalid\") ||\r\n errorMessage.includes(\"terminated\") ||\r\n errorMessage.includes(\"not connected\"))\r\n );\r\n }\r\n\r\n private isTimeoutError(error: any): boolean {\r\n const sqlState = this.getSQLState(error);\r\n\r\n // ODBC SQLSTATE codes for timeout errors\r\n if (sqlState) {\r\n return (\r\n sqlState === \"HYT00\" || // Timeout expired\r\n sqlState === \"HYT01\" // Connection timeout expired\r\n );\r\n }\r\n\r\n // Fallback to message parsing\r\n const errorMessage = (error.message || String(error)).toLowerCase();\r\n return (\r\n errorMessage.includes(\"timeout\") || errorMessage.includes(\"timed out\")\r\n );\r\n }\r\n\r\n private isSQLError(error: any): boolean {\r\n const sqlState = this.getSQLState(error);\r\n\r\n // ODBC SQLSTATE codes for SQL errors\r\n if (sqlState) {\r\n return (\r\n sqlState.startsWith(\"42\") || // Syntax error or access violation\r\n sqlState.startsWith(\"22\") || // Data exception\r\n sqlState.startsWith(\"23\") || // Integrity constraint violation\r\n sqlState.startsWith(\"21\") // Cardinality violation\r\n );\r\n }\r\n\r\n // Fallback to message parsing\r\n const errorMessage = (error.message || String(error)).toLowerCase();\r\n return (\r\n errorMessage.includes(\"sql\") ||\r\n errorMessage.includes(\"syntax\") ||\r\n errorMessage.includes(\"table\") ||\r\n errorMessage.includes(\"column\")\r\n );\r\n }\r\n\r\n private processSqlMethod(obj: QueryObject): any {\r\n const rows = obj.response?.rows ?? [];\r\n const rowCount = obj.response?.rowCount;\r\n\r\n switch (obj.sqlMethod) {\r\n case SqlMethod.SELECT:\r\n return rows;\r\n case SqlMethod.PLUCK:\r\n return rows.map(obj.pluck!);\r\n case SqlMethod.FIRST:\r\n return rows[0];\r\n case SqlMethod.INSERT:\r\n return rows;\r\n case SqlMethod.DELETE:\r\n case SqlMethod.DELETE_ALT:\r\n case SqlMethod.UPDATE:\r\n // Align with MySQL: return affected rows as a number for DML\r\n return obj.select ? rows : (rowCount ?? 0);\r\n case SqlMethod.COUNTER:\r\n return rowCount;\r\n default:\r\n return rows;\r\n }\r\n }\r\n}\r\n\r\ninterface DB2PoolConfig {\r\n min?: number;\r\n max?: number;\r\n acquireConnectionTimeout?: number;\r\n}\r\n\r\ninterface DB2ConnectionParams {\r\n // General Properties\r\n DSN?: string;\r\n SIGNON?: 0 | 1 | 2 | 3 | 4;\r\n SSL?: 0 | 1;\r\n\r\n // Server Properties\r\n CMT?: 0 | 1 | 2 | 3 | 4;\r\n CONNTYPE?: 0 | 1 | 2;\r\n DATABASE?: string;\r\n DBQ?: string;\r\n MAXDECPREC?: 31 | 63;\r\n MAXDECSCALE?: number;\r\n MINDIVSCALE?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;\r\n NAM?: 0 | 1;\r\n\r\n // Data Types Properties\r\n DFT?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;\r\n DSP?: 0 | 1 | 2 | 3 | 4;\r\n DEC?: 0 | 1;\r\n DECFLOATERROROPTION?: 0 | 1;\r\n DECFLOATROUNDMODE?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\r\n MAPDECIMALFLOATDESCRIBE?: 1 | 3;\r\n TFT?: 0 | 1 | 2 | 3 | 4;\r\n TSP?: 0 | 1 | 2 | 3;\r\n TSFT?: 0 | 1;\r\n XMLCURIMPPARSE?: 0 | 1;\r\n XMLDECLARATION?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;\r\n\r\n // Package Properties\r\n DFTPKGLIB?: string;\r\n PKG?: string;\r\n XDYNAMIC?: 0 | 1;\r\n\r\n // Performance Properties\r\n BLOCKFETCH?: 0 | 1;\r\n BLOCKSIZE?: number;\r\n COMPRESSION?: 0 | 1;\r\n CONCURRENCY?: 0 | 1;\r\n CURSORSENSITIVITY?: 0 | 1 | 2;\r\n EXTCOLINFO?: 0 | 1;\r\n LAZYCLOSE?: 0 | 1;\r\n MAXFIELDLEN?: number;\r\n PREFETCH?: 0 | 1;\r\n QRYSTGLMT?: number | \"*NOMAX\";\r\n QUERYOPTIMIZEGOAL?: 0 | 1 | 2;\r\n QUERYTIMEOUT?: 0 | 1;\r\n\r\n // Language Properties\r\n LANGUAGEID?:\r\n | \"AFR\"\r\n | \"ARA\"\r\n | \"BEL\"\r\n | \"BGR\"\r\n | \"CAT\"\r\n | \"CHS\"\r\n | \"CHT\"\r\n | \"CSY\"\r\n | \"DAN\"\r\n | \"DES\"\r\n | \"DEU\"\r\n | \"ELL\"\r\n | \"ENA\"\r\n | \"ENB\"\r\n | \"ENG\"\r\n | \"ENP\"\r\n | \"ENU\"\r\n | \"ESP\"\r\n | \"EST\"\r\n | \"FAR\"\r\n | \"FIN\"\r\n | \"FRA\"\r\n | \"FRB\"\r\n | \"FRC\"\r\n | \"FRS\"\r\n | \"GAE\"\r\n | \"HEB\"\r\n | \"HRV\"\r\n | \"HUN\"\r\n | \"ISL\"\r\n | \"ITA\"\r\n | \"ITS\"\r\n | \"JPN\"\r\n | \"KOR\"\r\n | \"LAO\"\r\n | \"LVA\"\r\n | \"LTU\"\r\n | \"MKD\"\r\n | \"NLB\"\r\n | \"NLD\"\r\n | \"NON\"\r\n | \"NOR\"\r\n | \"PLK\"\r\n | \"PTB\"\r\n | \"PTG\"\r\n | \"RMS\"\r\n | \"ROM\"\r\n | \"RUS\"\r\n | \"SKY\"\r\n | \"SLO\"\r\n | \"SQI\"\r\n | \"SRB\"\r\n | \"SRL\"\r\n | \"SVE\"\r\n | \"THA\"\r\n | \"TRK\"\r\n | \"UKR\"\r\n | \"URD\"\r\n | \"VIE\";\r\n SORTTABLE?: string;\r\n SORTTYPE?: 0 | 1 | 2 | 3;\r\n SORTWEIGHT?: 0 | 1;\r\n\r\n // Catalog Properties\r\n CATALOGOPTIONS?: number;\r\n LIBVIEW?: 0 | 1 | 2;\r\n REMARKS?: 0 | 1;\r\n SEARCHPATTERN?: 0 | 1;\r\n\r\n // Conversion Properties\r\n ALLOWUNSCHAR?: 0 | 1;\r\n CCSID?: number;\r\n GRAPHIC?: 0 | 1 | 2 | 3;\r\n HEXPARSEROPT?: 0 | 1;\r\n TRANSLATE?: 0 | 1;\r\n TRIMCHAR?: 0 | 1;\r\n UNICODESQL?: 0 | 1;\r\n XLATEDLL?: string;\r\n XLATEOPT?: number;\r\n\r\n // Diagnostic Properties\r\n QAQQINILIB?: string;\r\n SQDIAGCODE?: string;\r\n TRACE?: number;\r\n\r\n // Other Properties\r\n ALWAYSCALCLEN?: 0 | 1;\r\n ALLOWPROCCALLS?: 0 | 1;\r\n CONCURRENTACCESSRESOLUTION?: 0 | 1 | 2 | 3;\r\n DB2SQLSTATES?: 0 | 1;\r\n DATETIMETOCHAR?: number;\r\n DBCSNoTruncError?: 0 | 1;\r\n DEBUG?: number;\r\n KEEPALIVE?: 0 | 1 | 2;\r\n LOGINTIMEOUT?: number;\r\n TIMEOUT?: number;\r\n TRUEAUTOCOMMIT?: 0 | 1;\r\n NEWPWD?: string;\r\n XALCS?: 0 | 1;\r\n XALOCKTIMEOUT?: number;\r\n XATXNTIMEOUT?: number;\r\n}\r\n\r\ninterface DB2ConnectionConfig {\r\n database: string;\r\n host: string;\r\n port: 8471 | 9471 | number;\r\n user: string;\r\n password: string;\r\n driver: \"IBM i Access ODBC Driver\" | string;\r\n connectionStringParams?: DB2ConnectionParams;\r\n}\r\n\r\nexport interface DB2Config extends Knex.Config {\r\n client: any;\r\n connection: DB2ConnectionConfig;\r\n pool?: DB2PoolConfig;\r\n ibmi?: {\r\n multiRowInsert?: \"auto\" | \"sequential\" | \"disabled\";\r\n sequentialInsertTransactional?: boolean;\r\n preparedStatementCache?: boolean; // Enable per-connection statement caching\r\n preparedStatementCacheSize?: number; // Max cached statements per connection (default: 100)\r\n readUncommitted?: boolean; // Append WITH UR to SELECT queries\r\n normalizeBigintToString?: boolean; // Default: true - converts bigint values to strings for JSON safety\r\n };\r\n}\r\n\r\nexport const DB2Dialect = DB2Client;\r\nexport { IBMiMigrationRunner, createIBMiMigrationRunner };\r\nexport default DB2Client;\r\n","import SchemaCompiler from \"knex/lib/schema/compiler.js\";\r\n\r\nclass IBMiSchemaCompiler extends SchemaCompiler {\r\n // Use type assertion to work around ESM import interface issues\r\n [key: string]: any;\r\n\r\n hasTable(tableName: string) {\r\n const upperName = String(tableName).toUpperCase();\r\n\r\n // Extract schema and table name if qualified\r\n let schemaName: string | null = null;\r\n let actualTableName = upperName;\r\n\r\n if (upperName.includes(\".\")) {\r\n const parts = upperName.split(\".\");\r\n schemaName = parts[0];\r\n actualTableName = parts[1];\r\n }\r\n\r\n // Use schema from the builder if available\r\n const builderSchema = (this.builder as any)._schema;\r\n if (builderSchema) {\r\n schemaName = builderSchema.toUpperCase();\r\n }\r\n\r\n let sql: string;\r\n let bindings: any[];\r\n\r\n if (schemaName) {\r\n sql = `select count(*) as table_count from QSYS2.SYSTABLES where UPPER(TABLE_NAME) = ? AND UPPER(TABLE_SCHEMA) = ?`;\r\n bindings = [actualTableName, schemaName];\r\n } else {\r\n sql = `select count(*) as table_count from QSYS2.SYSTABLES where UPPER(TABLE_NAME) = ?`;\r\n bindings = [actualTableName];\r\n }\r\n\r\n this.pushQuery({\r\n sql,\r\n bindings,\r\n output: (_runner: unknown, resp: unknown) => {\r\n // Handle the response from the ODBC query\r\n // The first parameter is the runner, the second is the actual response\r\n if (!resp) {\r\n return false;\r\n }\r\n\r\n // Check if response is an array with results\r\n if (Array.isArray(resp) && resp.length > 0) {\r\n const firstRow = resp[0];\r\n if (firstRow && typeof firstRow === \"object\") {\r\n // Look for table_count or any count field\r\n const count =\r\n firstRow.table_count ||\r\n firstRow.TABLE_COUNT ||\r\n firstRow.count ||\r\n firstRow.COUNT ||\r\n 0;\r\n return count > 0;\r\n }\r\n }\r\n\r\n // Handle ODBC response format with numeric keys\r\n if (typeof resp === \"object\" && resp !== null) {\r\n const respObj = resp as Record<string, unknown>;\r\n // Check for ODBC array-like response with numeric indices\r\n const keys = Object.keys(respObj);\r\n for (const key of keys) {\r\n if (!isNaN(parseInt(key))) {\r\n const row = respObj[key] as Record<string, unknown> | null;\r\n if (row && typeof row === \"object\") {\r\n const count =\r\n row.table_count ||\r\n row.TABLE_COUNT ||\r\n row.count ||\r\n row.COUNT ||\r\n 0;\r\n return (count as number) > 0;\r\n }\r\n }\r\n }\r\n\r\n // Handle response with rows property\r\n const rowsObj = respObj as { rows?: unknown[] };\r\n if (rowsObj.rows && Array.isArray(rowsObj.rows) && rowsObj.rows.length > 0) {\r\n const firstRow = rowsObj.rows[0] as Record<string, unknown> | null;\r\n if (firstRow && typeof firstRow === \"object\") {\r\n const count =\r\n firstRow.table_count ||\r\n firstRow.TABLE_COUNT ||\r\n firstRow.count ||\r\n firstRow.COUNT ||\r\n 0;\r\n return (count as number) > 0;\r\n }\r\n }\r\n }\r\n\r\n return false;\r\n },\r\n });\r\n }\r\n\r\n toSQL() {\r\n const sequence = (this.builder as any)._sequence as any[];\r\n\r\n for (let i = 0, l = sequence.length; i < l; i++) {\r\n const query = sequence[i];\r\n this[query.method].apply(this, query.args);\r\n }\r\n\r\n return this.sequence;\r\n }\r\n}\r\n\r\nexport default IBMiSchemaCompiler;\r\n","import TableCompiler from \"knex/lib/schema/tablecompiler.js\";\r\n\r\nclass IBMiTableCompiler extends TableCompiler {\r\n // Use type assertion to work around ESM import interface issues\r\n [key: string]: any;\r\n\r\n createQuery(columns: { sql: any[] }, ifNot: any, like: any) {\r\n // Note: IBM i DB2 does not support IF NOT EXISTS syntax directly\r\n // The ifNot parameter should be handled by checking hasTable first\r\n if (ifNot && this.client?.logger?.warn) {\r\n this.client.logger.warn(\r\n \"IBM i DB2: IF NOT EXISTS is not natively supported. Use hasTable() check instead.\",\r\n );\r\n }\r\n\r\n let createStatement = \"\";\r\n\r\n if (like) {\r\n // IBM i DB2 syntax for creating table from existing structure\r\n createStatement = `create table ${this.tableName()} as (select * from ${this.tableNameLike()}) with no data`;\r\n } else {\r\n createStatement =\r\n \"create table \" +\r\n this.tableName() +\r\n (this._formatting ? \" (\\n \" : \" (\") +\r\n columns.sql.join(this._formatting ? \",\\n \" : \", \") +\r\n this._addChecks() +\r\n \")\";\r\n }\r\n\r\n this.pushQuery(createStatement);\r\n\r\n if (this.single.comment) {\r\n this.comment(this.single.comment);\r\n }\r\n\r\n if (like) {\r\n this.addColumns(columns, this.addColumnsPrefix);\r\n }\r\n }\r\n\r\n dropUnique(columns: string[], indexName: any) {\r\n indexName = indexName\r\n ? this.formatter.wrap(indexName)\r\n : this._indexCommand(\"unique\", this.tableNameRaw, columns);\r\n\r\n this.pushQuery(`drop index ${indexName}`);\r\n }\r\n\r\n unique(\r\n columns: string[],\r\n indexName:\r\n | string\r\n | { indexName?: string; deferrable?: string; predicate?: any },\r\n ) {\r\n let deferrable: string = \"\";\r\n let predicate: any;\r\n let finalIndexName: string | undefined;\r\n\r\n if (typeof indexName === \"object\" && indexName !== null) {\r\n deferrable = indexName.deferrable || \"\";\r\n predicate = indexName.predicate;\r\n finalIndexName = indexName.indexName;\r\n } else {\r\n finalIndexName = indexName;\r\n }\r\n\r\n if (deferrable && deferrable !== \"not deferrable\") {\r\n this.client.logger.warn?.(\r\n `IBMi: unique index \\`${finalIndexName}\\` will not be deferrable ${deferrable}.`,\r\n );\r\n }\r\n\r\n const wrappedIndexName = finalIndexName\r\n ? this.formatter.wrap(finalIndexName)\r\n : this._indexCommand(\"unique\", this.tableNameRaw, columns);\r\n columns = this.formatter.columnize(columns);\r\n\r\n const predicateQuery = predicate\r\n ? \" \" + this.client.queryCompiler(predicate).where()\r\n : \"\";\r\n\r\n this.pushQuery(\r\n `create unique index ${wrappedIndexName} on ${this.tableName()} (${columns})${predicateQuery}`,\r\n );\r\n }\r\n\r\n // All of the columns to \"add\" for the query\r\n addColumns(columns: any, prefix: any) {\r\n prefix = prefix || this.addColumnsPrefix;\r\n\r\n if (columns.sql.length > 0) {\r\n const columnSql = columns.sql.map((column: string) => {\r\n return prefix + column;\r\n });\r\n this.pushQuery({\r\n sql:\r\n (this.lowerCase ? \"alter table \" : \"ALTER TABLE \") +\r\n this.tableName() +\r\n \" \" +\r\n columnSql.join(\" \"),\r\n bindings: columns.bindings,\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport default IBMiTableCompiler;\r\n","import ColumnCompiler from \"knex/lib/schema/columncompiler.js\";\r\n\r\nclass IBMiColumnCompiler extends ColumnCompiler {\r\n // Use type assertion to work around ESM import interface issues\r\n [key: string]: any;\r\n\r\n increments(options = { primaryKey: true }) {\r\n return (\r\n \"int not null generated always as identity (start with 1, increment by 1)\" +\r\n (this.tableCompiler._canBeAddPrimaryKey(options) ? \" primary key\" : \"\")\r\n );\r\n }\r\n\r\n // Add more IBM i DB2 specific column types for better support\r\n bigIncrements(options = { primaryKey: true }) {\r\n return (\r\n \"bigint not null generated always as identity (start with 1, increment by 1)\" +\r\n (this.tableCompiler._canBeAddPrimaryKey(options) ? \" primary key\" : \"\")\r\n );\r\n }\r\n\r\n smallIncrements(options = { primaryKey: true }) {\r\n return (\r\n \"smallint not null generated always as identity (start with 1, increment by 1)\" +\r\n (this.tableCompiler._canBeAddPrimaryKey(options) ? \" primary key\" : \"\")\r\n );\r\n }\r\n\r\n varchar(length?: number) {\r\n return length ? `varchar(${length})` : \"varchar(255)\";\r\n }\r\n\r\n char(length?: number) {\r\n return length ? `char(${length})` : \"char(1)\";\r\n }\r\n\r\n text() {\r\n // IBM i DB2 uses CLOB for large text\r\n return \"clob(1M)\";\r\n }\r\n\r\n mediumtext() {\r\n return \"clob(16M)\";\r\n }\r\n\r\n longtext() {\r\n return \"clob(2G)\";\r\n }\r\n\r\n binary(length?: number) {\r\n return length ? `binary(${length})` : \"binary(1)\";\r\n }\r\n\r\n varbinary(length?: number) {\r\n return length ? `varbinary(${length})` : \"varbinary(255)\";\r\n }\r\n\r\n // IBM i DB2 decimal with precision/scale\r\n decimal(precision?: number, scale?: number) {\r\n if (precision && scale) {\r\n return `decimal(${precision}, ${scale})`;\r\n } else if (precision) {\r\n return `decimal(${precision})`;\r\n }\r\n return \"decimal(10, 2)\";\r\n }\r\n\r\n // IBM i DB2 timestamp\r\n // Note: IBM i DB2 does not support TIMESTAMP WITH TIME ZONE\r\n timestamp(options?: any) {\r\n if (options?.useTz && this.client?.logger?.warn) {\r\n this.client.logger.warn(\r\n \"IBM i DB2 does not support TIMESTAMP WITH TIME ZONE. Using plain TIMESTAMP instead.\",\r\n );\r\n }\r\n return \"timestamp\";\r\n }\r\n\r\n datetime(options?: any) {\r\n return this.timestamp(options);\r\n }\r\n\r\n // IBM i DB2 date and time types\r\n date() {\r\n return \"date\";\r\n }\r\n\r\n time() {\r\n return \"time\";\r\n }\r\n\r\n // JSON support (IBM i 7.3+)\r\n // Note: CHECK constraints with column references are not supported in this context\r\n // Users should add validation constraints separately if needed\r\n json() {\r\n return \"clob(16M)\";\r\n }\r\n\r\n jsonb() {\r\n // IBM i doesn't have native JSONB, use CLOB\r\n return \"clob(16M)\";\r\n }\r\n\r\n // UUID support using CHAR(36)\r\n uuid() {\r\n return \"char(36)\";\r\n }\r\n}\r\n\r\nexport default IBMiColumnCompiler;\r\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\";\r\nimport { rawOrFn as rawOrFn_ } from \"knex/lib/formatter/wrappingFormatter.js\";\r\n\r\nclass IBMiQueryCompiler extends QueryCompiler {\r\n // Use type assertion to work around ESM import interface issues\r\n [key: string]: any;\r\n\r\n // Cache for column metadata to improve performance with repeated operations\r\n private columnCache = new Map<string, string[]>();\r\n\r\n // Override select method to add IBM i optimization hints\r\n select() {\r\n let sql = super.select.call(this);\r\n\r\n // Add WITH UR (uncommitted read) if configured\r\n const readUncommitted = this.client?.config?.ibmi?.readUncommitted === true;\r\n if (readUncommitted && typeof sql === \"string\") {\r\n sql = sql + \" WITH UR\";\r\n }\r\n\r\n return sql;\r\n }\r\n\r\n private formatTimestampLocal(date: Date): string {\r\n const pad = (n: number) => String(n).padStart(2, \"0\");\r\n const y = date.getFullYear();\r\n const m = pad(date.getMonth() + 1);\r\n const d = pad(date.getDate());\r\n const hh = pad(date.getHours());\r\n const mm = pad(date.getMinutes());\r\n const ss = pad(date.getSeconds());\r\n return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;\r\n }\r\n insert() {\r\n const insertValues = this.single.insert || [];\r\n const { returning } = this.single;\r\n\r\n // Handle empty insert values\r\n if (this.isEmptyInsertValues(insertValues)) {\r\n if (this.isEmptyObject(insertValues)) {\r\n return this.buildEmptyInsertResult(returning);\r\n }\r\n return \"\";\r\n }\r\n\r\n // Decide multi-row insert strategy (default: allow multi-row single statement)\r\n const ibmiConfig = this.client?.config?.ibmi || {};\r\n const multiRowStrategy = ibmiConfig.multiRowInsert || \"auto\"; // 'auto' | 'sequential' | 'disabled'\r\n\r\n // When disabled, or sequential strategy with >1 rows, fall back to first-row SQL generation here.\r\n // For sequential strategy, execution of all rows is handled at runtime in the client.\r\n const isArrayInsert =\r\n Array.isArray(insertValues) && insertValues.length > 1;\r\n // Keep original values for sequential strategy metadata\r\n const originalValues = isArrayInsert ? insertValues.slice() : insertValues;\r\n const forceSingleRow =\r\n multiRowStrategy === \"disabled\" ||\r\n (multiRowStrategy === \"sequential\" && isArrayInsert);\r\n\r\n // If forcing single row, keep legacy single-row path by trimming to first element\r\n let workingValues: any = insertValues;\r\n if (forceSingleRow && isArrayInsert) {\r\n workingValues = [insertValues[0]];\r\n this.single.insert = workingValues; // mutate for downstream calls\r\n }\r\n\r\n // Get the standard INSERT statement from parent class (will include multi-row SQL if available)\r\n const standardInsert = super.insert();\r\n\r\n // If it's an object with sql property, use that; otherwise use the string directly\r\n const insertSql =\r\n typeof standardInsert === \"object\" && standardInsert.sql\r\n ? standardInsert.sql\r\n : standardInsert;\r\n\r\n // For IBM i, wrap INSERT with FINAL TABLE only when RETURNING is requested\r\n // Multi-row inserts without RETURNING should use plain INSERT for performance\r\n const multiRow = isArrayInsert && !forceSingleRow;\r\n\r\n // If multi-row insert without returning, use plain INSERT (return rowCount only)\r\n if (multiRow && !returning) {\r\n return { sql: insertSql, returning: undefined };\r\n }\r\n\r\n // Warn about potentially large result sets\r\n if (multiRow && returning === \"*\") {\r\n if (this.client?.printWarn) {\r\n this.client.printWarn(\"multi-row insert with returning * may be large\");\r\n }\r\n }\r\n\r\n // Use FINAL TABLE for single-row or when returning is specified\r\n const selectColumns = returning\r\n ? this.formatter.columnize(returning)\r\n : \"IDENTITY_VAL_LOCAL()\";\r\n const sql = `select ${selectColumns} from FINAL TABLE(${insertSql})`;\r\n\r\n // Add metadata for sequential strategy so runtime can execute remaining rows\r\n if (multiRowStrategy === \"sequential\" && isArrayInsert) {\r\n // Build column list using first row keys (sorted to match _prepInsert logic)\r\n const first = originalValues[0];\r\n const columns = Object.keys(first).sort();\r\n return {\r\n sql,\r\n returning: undefined,\r\n _ibmiSequentialInsert: {\r\n columns,\r\n rows: originalValues,\r\n tableName: this.tableName,\r\n returning: returning || null,\r\n identityOnly: !returning,\r\n },\r\n };\r\n }\r\n\r\n return { sql, returning: undefined };\r\n }\r\n\r\n private isEmptyInsertValues(insertValues: any): boolean {\r\n return (\r\n (Array.isArray(insertValues) && insertValues.length === 0) ||\r\n this.isEmptyObject(insertValues)\r\n );\r\n }\r\n\r\n private isEmptyObject(insertValues: any): boolean {\r\n return (\r\n insertValues !== null &&\r\n typeof insertValues === \"object\" &&\r\n !Array.isArray(insertValues) &&\r\n Object.keys(insertValues).length === 0\r\n );\r\n }\r\n\r\n private buildEmptyInsertResult(returning: any): {\r\n sql: string;\r\n returning: any;\r\n } {\r\n const selectColumns = returning\r\n ? this.formatter.columnize(returning)\r\n : \"IDENTITY_VAL_LOCAL()\";\r\n\r\n const returningSql = returning\r\n ? this._returning(\"insert\", returning, undefined) + \" \"\r\n : \"\";\r\n\r\n const insertSql = [\r\n this.with(),\r\n `insert into ${this.tableName}`,\r\n returningSql + this._emptyInsertValue,\r\n ]\r\n .filter(Boolean)\r\n .join(\" \");\r\n\r\n const sql = `select ${selectColumns} from FINAL TABLE(${insertSql})`;\r\n\r\n return { sql, returning };\r\n }\r\n\r\n _buildInsertData(insertValues: string | any[], returningSql: string): string {\r\n const insertData = this._prepInsert(insertValues);\r\n\r\n if (insertData.columns.length > 0) {\r\n const parts: string[] = [];\r\n parts.push(\"(\" + this.formatter.columnize(insertData.columns) + \") \");\r\n if (returningSql) parts.push(returningSql);\r\n parts.push(\"values \");\r\n\r\n const rowsSql: string[] = [];\r\n for (const row of insertData.values) {\r\n const placeholders = row.map(() => \"?\").join(\", \");\r\n rowsSql.push(\"(\" + placeholders + \")\");\r\n }\r\n parts.push(rowsSql.join(\", \"));\r\n return parts.join(\"\");\r\n }\r\n\r\n if (\r\n Array.isArray(insertValues) &&\r\n insertValues.length === 1 &&\r\n insertValues[0]\r\n ) {\r\n return (returningSql || \"\") + this._emptyInsertValue;\r\n }\r\n return \"\";\r\n }\r\n\r\n private generateCacheKey(data: any): string {\r\n // Include table name to prevent cache collisions between tables with same columns\r\n const tablePrefix = this.tableName ? `${this.tableName}:` : \"\";\r\n if (Array.isArray(data) && data.length > 0) {\r\n // Use the keys of the first object as cache key\r\n return (\r\n tablePrefix +\r\n Object.keys(data[0] || {})\r\n .sort()\r\n .join(\"|\")\r\n );\r\n }\r\n if (data && typeof data === \"object\") {\r\n return tablePrefix + Object.keys(data).sort().join(\"|\");\r\n }\r\n return \"\";\r\n }\r\n\r\n _prepInsert(data: any): { columns: any; values: any } {\r\n // Handle timestamps in knex migrations\r\n if (typeof data === \"object\" && data?.migration_time) {\r\n const parsed = new Date(data.migration_time);\r\n if (!isNaN(parsed.getTime())) {\r\n data.migration_time = this.formatTimestampLocal(parsed);\r\n }\r\n }\r\n\r\n const isRaw = rawOrFn_(\r\n data,\r\n undefined,\r\n this.builder,\r\n this.client,\r\n this.bindingsHolder,\r\n );\r\n\r\n if (isRaw) {\r\n return isRaw;\r\n }\r\n\r\n // Normalize data to array format\r\n const dataArray = Array.isArray(data) ? data : data ? [data] : [];\r\n\r\n if (dataArray.length === 0) {\r\n return { columns: [], values: [] };\r\n }\r\n\r\n // Multi-row support: build unified column list from first row, then map all rows\r\n const firstItem = dataArray[0];\r\n if (!firstItem || typeof firstItem !== \"object\") {\r\n return { columns: [], values: [] };\r\n }\r\n\r\n const cacheKey = this.generateCacheKey(firstItem);\r\n let columns: string[];\r\n if (cacheKey && this.columnCache.has(cacheKey)) {\r\n columns = this.columnCache.get(cacheKey)!;\r\n } else {\r\n columns = Object.keys(firstItem).sort();\r\n if (cacheKey && columns.length > 0)\r\n this.columnCache.set(cacheKey, columns);\r\n }\r\n\r\n const values: any[] = [];\r\n for (const item of dataArray) {\r\n if (!item || typeof item !== \"object\") continue;\r\n values.push(columns.map((c) => item[c] ?? undefined));\r\n }\r\n\r\n return { columns, values };\r\n }\r\n\r\n update(): { sql: string; returning: any; _ibmiUpdateReturning?: any } {\r\n const withSQL = this.with();\r\n const updates = this._prepUpdate(this.single.update);\r\n const where = this.where();\r\n const order = this.order();\r\n const limit = this.limit();\r\n const { returning } = this.single;\r\n\r\n // Add IBM i v7r3+ optimization hints for UPDATE\r\n const optimizationHints = \"\";\r\n\r\n // Build the base update statement\r\n const baseUpdateSql = [\r\n withSQL,\r\n `update ${this.single.only ? \"only \" : \"\"}${this.tableName}`,\r\n \"set\",\r\n updates.join(\", \"),\r\n where,\r\n order,\r\n limit,\r\n optimizationHints,\r\n ]\r\n .filter(Boolean)\r\n .join(\" \");\r\n\r\n // Handle returning clause\r\n if (returning) {\r\n // Return the base UPDATE SQL (not FINAL TABLE wrapper)\r\n // The metadata tells the client to execute UPDATE + SELECT separately\r\n // This ensures that .toString() and .toQuery() don't generate invalid FINAL TABLE syntax\r\n const selectColumns = this.formatter.columnize(this.single.returning);\r\n\r\n return {\r\n sql: baseUpdateSql,\r\n returning,\r\n _ibmiUpdateReturning: {\r\n updateSql: baseUpdateSql,\r\n selectColumns,\r\n whereClause: where,\r\n tableName: this.tableName,\r\n setBindingCount: updates\r\n .map((fragment: string) => (fragment.match(/\\?/g) || []).length)\r\n .reduce((sum: number, count: number) => sum + count, 0),\r\n },\r\n };\r\n }\r\n\r\n return { sql: baseUpdateSql, returning };\r\n }\r\n\r\n // Emulate DELETE ... RETURNING by attaching metadata for SELECT + DELETE execution\r\n del(): { sql: string; returning: any; _ibmiDeleteReturning?: any } {\r\n const baseDelete = super.del();\r\n const { returning } = this.single;\r\n if (!returning) {\r\n return { sql: baseDelete as string, returning: undefined };\r\n }\r\n const deleteSql =\r\n typeof baseDelete === \"object\" && (baseDelete as any).sql\r\n ? (baseDelete as any).sql\r\n : baseDelete;\r\n const selectColumns = this.formatter.columnize(returning);\r\n // Return the base DELETE SQL (not FINAL TABLE wrapper)\r\n // The metadata tells the client to execute SELECT + DELETE separately\r\n // This ensures that .toString() and .toQuery() don't generate invalid FINAL TABLE syntax\r\n return {\r\n sql: deleteSql,\r\n returning,\r\n _ibmiDeleteReturning: {\r\n deleteSql,\r\n selectColumns,\r\n whereClause: this.where(),\r\n tableName: this.tableName,\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Handle returning clause for IBMi DB2 queries\r\n * Note: IBMi DB2 has limited support for RETURNING clauses\r\n * @param method - The SQL method (insert, update, delete)\r\n * @param value - The returning value\r\n * @param withTrigger - Trigger support (currently unused)\r\n */\r\n _returning(method: string, value: any, withTrigger: undefined) {\r\n switch (method) {\r\n case \"update\":\r\n case \"insert\":\r\n return value ? `${withTrigger ? \" into #out\" : \"\"}` : \"\";\r\n case \"del\":\r\n return value ? `${withTrigger ? \" into #out\" : \"\"}` : \"\";\r\n case \"rowcount\":\r\n return value ? \"select @@rowcount\" : \"\";\r\n default:\r\n return \"\";\r\n }\r\n }\r\n\r\n columnizeWithPrefix(prefix: string, target: string | string[]) {\r\n const columns = typeof target === \"string\" ? [target] : target;\r\n const parts: string[] = [];\r\n\r\n for (let i = 0; i < columns.length; i++) {\r\n if (i > 0) parts.push(\", \");\r\n parts.push(prefix + this.wrap(columns[i]));\r\n }\r\n\r\n return parts.join(\"\");\r\n }\r\n}\r\n\r\nexport default IBMiQueryCompiler;\r\n","import fs from \"fs\";\r\nimport path from \"path\";\r\nimport { pathToFileURL } from \"url\";\r\nimport { Knex } from \"knex\";\r\n\r\nexport interface IBMiMigrationConfig {\r\n directory: string;\r\n tableName: string;\r\n schemaName?: string;\r\n /**\r\n * Deprecated for runner discovery. Kept for backward compatibility.\r\n * The runner discovers .js/.ts/.mjs/.cjs migrations regardless of this value.\r\n */\r\n extension?: string;\r\n}\r\n\r\nfunction buildTsRuntimeHelpMessage(fileName: string): string {\r\n return (\r\n `TypeScript migration '${fileName}' requires a TypeScript runtime loader. ` +\r\n \"Run with a TS-capable runtime (for example: `node --import tsx`) or precompile migrations to JavaScript.\"\r\n );\r\n}\r\n\r\nexport class IBMiMigrationRunner {\r\n private knex: Knex;\r\n private config: IBMiMigrationConfig;\r\n\r\n constructor(knex: Knex, config?: Partial<IBMiMigrationConfig>) {\r\n this.knex = knex;\r\n\r\n // Default configuration\r\n this.config = {\r\n directory: \"./migrations\",\r\n tableName: \"KNEX_MIGRATIONS\",\r\n schemaName: undefined,\r\n ...config,\r\n };\r\n\r\n if (typeof config?.extension === \"string\") {\r\n console.warn(\r\n \"⚠️ IBMiMigrationRunner config 'extension' is ignored for discovery. \" +\r\n \"The runner always discovers .js/.ts/.mjs/.cjs migration files.\",\r\n );\r\n }\r\n }\r\n\r\n private getFullTableName(): string {\r\n return this.config.schemaName\r\n ? `${this.config.schemaName}.${this.config.tableName}`\r\n : this.config.tableName;\r\n }\r\n\r\n async latest(): Promise<void> {\r\n try {\r\n console.log(\r\n \"🚀 IBM i DB2 Migration Runner - bypassing Knex locking system\",\r\n );\r\n\r\n // Ensure the migration table exists\r\n const tableName = this.getFullTableName();\r\n\r\n const migrationTableExists = await (this.knex as any).schema.hasTable(\r\n tableName,\r\n );\r\n if (!migrationTableExists) {\r\n console.log(`📝 Creating migration table: ${tableName}`);\r\n await (this.knex as any).schema.createTable(tableName, (table: any) => {\r\n table.increments(\"id\").primary();\r\n table.string(\"name\").unique(); // Prevent duplicate migration names\r\n table.integer(\"batch\");\r\n table.timestamp(\"migration_time\");\r\n });\r\n console.log(\"✅ Migration table created\");\r\n }\r\n\r\n // Get completed migrations (IBM i uses uppercase column names)\r\n const completed = await this.knex(tableName).select(\"NAME\").orderBy(\"ID\");\r\n const completedNames = completed.map((c: any) => c.NAME);\r\n console.log(`📋 Found ${completedNames.length} completed migrations`);\r\n\r\n // Get migration files\r\n const migrationFiles = this.getMigrationFiles();\r\n console.log(`📁 Found ${migrationFiles.length} migration files`);\r\n\r\n // Find new migrations to run\r\n const newMigrations = migrationFiles.filter(\r\n (file) => !completedNames.includes(file),\r\n );\r\n\r\n if (newMigrations.length === 0) {\r\n console.log(\"✅ No new migrations to run\");\r\n return;\r\n }\r\n\r\n console.log(`🎯 Running ${newMigrations.length} new migrations:`);\r\n newMigrations.forEach((file) => console.log(` - ${file}`));\r\n\r\n // Get next batch number (IBM i uses uppercase column names)\r\n const batchResult = await this.knex(tableName).max(\"BATCH as max_batch\");\r\n const nextBatch = (batchResult[0]?.max_batch || 0) + 1;\r\n console.log(`📊 Using batch number: ${nextBatch}`);\r\n\r\n // Run each migration\r\n for (const migrationFile of newMigrations) {\r\n console.log(`\\n🔄 Running migration: ${migrationFile}`);\r\n\r\n try {\r\n // Import the migration with cache busting to ensure fresh imports\r\n const migrationPath = this.getMigrationPath(migrationFile);\r\n const fileUrl = pathToFileURL(migrationPath).href;\r\n let migration: any;\r\n try {\r\n const moduleNs = await import(`${fileUrl}?t=${Date.now()}`);\r\n migration = moduleNs.default ?? moduleNs;\r\n } catch (importError: any) {\r\n const isTsMigration = migrationFile.toLowerCase().endsWith(\".ts\");\r\n const message = String(importError?.message || importError || \"\");\r\n if (\r\n isTsMigration &&\r\n (message.includes(\"Unknown file extension\") ||\r\n message.includes(\"Cannot use import statement\") ||\r\n message.includes(\"Unexpected token\"))\r\n ) {\r\n throw new Error(buildTsRuntimeHelpMessage(migrationFile));\r\n }\r\n throw importError;\r\n }\r\n\r\n if (!migration.up || typeof migration.up !== \"function\") {\r\n throw new Error(`Migration ${migrationFile} has no 'up' function`);\r\n }\r\n\r\n // Execute the migration\r\n console.log(` ⚡ Executing migration...`);\r\n await migration.up(this.knex);\r\n\r\n // Record the migration\r\n await this.knex(tableName).insert({\r\n name: migrationFile,\r\n batch: nextBatch,\r\n migration_time: new Date(),\r\n });\r\n\r\n console.log(` ✅ Migration ${migrationFile} completed successfully`);\r\n } catch (error: any) {\r\n console.error(\r\n ` ❌ Migration ${migrationFile} failed:`,\r\n error.message,\r\n );\r\n throw error;\r\n }\r\n }\r\n\r\n console.log(`\\n🎉 All migrations completed successfully!`);\r\n } catch (error: any) {\r\n console.error(\"❌ Migration runner failed:\", error.message);\r\n throw error;\r\n }\r\n }\r\n\r\n async rollback(steps: number = 1): Promise<void> {\r\n try {\r\n console.log(`🔄 Rolling back ${steps} migration batch(es)...`);\r\n\r\n const tableName = this.getFullTableName();\r\n\r\n // Get the last batch(es) to rollback\r\n const batchesToRollback = await this.knex(tableName)\r\n .distinct(\"BATCH\")\r\n .orderBy(\"BATCH\", \"desc\")\r\n .limit(steps);\r\n\r\n if (batchesToRollback.length === 0) {\r\n console.log(\"✅ No migrations to rollback\");\r\n return;\r\n }\r\n\r\n const batchNumbers = batchesToRollback.map((b: any) => b.BATCH);\r\n console.log(`📊 Rolling back batches: ${batchNumbers.join(\", \")}`);\r\n\r\n // Get migrations to rollback\r\n const migrationsToRollback = await this.knex(tableName)\r\n .select(\"NAME\")\r\n .whereIn(\"BATCH\", batchNumbers)\r\n .orderBy(\"ID\", \"desc\");\r\n\r\n console.log(`🎯 Rolling back ${migrationsToRollback.length} migrations:`);\r\n migrationsToRollback.forEach((m: any) => console.log(` - ${m.NAME}`));\r\n\r\n // Rollback each migration\r\n for (const migrationRecord of migrationsToRollback) {\r\n const migrationFile = migrationRecord.NAME;\r\n console.log(`\\n🔄 Rolling back migration: ${migrationFile}`);\r\n\r\n try {\r\n // Import the migration with cache busting to ensure fresh imports\r\n const migrationPath = this.getMigrationPath(migrationFile);\r\n const fileUrl = pathToFileURL(migrationPath).href;\r\n let migration: any;\r\n try {\r\n const moduleNs = await import(`${fileUrl}?t=${Date.now()}`);\r\n migration = moduleNs.default ?? moduleNs;\r\n } catch (importError: any) {\r\n const isTsMigration = migrationFile.toLowerCase().endsWith(\".ts\");\r\n const message = String(importError?.message || importError || \"\");\r\n if (\r\n isTsMigration &&\r\n (message.includes(\"Unknown file extension\") ||\r\n message.includes(\"Cannot use import statement\") ||\r\n message.includes(\"Unexpected token\"))\r\n ) {\r\n throw new Error(buildTsRuntimeHelpMessage(migrationFile));\r\n }\r\n throw importError;\r\n }\r\n\r\n if (migration.down && typeof migration.down === \"function\") {\r\n console.log(` ⚡ Executing rollback...`);\r\n await migration.down(this.knex);\r\n } else {\r\n console.log(\r\n ` ⚠️ Migration ${migrationFile} has no 'down' function, skipping rollback`,\r\n );\r\n }\r\n\r\n // Remove the migration record\r\n await this.knex(tableName).where(\"NAME\", migrationFile).del();\r\n\r\n console.log(\r\n ` ✅ Migration ${migrationFile} rolled back successfully`,\r\n );\r\n } catch (error: any) {\r\n console.error(\r\n ` ❌ Migration ${migrationFile} rollback failed:`,\r\n error.message,\r\n );\r\n throw error;\r\n }\r\n }\r\n\r\n console.log(`\\n🎉 Rollback completed successfully!`);\r\n } catch (error: any) {\r\n console.error(\"❌ Rollback failed:\", error.message);\r\n throw error;\r\n }\r\n }\r\n\r\n async currentVersion(): Promise<string | null> {\r\n try {\r\n const tableName = this.getFullTableName();\r\n\r\n const migrationTableExists = await (this.knex as any).schema.hasTable(\r\n tableName,\r\n );\r\n if (!migrationTableExists) {\r\n return null;\r\n }\r\n\r\n const result = await this.knex(tableName)\r\n .select(\"NAME\")\r\n .orderBy(\"ID\", \"desc\")\r\n .first();\r\n\r\n return result?.NAME || null;\r\n } catch (error: any) {\r\n console.error(\"❌ Error getting current version:\", error.message);\r\n return null;\r\n }\r\n }\r\n\r\n async listExecuted(): Promise<string[]> {\r\n try {\r\n const tableName = this.getFullTableName();\r\n\r\n const migrationTableExists = await (this.knex as any).schema.hasTable(\r\n tableName,\r\n );\r\n if (!migrationTableExists) {\r\n return [];\r\n }\r\n\r\n const completed = await this.knex(tableName).select(\"NAME\").orderBy(\"ID\");\r\n return completed.map((c: any) => c.NAME);\r\n } catch (error: any) {\r\n console.error(\"❌ Error listing executed migrations:\", error.message);\r\n return [];\r\n }\r\n }\r\n\r\n async listPending(): Promise<string[]> {\r\n try {\r\n const allFiles = this.getMigrationFiles();\r\n const executed = await this.listExecuted();\r\n return allFiles.filter((file) => !executed.includes(file));\r\n } catch (error: any) {\r\n console.error(\"❌ Error listing pending migrations:\", error.message);\r\n return [];\r\n }\r\n }\r\n\r\n private getMigrationFiles(): string[] {\r\n const { directory } = this.config;\r\n\r\n if (!fs.existsSync(directory)) {\r\n throw new Error(`Migration directory does not exist: ${directory}`);\r\n }\r\n\r\n // Support multiple extensions by checking for common migration file extensions\r\n const validExtensions = [\"js\", \"ts\", \"mjs\", \"cjs\"];\r\n return fs\r\n .readdirSync(directory)\r\n .filter((file) => validExtensions.some((ext) => file.endsWith(`.${ext}`)))\r\n .sort();\r\n }\r\n\r\n private getMigrationPath(filename: string): string {\r\n return path.resolve(this.config.directory, filename);\r\n }\r\n}\r\n\r\n// Export a factory function for easy instantiation\r\nexport function createIBMiMigrationRunner(\r\n knex: Knex,\r\n config?: Partial<IBMiMigrationConfig>,\r\n): IBMiMigrationRunner {\r\n return new IBMiMigrationRunner(knex, config);\r\n}\r\n"],"mappings":"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","names":["Buffer","knex","Buffer"]}
|
|
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 { Buffer } from \"node:buffer\";\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 as string | undefined;\n if (firstKey !== undefined) {\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 }\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 private normalizeBigintToString: boolean;\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 const ibmiConfig = (config as any)?.ibmi;\n this.normalizeBigintToString =\n ibmiConfig?.normalizeBigintToString !== false;\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 if (connectionConfig.sessionInit) {\n const { currentSchema, currentPath, statements } =\n connectionConfig.sessionInit;\n\n if (currentSchema) {\n await connection.query(`SET CURRENT SCHEMA = ${currentSchema}`);\n }\n\n if (currentPath) {\n await connection.query(`SET CURRENT PATH = ${currentPath}`);\n }\n\n if (statements && statements.length > 0) {\n for (const stmt of statements) {\n await connection.query(stmt);\n }\n }\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 // Knex pool validation hook.\n // If this returns false, Knex/tarn will destroy the resource and create a new one.\n // This is critical for recovering after IBM i restarts / network drops.\n async validateConnection(connection: any): Promise<boolean> {\n try {\n // node-odbc exposes `connected` getter on Connection wrapper\n return Boolean(connection && connection.connected);\n } catch {\n return false;\n }\n }\n\n _getConnectionString(connectionConfig: DB2ConnectionConfig) {\n const userParams = connectionConfig.connectionStringParams || {};\n\n // Use user-provided parameters directly without applying defaults\n // Let the ODBC driver use its own defaults unless explicitly overridden\n //\n // Driver Defaults (for reference):\n // - CMT: 2 (Read uncommitted / *CHG)\n // - TRUEAUTOCOMMIT: 0 (*NONE isolation level)\n // - BLOCKFETCH: 0 (disabled)\n //\n // Reference: https://www.ibm.com/docs/en/i/7.4.0?topic=details-connection-string-keywords\n const connectionStringParams: Record<string, unknown> = { ...userParams };\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 const databasePart = connectionConfig.database\n ? `DATABASE=${connectionConfig.database};`\n : \"\";\n\n return (\n `DRIVER=${connectionConfig.driver};` +\n `SYSTEM=${connectionConfig.host};` +\n `PORT=${connectionConfig.port || 8471};` +\n databasePart +\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 // Mark this connection as unusable so Knex/tarn destroys it.\n // Without this, dead ODBC connections can remain in the pool indefinitely.\n (connection as any).__knex__disposed = error;\n\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 UPDATE + 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 * @warning RACE CONDITION: In concurrent environments, rows may change between\n * the UPDATE and SELECT operations. If another transaction modifies, inserts,\n * or deletes rows matching the WHERE clause between these two statements,\n * the returned results may not accurately reflect what was updated.\n * For strict consistency requirements, consider:\n * - Using serializable transaction isolation level\n * - Implementing optimistic locking at the application level\n * - Avoiding `.returning()` on UPDATE and fetching data separately\n */\n private async executeUpdateReturning(\n connection: Connection,\n obj: any,\n ): Promise<any> {\n const { _ibmiUpdateReturning } = obj;\n const {\n updateSql,\n selectColumns,\n whereClause,\n tableName,\n setBindingCount,\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 inferredSetBindingCount =\n typeof setBindingCount === \"number\"\n ? setBindingCount\n : ((updateSql.split(\" where \")[0].match(/\\?/g) || [])\n .length as number);\n const whereBindings = obj.bindings\n ? obj.bindings.slice(inferredSetBindingCount)\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 } = 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 const normalizedRows = this.maybeNormalizeBigint(rows);\n obj.response = { rows: normalizedRows, rowCount: normalizedRows.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 private shouldNormalizeBigintValues(): boolean {\n return this.normalizeBigintToString;\n }\n\n private maybeNormalizeBigint<T>(value: T): T {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (!this.shouldNormalizeBigintValues()) {\n return value;\n }\n\n return this.normalizeBigintValue(value);\n }\n\n private normalizeBigintValue(\n value: any,\n seen: WeakSet<object> = new WeakSet(),\n ): any {\n if (typeof value === \"bigint\") {\n return value.toString();\n }\n\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n value[i] = this.normalizeBigintValue(value[i], seen);\n }\n return value;\n }\n\n if (value && typeof value === \"object\") {\n if (\n value instanceof Date ||\n Buffer.isBuffer(value) ||\n ArrayBuffer.isView(value)\n ) {\n return value;\n }\n\n const obj = value as Record<string, any>;\n\n if (seen.has(obj)) {\n return value;\n }\n\n seen.add(obj);\n\n for (const key of Object.keys(obj)) {\n obj[key] = this.normalizeBigintValue(obj[key], seen);\n }\n\n return value;\n }\n\n return value;\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 const identityRows = result.map(\n (row: { [x: string]: any }) => row[result.columns[0].name],\n );\n const normalizedIdentityRows = this.maybeNormalizeBigint(identityRows);\n return {\n rows: normalizedIdentityRows,\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: this.maybeNormalizeBigint(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 if (this.isConnectionError(error)) {\n (connection as any).__knex__disposed = error;\n }\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 if (this.isConnectionError(err)) {\n (connection as any).__knex__disposed = err;\n }\n cleanup();\n reject(err);\n });\n readableStream.pipe(stream);\n },\n );\n });\n }\n\n private calculateOptimalFetchSize(sql: string): number {\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(parentThis.maybeNormalizeBigint(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(parentThis.maybeNormalizeBigint(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 if (response) {\n this.maybeNormalizeBigint(response.rows);\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 this.processSqlMethod({\n ...obj,\n response: { rows: [], rowCount: 0 },\n } as QueryObject);\n }\n\n if (!obj.response.rows) {\n const usesRowCountOnly =\n !obj.select &&\n (obj.sqlMethod === SqlMethod.DELETE ||\n obj.sqlMethod === SqlMethod.DELETE_ALT ||\n obj.sqlMethod === SqlMethod.UPDATE ||\n obj.sqlMethod === SqlMethod.COUNTER);\n\n if (usesRowCountOnly) {\n return null;\n }\n\n this.printWarn(\"rows undefined \" + this.safeStringify(obj));\n return this.processSqlMethod({\n ...obj,\n response: {\n ...obj.response,\n rows: [],\n rowCount: obj.response.rowCount ?? 0,\n },\n } as QueryObject);\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 throw this.wrapError(retryError, `${method}_retry`, 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 = (error.message || String(error)).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 = (error.message || String(error)).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 = (error.message || String(error)).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 = obj.response?.rows ?? [];\n const rowCount = obj.response?.rowCount;\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?: number;\n user: string;\n password: string;\n driver: \"IBM i Access ODBC Driver\" | string;\n connectionStringParams?: DB2ConnectionParams;\n sessionInit?: {\n currentSchema?: string;\n currentPath?: string;\n statements?: string[];\n };\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 normalizeBigintToString?: boolean; // Default: true - converts bigint values to strings for JSON safety\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: unknown, resp: unknown) => {\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 const respObj = resp as Record<string, unknown>;\n // Check for ODBC array-like response with numeric indices\n const keys = Object.keys(respObj);\n for (const key of keys) {\n if (!isNaN(parseInt(key))) {\n const row = respObj[key] as Record<string, unknown> | null;\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 as number) > 0;\n }\n }\n }\n\n // Handle response with rows property\n const rowsObj = respObj as { rows?: unknown[] };\n if (\n rowsObj.rows &&\n Array.isArray(rowsObj.rows) &&\n rowsObj.rows.length > 0\n ) {\n const firstRow = rowsObj.rows[0] as Record<string, unknown> | null;\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 as number) > 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\nexport default IBMiSchemaCompiler;\n","import TableCompiler from \"knex/lib/schema/tablecompiler.js\";\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: string) => {\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\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 smallIncrements(options = { primaryKey: true }) {\n return (\n \"smallint 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 SQL generation here.\n // For sequential strategy, execution of all rows is handled at runtime in the client.\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 // Include table name to prevent cache collisions between tables with same columns\n const tablePrefix = this.tableName ? `${this.tableName}:` : \"\";\n if (Array.isArray(data) && data.length > 0) {\n // Use the keys of the first object as cache key\n return (\n tablePrefix +\n Object.keys(data[0] || {})\n .sort()\n .join(\"|\")\n );\n }\n if (data && typeof data === \"object\") {\n return tablePrefix + Object.keys(data).sort().join(\"|\");\n }\n return \"\";\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 // Return the base UPDATE SQL (not FINAL TABLE wrapper)\n // The metadata tells the client to execute UPDATE + SELECT separately\n // This ensures that .toString() and .toQuery() don't generate invalid FINAL TABLE syntax\n const selectColumns = this.formatter.columnize(this.single.returning);\n\n return {\n sql: baseUpdateSql,\n returning,\n _ibmiUpdateReturning: {\n updateSql: baseUpdateSql,\n selectColumns,\n whereClause: where,\n tableName: this.tableName,\n setBindingCount: updates\n .map((fragment: string) => (fragment.match(/\\?/g) || []).length)\n .reduce((sum: number, count: number) => sum + count, 0),\n },\n };\n }\n\n return { sql: baseUpdateSql, returning };\n }\n\n // Emulate DELETE ... RETURNING by attaching metadata for SELECT + DELETE execution\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 // Return the base DELETE SQL (not FINAL TABLE wrapper)\n // The metadata tells the client to execute SELECT + DELETE separately\n // This ensures that .toString() and .toQuery() don't generate invalid FINAL TABLE syntax\n return {\n sql: deleteSql,\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 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 { pathToFileURL } from \"url\";\nimport { Knex } from \"knex\";\n\nexport interface IBMiMigrationConfig {\n directory: string;\n tableName: string;\n schemaName?: string;\n /**\n * Deprecated for runner discovery. Kept for backward compatibility.\n * The runner discovers .js/.ts/.mjs/.cjs migrations regardless of this value.\n */\n extension?: string;\n}\n\nfunction buildTsRuntimeHelpMessage(fileName: string): string {\n return (\n `TypeScript migration '${fileName}' requires a TypeScript runtime loader. ` +\n \"Run with a TS-capable runtime (for example: `node --import tsx`) or precompile migrations to JavaScript.\"\n );\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 ...config,\n };\n\n if (typeof config?.extension === \"string\") {\n console.warn(\n \"⚠️ IBMiMigrationRunner config 'extension' is ignored for discovery. \" +\n \"The runner always discovers .js/.ts/.mjs/.cjs migration files.\",\n );\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: any) => {\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 with cache busting to ensure fresh imports\n const migrationPath = this.getMigrationPath(migrationFile);\n const fileUrl = pathToFileURL(migrationPath).href;\n let migration: any;\n try {\n const moduleNs = await import(`${fileUrl}?t=${Date.now()}`);\n migration = moduleNs.default ?? moduleNs;\n } catch (importError: any) {\n const isTsMigration = migrationFile.toLowerCase().endsWith(\".ts\");\n const message = String(importError?.message || importError || \"\");\n if (\n isTsMigration &&\n (message.includes(\"Unknown file extension\") ||\n message.includes(\"Cannot use import statement\") ||\n message.includes(\"Unexpected token\"))\n ) {\n throw new Error(buildTsRuntimeHelpMessage(migrationFile));\n }\n throw importError;\n }\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 with cache busting to ensure fresh imports\n const migrationPath = this.getMigrationPath(migrationFile);\n const fileUrl = pathToFileURL(migrationPath).href;\n let migration: any;\n try {\n const moduleNs = await import(`${fileUrl}?t=${Date.now()}`);\n migration = moduleNs.default ?? moduleNs;\n } catch (importError: any) {\n const isTsMigration = migrationFile.toLowerCase().endsWith(\".ts\");\n const message = String(importError?.message || importError || \"\");\n if (\n isTsMigration &&\n (message.includes(\"Unknown file extension\") ||\n message.includes(\"Cannot use import statement\") ||\n message.includes(\"Unexpected token\"))\n ) {\n throw new Error(buildTsRuntimeHelpMessage(migrationFile));\n }\n throw importError;\n }\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 } = 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 return fs\n .readdirSync(directory)\n .filter((file) => validExtensions.some((ext) => file.endsWith(`.${ext}`)))\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":["Buffer","knex","Buffer"]}
|