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 { | interface OraTable { | ||||||
|   OWNER: string |   OWNER: string | ||||||
|   TABLE_NAME: string |   TABLE_NAME: string | ||||||
|  |   KIND: 'table' | 'view' | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| interface OraColumn { | interface OraColumn { | ||||||
|  | @ -16,6 +17,8 @@ interface OraColumn { | ||||||
|   COLUMN_NAME: string |   COLUMN_NAME: string | ||||||
|   DATA_TYPE: string |   DATA_TYPE: string | ||||||
|   DATA_LENGTH: number | null |   DATA_LENGTH: number | null | ||||||
|  |   DATA_DEFAULT: string | null | ||||||
|  |   IDENTITY_COLUMN: 'YES' | 'NO' | ||||||
|   NULLABLE: 'Y' | 'N' |   NULLABLE: 'Y' | 'N' | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -26,13 +29,16 @@ interface Schema { | ||||||
| interface Table { | interface Table { | ||||||
|   owner: string |   owner: string | ||||||
|   name: string |   name: string | ||||||
|  |   kind: 'table' | 'view' | ||||||
|   columns: Column[] |   columns: Column[] | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| interface Column { | interface Column { | ||||||
|   name: string |   name: string | ||||||
|   datatype: string |   datatype: string | ||||||
|  |   identity: boolean | ||||||
|   nullable: boolean |   nullable: boolean | ||||||
|  |   default?: string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function getStringParts(str: string, offset: number) { | function getStringParts(str: string, offset: number) { | ||||||
|  | @ -134,30 +140,43 @@ async function main() { | ||||||
|   async function refresh() { |   async function refresh() { | ||||||
|     const tables = await execute<OraTable>( |     const tables = await execute<OraTable>( | ||||||
|       ` |       ` | ||||||
|         select owner, table_name from all_tables |         select owner, table_name, 'table' kind from all_tables | ||||||
|         union all select owner, view_name table_name from all_views |         union all select owner, view_name table_name, 'view' from all_views | ||||||
|         union all select '' owner, table_name from user_tables |         union all select '' owner, table_name, 'table' from user_tables | ||||||
|         union all select '' owner, view_name table_name from user_views |         union all select '' owner, view_name table_name, 'view' from user_views | ||||||
|       `,
 |       `,
 | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     const columns = await execute<OraColumn>( |     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 |     schema.tables.length = 0 | ||||||
| 
 | 
 | ||||||
|     for (const table of tables.rows ?? []) { |     for (const table of tables.rows ?? []) { | ||||||
|       schema.tables.push({ |       schema.tables.push({ | ||||||
|         owner: table.OWNER ?? '', |         owner: table.OWNER ?? '', | ||||||
|         name: table.TABLE_NAME, |         name: table.TABLE_NAME, | ||||||
|  |         kind: table.KIND, | ||||||
|         columns: (columns.rows ?? []) |         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) => ({ |           .map((col) => ({ | ||||||
|             name: col.COLUMN_NAME, |             name: col.COLUMN_NAME, | ||||||
|             datatype: |             datatype: | ||||||
|               col.DATA_LENGTH === null ? col.DATA_TYPE : `${col.DATA_TYPE}(${col.DATA_LENGTH})`, |               col.DATA_LENGTH === null ? col.DATA_TYPE : `${col.DATA_TYPE}(${col.DATA_LENGTH})`, | ||||||
|  |             identity: col.IDENTITY_COLUMN === 'YES', | ||||||
|             nullable: col.NULLABLE === 'Y', |             nullable: col.NULLABLE === 'Y', | ||||||
|  |             default: col.DATA_DEFAULT ?? undefined, | ||||||
|           })), |           })), | ||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
|  | @ -181,6 +200,64 @@ async function main() { | ||||||
|     } else if (query === '\\q') { |     } else if (query === '\\q') { | ||||||
|       await connection.close() |       await connection.close() | ||||||
|       process.exit(0) |       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) { |     } else if (query) { | ||||||
|       try { |       try { | ||||||
|         const result = await execute(query, [], 1024) |         const result = await execute(query, [], 1024) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue