From 9429da5346dd36ff876956af215f3052d2455bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Hamal=20Dvo=C5=99=C3=A1k?= Date: Sun, 30 Nov 2025 18:21:12 +0100 Subject: [PATCH] Speed up setup, ignore SIGINT --- package.json | 3 +-- src/index.ts | 76 +++++++++++++++++++++++++++++++--------------------- 2 files changed, 46 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index a45df23..5092a61 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,7 @@ "description": "Command-line Oracle Client", "scripts": { "build": "tsc", - "start": "node dist/index.js", - "dev": "nodemon --exec tsx index.ts" + "start": "node dist/index.js" }, "bin": { "node-oracledb-cli": "dist/index.js" diff --git a/src/index.ts b/src/index.ts index 66290e3..f2cf132 100644 --- a/src/index.ts +++ b/src/index.ts @@ -194,6 +194,7 @@ async function main() { for (const tab of tables) { for (const col of tab.columns) { completions.push(col.name) + completions.push(`${tab.name}.${col.name}`) } } @@ -207,7 +208,7 @@ async function main() { completions.sort() - const suffix = linePartial.match(/[a-zA-Z0-9_.$]*.$/)?.[0] ?? '' + const suffix = linePartial.match(/[a-zA-Z0-9_.$]*$/)?.[0] ?? '' const upper = suffix.toUpperCase() const prefix = linePartial.substring(0, linePartial.length - suffix.length) @@ -243,7 +244,8 @@ async function main() { async function refresh() { const tables = await execute( ` - select owner, table_name, 'table' kind from all_tables + select + owner, table_name, 'table' kind from all_tables union all select owner, view_name table_name, 'view' from all_views union all select '' owner, table_name, 'table' from user_tables union all select '' owner, view_name table_name, 'view' from user_views @@ -281,49 +283,56 @@ async function main() { schema.tables.length = 0 schema.procedures.length = 0 + const colMap = new Map() + + for (const col of columns.rows ?? []) { + const key = `${col.OWNER}|${col.TABLE_NAME}` + if (!colMap.has(key)) colMap.set(key, []) + colMap.get(key).push({ + name: col.COLUMN_NAME, + datatype: + col.DATA_LENGTH === null ? col.DATA_TYPE : `${col.DATA_TYPE}(${col.DATA_LENGTH})`, + identity: col.IDENTITY_COLUMN === 'YES', + nullable: col.NULLABLE === 'Y', + default: col.DATA_DEFAULT ?? undefined, + }) + } + + const argMap = new Map() + + for (const arg of procargs.rows ?? []) { + const key = `${arg.OWNER}|${arg.PACKAGE_NAME}|${arg.OBJECT_NAME}` + if (!argMap.has(key)) argMap.set(key, []) + argMap.get(key).push({ + inout: arg.IN_OUT ?? '?', + datatype: arg.DATA_TYPE, + default: arg.DEFAULTED === 'Y' ? arg.DEFAULT_VALUE : undefined, + }) + } + + const defaultUser = self.rows?.[0]?.USER + for (const table of tables.rows ?? []) { + const owner = table.OWNER || defaultUser + const key = `${owner}|${table.TABLE_NAME}` schema.tables.push({ owner: table.OWNER ?? '', name: table.TABLE_NAME, kind: table.KIND, - columns: (columns.rows ?? []) - .filter( - (col) => - col.OWNER === (table.OWNER || self.rows![0].USER) && - col.TABLE_NAME === table.TABLE_NAME, - ) - .map((col) => ({ - name: col.COLUMN_NAME, - datatype: - col.DATA_LENGTH === null ? col.DATA_TYPE : `${col.DATA_TYPE}(${col.DATA_LENGTH})`, - identity: col.IDENTITY_COLUMN === 'YES', - nullable: col.NULLABLE === 'Y', - default: col.DATA_DEFAULT ?? undefined, - })), + columns: colMap.get(key) ?? [], }) } for (const proc of procedures.rows ?? []) { - if (proc.PROCEDURE_NAME === null) { - continue - } + if (proc.PROCEDURE_NAME === null) continue + const owner = proc.OWNER || defaultUser + const key = `${owner}|${proc.OBJECT_NAME}|${proc.PROCEDURE_NAME}` schema.procedures.push({ owner: proc.OWNER ?? '', package: proc.OBJECT_NAME, name: proc.PROCEDURE_NAME, - arguments: (procargs.rows ?? []) - .filter( - (arg) => - arg.OWNER === (proc.OWNER || self.rows![0].USER) && - arg.PACKAGE_NAME === proc.OBJECT_NAME && - arg.OBJECT_NAME === proc.PROCEDURE_NAME, - ) - .map((arg) => ({ - inout: arg.IN_OUT ?? '?', - datatype: arg.DATA_TYPE, - default: arg.DEFAULTED === 'Y' ? arg.DEFAULT_VALUE : undefined, - })), + arguments: argMap.get(key) ?? [], }) } } @@ -485,6 +494,11 @@ async function main() { rl.prompt() }) + rl.on('SIGINT', () => { + rl.write(null, { ctrl: true, name: 'u' }) + rl.prompt(true) + }) + rl.on('close', async () => { await connection.close()