2013-08-29 14:03:45 +02:00
import threading
import Queue
sqlSubmitQueue = Queue . Queue ( ) #SQLITE3 is so thread-unsafe that they won't even let you call it from different threads using your own locks. SQL objects can only be called from one thread.
sqlReturnQueue = Queue . Queue ( )
sqlLock = threading . Lock ( )
2013-08-27 02:00:30 +02:00
def sqlQuery ( sqlStatement , * args ) :
2013-08-29 14:03:45 +02:00
sqlLock . acquire ( )
sqlSubmitQueue . put ( sqlStatement )
2013-08-27 02:00:30 +02:00
if args == ( ) :
2013-08-29 14:03:45 +02:00
sqlSubmitQueue . put ( ' ' )
2015-11-27 00:37:44 +01:00
elif type ( args [ 0 ] ) in [ list , tuple ] :
sqlSubmitQueue . put ( args [ 0 ] )
2013-08-27 02:00:30 +02:00
else :
2013-08-29 14:03:45 +02:00
sqlSubmitQueue . put ( args )
2013-08-27 02:00:30 +02:00
2016-03-22 17:17:45 +01:00
queryreturn , rowcount = sqlReturnQueue . get ( )
2013-08-29 14:03:45 +02:00
sqlLock . release ( )
2013-08-27 02:00:30 +02:00
return queryreturn
2018-01-25 22:04:38 +01:00
2017-11-30 19:39:31 +01:00
def sqlExecuteChunked ( sqlStatement , idCount , * args ) :
2018-01-25 22:04:38 +01:00
# SQLITE_MAX_VARIABLE_NUMBER,
# unfortunately getting/setting isn't exposed to python
2017-11-30 19:39:31 +01:00
sqlExecuteChunked . chunkSize = 999
if idCount == 0 or idCount > len ( args ) :
return 0
totalRowCount = 0
with sqlLock :
2018-01-25 22:04:38 +01:00
for i in range (
len ( args ) - idCount , len ( args ) ,
sqlExecuteChunked . chunkSize - ( len ( args ) - idCount )
) :
chunk_slice = args [
i : i + sqlExecuteChunked . chunkSize - ( len ( args ) - idCount )
]
sqlSubmitQueue . put (
sqlStatement . format ( ' , ' . join ( ' ? ' * len ( chunk_slice ) ) )
)
2017-11-30 19:39:31 +01:00
# first static args, and then iterative chunk
2018-01-25 22:04:38 +01:00
sqlSubmitQueue . put (
args [ 0 : len ( args ) - idCount ] + chunk_slice
)
2017-11-30 19:39:31 +01:00
retVal = sqlReturnQueue . get ( )
totalRowCount + = retVal [ 1 ]
sqlSubmitQueue . put ( ' commit ' )
return totalRowCount
2018-01-25 22:04:38 +01:00
2013-08-27 02:00:30 +02:00
def sqlExecute ( sqlStatement , * args ) :
2013-08-29 14:03:45 +02:00
sqlLock . acquire ( )
sqlSubmitQueue . put ( sqlStatement )
2013-08-27 02:00:30 +02:00
if args == ( ) :
2013-08-29 14:03:45 +02:00
sqlSubmitQueue . put ( ' ' )
2013-08-27 02:00:30 +02:00
else :
2013-08-29 14:03:45 +02:00
sqlSubmitQueue . put ( args )
2013-08-27 02:00:30 +02:00
2016-03-22 17:17:45 +01:00
queryreturn , rowcount = sqlReturnQueue . get ( )
2013-08-29 14:03:45 +02:00
sqlSubmitQueue . put ( ' commit ' )
sqlLock . release ( )
2016-03-22 17:17:45 +01:00
return rowcount
2013-08-27 02:00:30 +02:00
def sqlStoredProcedure ( procName ) :
2013-08-29 14:03:45 +02:00
sqlLock . acquire ( )
sqlSubmitQueue . put ( procName )
sqlLock . release ( )
2013-08-31 16:40:11 +02:00
class SqlBulkExecute :
def __enter__ ( self ) :
sqlLock . acquire ( )
return self
def __exit__ ( self , type , value , traceback ) :
sqlSubmitQueue . put ( ' commit ' )
sqlLock . release ( )
def execute ( self , sqlStatement , * args ) :
sqlSubmitQueue . put ( sqlStatement )
if args == ( ) :
sqlSubmitQueue . put ( ' ' )
else :
sqlSubmitQueue . put ( args )
sqlReturnQueue . get ( )
def query ( self , sqlStatement , * args ) :
sqlSubmitQueue . put ( sqlStatement )
if args == ( ) :
sqlSubmitQueue . put ( ' ' )
else :
sqlSubmitQueue . put ( args )
return sqlReturnQueue . get ( )