Skip to content

Commit d0160c7

Browse files
gh-64662: Add virtual table support to sqlite3.Connection.iterdump (#108340)
Co-authored-by: Aviv Palivoda <[email protected]>
1 parent fecb9fa commit d0160c7

File tree

4 files changed

+38
-7
lines changed

4 files changed

+38
-7
lines changed

Doc/whatsnew/3.13.rst

+3
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ sqlite3
165165
object is not :meth:`closed <sqlite3.Connection.close>` explicitly.
166166
(Contributed by Erlend E. Aasland in :gh:`105539`.)
167167

168+
* Add support for virtual tables to :meth:`sqlite3.Connection.iterdump`.
169+
(Contributed by Aviv Palivoda in :gh:`64662`.)
170+
168171
tkinter
169172
-------
170173

Lib/sqlite3/dump.py

+13-7
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def _iterdump(connection):
2424
directly but instead called from the Connection method, iterdump().
2525
"""
2626

27+
writeable_schema = False
2728
cu = connection.cursor()
2829
yield('BEGIN TRANSACTION;')
2930

@@ -50,13 +51,15 @@ def _iterdump(connection):
5051
yield('ANALYZE "sqlite_master";')
5152
elif table_name.startswith('sqlite_'):
5253
continue
53-
# NOTE: Virtual table support not implemented
54-
#elif sql.startswith('CREATE VIRTUAL TABLE'):
55-
# qtable = table_name.replace("'", "''")
56-
# yield("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"\
57-
# "VALUES('table','{0}','{0}',0,'{1}');".format(
58-
# qtable,
59-
# sql.replace("''")))
54+
elif sql.startswith('CREATE VIRTUAL TABLE'):
55+
if not writeable_schema:
56+
writeable_schema = True
57+
yield('PRAGMA writable_schema=ON;')
58+
yield("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
59+
"VALUES('table',{0},{0},0,{1});".format(
60+
_quote_value(table_name),
61+
_quote_value(sql),
62+
))
6063
else:
6164
yield('{0};'.format(sql))
6265

@@ -85,6 +88,9 @@ def _iterdump(connection):
8588
for name, type, sql in schema_res.fetchall():
8689
yield('{0};'.format(sql))
8790

91+
if writeable_schema:
92+
yield('PRAGMA writable_schema=OFF;')
93+
8894
# gh-79009: Yield statements concerning the sqlite_sequence table at the
8995
# end of the transaction.
9096
for row in sqlite_sequence:

Lib/test/test_sqlite3/test_dump.py

+20
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,26 @@ def __getitem__(self, index):
113113
got = list(self.cx.iterdump())
114114
self.assertEqual(expected, got)
115115

116+
def test_dump_virtual_tables(self):
117+
# gh-64662
118+
expected = [
119+
"BEGIN TRANSACTION;",
120+
"PRAGMA writable_schema=ON;",
121+
("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
122+
"VALUES('table','test','test',0,'CREATE VIRTUAL TABLE test USING fts4(example)');"),
123+
"CREATE TABLE 'test_content'(docid INTEGER PRIMARY KEY, 'c0example');",
124+
"CREATE TABLE 'test_docsize'(docid INTEGER PRIMARY KEY, size BLOB);",
125+
("CREATE TABLE 'test_segdir'(level INTEGER,idx INTEGER,start_block INTEGER,"
126+
"leaves_end_block INTEGER,end_block INTEGER,root BLOB,PRIMARY KEY(level, idx));"),
127+
"CREATE TABLE 'test_segments'(blockid INTEGER PRIMARY KEY, block BLOB);",
128+
"CREATE TABLE 'test_stat'(id INTEGER PRIMARY KEY, value BLOB);",
129+
"PRAGMA writable_schema=OFF;",
130+
"COMMIT;"
131+
]
132+
self.cu.execute("CREATE VIRTUAL TABLE test USING fts4(example)")
133+
actual = list(self.cx.iterdump())
134+
self.assertEqual(expected, actual)
135+
116136

117137
if __name__ == "__main__":
118138
unittest.main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add support for virtual tables to :meth:`sqlite3.Connection.iterdump`. Patch
2+
by Aviv Palivoda.

0 commit comments

Comments
 (0)