Skip to content

Commit 3fcc661

Browse files
committed
Add .tables for sqlite3 command-line interface
1 parent e682141 commit 3fcc661

2 files changed

Lines changed: 38 additions & 0 deletions

File tree

Lib/sqlite3/__main__.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,28 @@ def runsource(self, source, filename="<input>", symbol="single"):
6363
# Remember to update CLI_COMMANDS in _completer.py
6464
if source[0] == ".":
6565
match source[1:].strip():
66+
case "tables":
67+
schema_names = tuple(row[1]
68+
for row in self._cur.execute("PRAGMA database_list"))
69+
select_clauses = (f"""SELECT
70+
CASE '{schema}'
71+
WHEN 'main' THEN name
72+
ELSE CONCAT('{schema}.', name)
73+
END
74+
FROM "{schema}".sqlite_master
75+
WHERE type IN ('table', 'view')
76+
AND name NOT LIKE 'sqlite_%'"""
77+
for schema in schema_names
78+
)
79+
command = " UNION ALL ".join(select_clauses) + " ORDER BY 1"
80+
for row in self._cur.execute(command):
81+
print(row[0])
6682
case "version":
6783
print(sqlite3.sqlite_version)
6884
case "help":
6985
t = theme.syntax
7086
print(f"Enter SQL code or one of the below commands, and press enter.\n\n"
87+
f"{t.builtin}.tables{t.reset} List names of tables\n"
7188
f"{t.builtin}.version{t.reset} Print underlying SQLite library version\n"
7289
f"{t.builtin}.help{t.reset} Print this help message\n"
7390
f"{t.builtin}.quit{t.reset} Exit the CLI, equivalent to CTRL-D\n")

Lib/test/test_sqlite3/test_cli.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,27 @@ def test_interact_version(self):
125125
self.assertEqual(out.count(self.PS2), 0)
126126
self.assertIn(sqlite3.sqlite_version, out)
127127

128+
def test_interact_tables(self):
129+
out, err = self.run_cli(commands=(
130+
"CREATE TABLE table_ (id INTEGER);",
131+
"CREATE TEMP TABLE temp_table (id INTEGER);",
132+
"CREATE VIEW view_ AS SELECT * FROM table_;",
133+
"CREATE TEMP VIEW temp_view As SELECT * FROM table_;",
134+
"ATTACH ':memory:' AS attach_;",
135+
"CREATE TABLE attach_.table_ (id INTEGER);",
136+
"CREATE VIEW attach_.view_ AS SELECT * FROM table_;",
137+
"ATTACH ':memory:' AS 123;",
138+
"CREATE TABLE \"123\".table_ (id INTEGER);",
139+
"CREATE VIEW \"123\".view_ AS SELECT * FROM table_;",
140+
".tables",
141+
))
142+
self.assertIn(self.MEMORY_DB_MSG, err)
143+
self.assertEndsWith(out, self.PS1)
144+
self.assertEqual(out.count(self.PS1), 12)
145+
self.assertEqual(out.count(self.PS2), 0)
146+
self.assertIn("123.table_\n123.view_\nattach_.table_\nattach_.view_\n"
147+
"table_\ntemp.temp_table\ntemp.temp_view\nview_\n", out)
148+
128149
def test_interact_empty_source(self):
129150
out, err = self.run_cli(commands=("", " "))
130151
self.assertIn(self.MEMORY_DB_MSG, err)

0 commit comments

Comments
 (0)