Skip to content

Commit d7d8562

Browse files
author
Peng Ren
committed
Add support to list columns and indexes
1 parent 81f9361 commit d7d8562

5 files changed

Lines changed: 285 additions & 9 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"displayName": "SQL For ALL",
44
"publisher": "sql4all",
55
"description": "Query SQL/NoSQL Databases using SQL — backed by SQLAlchemy",
6-
"version": "0.5.2",
6+
"version": "0.5.3",
77
"license": "MIT",
88
"engines": {
99
"vscode": "^1.110.0"
15.4 KB
Binary file not shown.

python/query_executor.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ def parse_arguments():
9696
'query', 'ping',
9797
'list-tables', 'list-views', 'list-materialized-views',
9898
'list-sequences', 'list-temp-tables', 'list-temp-views',
99+
'list-columns', 'list-indexes',
99100
],
100101
help='Action to perform',
101102
)
@@ -254,6 +255,84 @@ def action_list_entities(engine, action, conn=None):
254255
) from e
255256

256257

258+
def action_list_columns(engine, table_name, conn=None):
259+
"""List column details for a table via SQLAlchemy inspect."""
260+
try:
261+
from sqlalchemy import inspect as sa_inspect
262+
inspector = sa_inspect(conn if conn is not None else engine)
263+
columns = inspector.get_columns(table_name)
264+
rows = []
265+
for col in columns:
266+
rows.append({
267+
'column_name': col['name'],
268+
'type': str(col['type']),
269+
'nullable': col.get('nullable', True),
270+
'default': (
271+
str(col['default'])
272+
if col.get('default') is not None
273+
else None
274+
),
275+
'autoincrement': col.get('autoincrement', False),
276+
'primary_key': col.get('primary_key', False),
277+
})
278+
return {
279+
"kind": "result-set",
280+
"rows": rows,
281+
"columns": [
282+
'column_name', 'type', 'nullable',
283+
'default', 'autoincrement', 'primary_key',
284+
],
285+
"rowCount": len(rows),
286+
"message": f"Found {len(rows)} column(s)",
287+
}
288+
except Exception as e:
289+
raise Exception(
290+
f"Failed to list columns: {e}"
291+
) from e
292+
293+
294+
def action_list_indexes(engine, table_name, conn=None):
295+
"""List index details for a table via SQLAlchemy inspect."""
296+
try:
297+
from sqlalchemy import inspect as sa_inspect
298+
inspector = sa_inspect(conn if conn is not None else engine)
299+
# Get regular indexes
300+
indexes = inspector.get_indexes(table_name)
301+
# Get primary key constraint
302+
try:
303+
pk = inspector.get_pk_constraint(table_name)
304+
if pk and pk.get('constrained_columns'):
305+
indexes = [{
306+
'name': pk.get('name') or 'PRIMARY',
307+
'column_names': pk['constrained_columns'],
308+
'unique': True,
309+
'primary_key': True,
310+
}] + indexes
311+
except Exception:
312+
pass
313+
rows = []
314+
for idx in indexes:
315+
rows.append({
316+
'index_name': idx.get('name') or '(unnamed)',
317+
'columns': ', '.join(
318+
str(c) for c in idx.get('column_names', []) if c
319+
),
320+
'unique': idx.get('unique', False),
321+
'primary_key': idx.get('primary_key', False),
322+
})
323+
return {
324+
"kind": "result-set",
325+
"rows": rows,
326+
"columns": ['index_name', 'columns', 'unique', 'primary_key'],
327+
"rowCount": len(rows),
328+
"message": f"Found {len(rows)} index(es)",
329+
}
330+
except Exception as e:
331+
raise Exception(
332+
f"Failed to list indexes: {e}"
333+
) from e
334+
335+
257336
def action_query(engine, sql_query, query_params, conn=None):
258337
"""Execute a SQL query and return results."""
259338
try:
@@ -320,6 +399,14 @@ def dispatch_action(engine, action, query='', params_raw='', conn=None):
320399
result = action_ping(engine)
321400
elif action in ENTITY_ACTIONS:
322401
result = action_list_entities(engine, action, conn)
402+
elif action == 'list-columns':
403+
if not query or not query.strip():
404+
raise ValueError('Table name is required for list-columns.')
405+
result = action_list_columns(engine, query.strip(), conn)
406+
elif action == 'list-indexes':
407+
if not query or not query.strip():
408+
raise ValueError('Table name is required for list-indexes.')
409+
result = action_list_indexes(engine, query.strip(), conn)
323410
elif action == 'query':
324411
if not query or not query.strip():
325412
raise ValueError('Query is empty.')

0 commit comments

Comments
 (0)