Add and improve introspection shortcuts
This commit is contained in:
parent
2beb66a334
commit
04db6ffcb4
1 changed files with 83 additions and 6 deletions
89
src/index.ts
89
src/index.ts
|
@ -8,6 +8,7 @@ import { findUpSync } from 'find-up'
|
|||
interface OraTable {
|
||||
OWNER: string
|
||||
TABLE_NAME: string
|
||||
KIND: 'table' | 'view'
|
||||
}
|
||||
|
||||
interface OraColumn {
|
||||
|
@ -16,6 +17,8 @@ interface OraColumn {
|
|||
COLUMN_NAME: string
|
||||
DATA_TYPE: string
|
||||
DATA_LENGTH: number | null
|
||||
DATA_DEFAULT: string | null
|
||||
IDENTITY_COLUMN: 'YES' | 'NO'
|
||||
NULLABLE: 'Y' | 'N'
|
||||
}
|
||||
|
||||
|
@ -26,13 +29,16 @@ interface Schema {
|
|||
interface Table {
|
||||
owner: string
|
||||
name: string
|
||||
kind: 'table' | 'view'
|
||||
columns: Column[]
|
||||
}
|
||||
|
||||
interface Column {
|
||||
name: string
|
||||
datatype: string
|
||||
identity: boolean
|
||||
nullable: boolean
|
||||
default?: string
|
||||
}
|
||||
|
||||
function getStringParts(str: string, offset: number) {
|
||||
|
@ -134,30 +140,43 @@ async function main() {
|
|||
async function refresh() {
|
||||
const tables = await execute<OraTable>(
|
||||
`
|
||||
select owner, table_name from all_tables
|
||||
union all select owner, view_name table_name from all_views
|
||||
union all select '' owner, table_name from user_tables
|
||||
union all select '' owner, view_name table_name from user_views
|
||||
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
|
||||
`,
|
||||
)
|
||||
|
||||
const columns = await execute<OraColumn>(
|
||||
'select owner, table_name, column_name, data_type, data_length, nullable from all_tab_cols',
|
||||
`
|
||||
select owner, table_name, column_name, data_type, data_length, nullable,
|
||||
data_default, identity_column
|
||||
from all_tab_cols
|
||||
`,
|
||||
)
|
||||
|
||||
const self = await execute<{ USER: string }>('select user from dual')
|
||||
|
||||
schema.tables.length = 0
|
||||
|
||||
for (const table of tables.rows ?? []) {
|
||||
schema.tables.push({
|
||||
owner: table.OWNER ?? '',
|
||||
name: table.TABLE_NAME,
|
||||
kind: table.KIND,
|
||||
columns: (columns.rows ?? [])
|
||||
.filter((col) => col.OWNER === table.OWNER && col.TABLE_NAME === table.TABLE_NAME)
|
||||
.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,
|
||||
})),
|
||||
})
|
||||
}
|
||||
|
@ -181,6 +200,64 @@ async function main() {
|
|||
} else if (query === '\\q') {
|
||||
await connection.close()
|
||||
process.exit(0)
|
||||
} else if (query === '\\r') {
|
||||
await refresh()
|
||||
} else if (query.match(/^\\[dD][tv]?($|\s)/)) {
|
||||
const tables = schema.tables.filter((tab) => {
|
||||
if (query.startsWith('\\dt')) {
|
||||
return tab.kind === 'table' && !tab.owner
|
||||
} else if (query.startsWith('\\dv')) {
|
||||
return tab.kind === 'view' && !tab.owner
|
||||
} else if (query.startsWith('\\Dt')) {
|
||||
return tab.kind === 'table' && tab.owner
|
||||
} else if (query.startsWith('\\Dv')) {
|
||||
return tab.kind === 'view' && tab.owner
|
||||
} else if (query.startsWith('\\d')) {
|
||||
return !tab.owner
|
||||
} else if (query.startsWith('\\D')) {
|
||||
return tab.owner
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
||||
const [_, name] = query.split(/\s+/).map((part) => part.trim())
|
||||
const upper = (name ?? '').toUpperCase()
|
||||
|
||||
console.table(
|
||||
tables.filter((tab) => {
|
||||
const fullName = `${tab.owner}.${tab.name}`
|
||||
return fullName.toUpperCase().includes(upper)
|
||||
}),
|
||||
['owner', 'name', 'kind'],
|
||||
)
|
||||
} else if (query.match(/^\\[dD][tv]?\+?\s+\S+/)) {
|
||||
const [_, name] = query.split(/\s+/).map((part) => part.trim())
|
||||
const upper = name.toUpperCase()
|
||||
|
||||
const table = schema.tables.find((tab) => {
|
||||
if (!tab.owner && (tab.name === name || tab.name === upper)) {
|
||||
return true
|
||||
}
|
||||
|
||||
const fullName = `${tab.owner}.${tab.name}`
|
||||
return fullName === name || fullName === upper
|
||||
})
|
||||
|
||||
if (table) {
|
||||
console.table(
|
||||
table.columns.map((col) => ({
|
||||
name: col.name,
|
||||
type: col.datatype,
|
||||
flags: [col.identity ? 'ID' : '', col.nullable ? '' : 'NOT NULL']
|
||||
.filter(Boolean)
|
||||
.join(' '),
|
||||
default: col.default,
|
||||
})),
|
||||
)
|
||||
} else {
|
||||
console.log('Did not find', name)
|
||||
}
|
||||
} else if (query) {
|
||||
try {
|
||||
const result = await execute(query, [], 1024)
|
||||
|
|
Loading…
Reference in a new issue