]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-64662: Add virtual table support to sqlite3.Connection.iterdump (#108340)
authorErlend E. Aasland <erlend@python.org>
Sun, 27 Aug 2023 22:18:32 +0000 (00:18 +0200)
committerGitHub <noreply@github.com>
Sun, 27 Aug 2023 22:18:32 +0000 (00:18 +0200)
Co-authored-by: Aviv Palivoda <palaviv@gmail.com>
Doc/whatsnew/3.13.rst
Lib/sqlite3/dump.py
Lib/test/test_sqlite3/test_dump.py
Misc/NEWS.d/next/Library/2023-08-22-22-29-42.gh-issue-64662.jHl_Bt.rst [new file with mode: 0644]

index 4ff12b16d00266b7d1f2fa04726878d9897cf3e5..2770207c7097a54692e2cf9116a6434878dc78ec 100644 (file)
@@ -165,6 +165,9 @@ sqlite3
   object is not :meth:`closed <sqlite3.Connection.close>` explicitly.
   (Contributed by Erlend E. Aasland in :gh:`105539`.)
 
+* Add support for virtual tables to :meth:`sqlite3.Connection.iterdump`.
+  (Contributed by Aviv Palivoda in :gh:`64662`.)
+
 tkinter
 -------
 
index cf73cc33810cb15ff5ccb5cfa191e3c81233f33d..ead3360ce676086c722076d3783fd970a505321b 100644 (file)
@@ -24,6 +24,7 @@ def _iterdump(connection):
     directly but instead called from the Connection method, iterdump().
     """
 
+    writeable_schema = False
     cu = connection.cursor()
     yield('BEGIN TRANSACTION;')
 
@@ -50,13 +51,15 @@ def _iterdump(connection):
             yield('ANALYZE "sqlite_master";')
         elif table_name.startswith('sqlite_'):
             continue
-        # NOTE: Virtual table support not implemented
-        #elif sql.startswith('CREATE VIRTUAL TABLE'):
-        #    qtable = table_name.replace("'", "''")
-        #    yield("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"\
-        #        "VALUES('table','{0}','{0}',0,'{1}');".format(
-        #        qtable,
-        #        sql.replace("''")))
+        elif sql.startswith('CREATE VIRTUAL TABLE'):
+            if not writeable_schema:
+                writeable_schema = True
+                yield('PRAGMA writable_schema=ON;')
+            yield("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
+                  "VALUES('table',{0},{0},0,{1});".format(
+                      _quote_value(table_name),
+                      _quote_value(sql),
+                  ))
         else:
             yield('{0};'.format(sql))
 
@@ -85,6 +88,9 @@ def _iterdump(connection):
     for name, type, sql in schema_res.fetchall():
         yield('{0};'.format(sql))
 
+    if writeable_schema:
+        yield('PRAGMA writable_schema=OFF;')
+
     # gh-79009: Yield statements concerning the sqlite_sequence table at the
     # end of the transaction.
     for row in sqlite_sequence:
index 5f6811fb5cc0a52ac19343aee17c67352224b0c9..3107e1b165d9503f4037443c6b1f382dd273ceb9 100644 (file)
@@ -113,6 +113,26 @@ class DumpTests(MemoryDatabaseMixin, unittest.TestCase):
         got = list(self.cx.iterdump())
         self.assertEqual(expected, got)
 
+    def test_dump_virtual_tables(self):
+        # gh-64662
+        expected = [
+            "BEGIN TRANSACTION;",
+            "PRAGMA writable_schema=ON;",
+            ("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
+             "VALUES('table','test','test',0,'CREATE VIRTUAL TABLE test USING fts4(example)');"),
+            "CREATE TABLE 'test_content'(docid INTEGER PRIMARY KEY, 'c0example');",
+            "CREATE TABLE 'test_docsize'(docid INTEGER PRIMARY KEY, size BLOB);",
+            ("CREATE TABLE 'test_segdir'(level INTEGER,idx INTEGER,start_block INTEGER,"
+             "leaves_end_block INTEGER,end_block INTEGER,root BLOB,PRIMARY KEY(level, idx));"),
+            "CREATE TABLE 'test_segments'(blockid INTEGER PRIMARY KEY, block BLOB);",
+            "CREATE TABLE 'test_stat'(id INTEGER PRIMARY KEY, value BLOB);",
+            "PRAGMA writable_schema=OFF;",
+            "COMMIT;"
+        ]
+        self.cu.execute("CREATE VIRTUAL TABLE test USING fts4(example)")
+        actual = list(self.cx.iterdump())
+        self.assertEqual(expected, actual)
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/Misc/NEWS.d/next/Library/2023-08-22-22-29-42.gh-issue-64662.jHl_Bt.rst b/Misc/NEWS.d/next/Library/2023-08-22-22-29-42.gh-issue-64662.jHl_Bt.rst
new file mode 100644 (file)
index 0000000..3fddc8c
--- /dev/null
@@ -0,0 +1,2 @@
+Add support for virtual tables to :meth:`sqlite3.Connection.iterdump`. Patch
+by Aviv Palivoda.