5 import datasette.views.base
6 from datasette.tracer import trace
7 from datasette.database import Database
8 from datasette.database import Results
10 from .connectors import ConnectorList
12 connections = threading.local()
15 def patch_datasette():
17 Monkey patching for original Datasette
20 async def table_columns(self, table):
22 return await self.original_table_columns(table)
23 except sqlite3.DatabaseError:
24 return ConnectorList.table_columns(self.path, table)
26 Database.original_table_columns = Database.table_columns
27 Database.table_columns = table_columns
30 async def primary_keys(self, table):
32 return await self.original_primary_keys(table)
33 except sqlite3.DatabaseError:
34 return ConnectorList.primary_keys(self.path, table)
36 Database.original_primary_keys = Database.primary_keys
37 Database.primary_keys = primary_keys
40 async def fts_table(self, table):
42 return await self.original_fts_table(table)
43 except sqlite3.DatabaseError:
44 return ConnectorList.fts_table(self.path, table)
46 Database.original_fts_table = Database.fts_table
47 Database.fts_table = fts_table
50 def connect(self, write=False):
52 # Check if it's a sqlite database
53 conn = self.original_connect(write=write)
54 conn.execute("select name from sqlite_master where type='table'")
56 except sqlite3.DatabaseError:
57 conn = ConnectorList.connect(self.path)
60 Database.original_connect = Database.connect
61 Database.connect = connect
64 async def execute_fn(self, fn):
66 conn = getattr(connections, self.name, None)
69 if isinstance(conn, sqlite3.Connection):
70 self.ds._prepare_connection(conn, self.name)
71 setattr(connections, self.name, conn)
74 return await asyncio.get_event_loop().run_in_executor(
75 self.ds.executor, in_thread
78 Database.original_execute_fn = Database.execute_fn
79 Database.execute_fn = execute_fn