11import re
2+ import sqlite3
23import time
34from abc import ABC , abstractmethod
45from typing import Optional , Sequence
1112
1213from .errors import DatabaseError
1314
15+ from sqlite3 import Connection as Sqlite3ConnectionRaw
16+ from sqlite3 import Cursor as Sqlite3CursorRaw
17+
18+
1419
1520class AbstractCursor (ABC ):
1621 @abstractmethod
@@ -286,6 +291,98 @@ def reconnect(self, attempts, delay):
286291 else :
287292 raise DatabaseError (str ("Reconnecting failed." ))
288293
294+ class Sqlite3Cursor (AbstractCursor ):
295+ def __init__ (self , cursor : Sqlite3CursorRaw , * args , ** kwargs ):
296+ self .cursor = cursor
297+
298+ def execute (self , query : str , param_list : Sequence = None ):
299+ try :
300+ if param_list is None :
301+ return self .cursor .execute (query )
302+ else :
303+ return self .cursor .execute (query , param_list )
304+ except sqlite3 .Error as err :
305+ raise DatabaseError (str (err ))
306+
307+ def rowcount (self ):
308+ return self .cursor .rowcount
309+
310+ def lastrowid (self ):
311+ return self .cursor .lastrowid
312+
313+ def description (self ):
314+ return self .cursor .description
315+
316+ def fetchone (self ):
317+ try :
318+ return self .cursor .fetchone ()
319+ except sqlite3 .Error as err :
320+ raise DatabaseError (str (err ))
321+
322+ def fetchall (self ):
323+ try :
324+ return self .cursor .fetchall ()
325+ except sqlite3 .Error as err :
326+ raise DatabaseError (str (err ))
327+
328+ def fetchmany (self , size : int ):
329+ try :
330+ return self .cursor .fetchmany (size )
331+ except sqlite3 .Error as err :
332+ raise DatabaseError (str (err ))
333+
334+ def close (self ):
335+ try :
336+ self .cursor .close ()
337+ except sqlite3 .Error as err :
338+ raise DatabaseError (str (err ))
339+
340+ def __enter__ (self ):
341+ return self
342+
343+ def __exit__ (self , exc_type , exc_val , exc_tb ):
344+ self .cursor .close ()
345+ if exc_type :
346+ print (f"An exception occurred: { exc_val } " )
347+ return False
348+
349+ class Sqlite3Connection (AbstractConnection ):
350+ def __init__ (self , conn : Sqlite3ConnectionRaw ):
351+ self .conn = conn
352+
353+ def cursor (self , * args , ** kwargs ) -> AbstractCursor :
354+ prepared = False
355+ if 'prepared' in kwargs :
356+ prepared = kwargs ['prepared' ]
357+ del kwargs ['prepared' ]
358+ return Sqlite3Cursor (cursor = self .conn .cursor (* args , ** kwargs ))
359+
360+ def close (self ):
361+ self .conn .close ()
362+
363+ def set_autocommit (self , autocommit : bool ):
364+ pass
365+
366+ def start_transaction (self ):
367+ pass
368+
369+ def commit (self ):
370+ try :
371+ self .conn .commit ()
372+ except sqlite3 .Error as err :
373+ raise DatabaseError (str (err ))
374+
375+ def rollback (self ):
376+ try :
377+ self .conn .rollback ()
378+ except sqlite3 .Error as err :
379+ raise DatabaseError (str (err ))
380+
381+ def need_returning_id (self ):
382+ return False
383+
384+ def reconnect (self , attempts , delay ):
385+ pass
289386
290387class ConnectionFactory (ABC ):
291388 @staticmethod
@@ -304,5 +401,10 @@ def get_connection(*args, **kwargs) -> Optional[AbstractConnection]:
304401 ret_conn = PostgreSQLConnection (conn )
305402 ret_conn .__setattr__ ("connect_kwargs" , kwargs )
306403 return ret_conn
404+ elif dbms_name == 'sqlite3' :
405+ db_path = kwargs .get ("db_path" )
406+ conn = sqlite3 .connect (db_path )
407+ ret_conn = Sqlite3Connection (conn )
408+ return ret_conn
307409 else :
308410 raise NotImplementedError (dbms_name )
0 commit comments