DAL is now a pickeable singleton

This commit is contained in:
mdipierro
2012-09-29 22:33:18 -05:00
parent 662261c590
commit f99a1406bb
3 changed files with 46 additions and 19 deletions
+1 -1
View File
@@ -1 +1 @@
Version 2.0.9 (2012-09-29 20:59:43) dev Version 2.0.9 (2012-09-29 22:33:02) dev
+41 -18
View File
@@ -519,6 +519,8 @@ class ConnectionPool(object):
sql_locker.release() sql_locker.release()
if really: if really:
getattr(instance, 'close')() getattr(instance, 'close')()
if instance.db._singleton_code in thread_local.db_instances:
del thread_local.db_instances[instance.db._singleton_code]
if callable(action): if callable(action):
action(None) action(None)
@@ -6583,15 +6585,23 @@ class DAL(object):
Field('fieldname2')) Field('fieldname2'))
""" """
#def __new__(cls, uri, *args, **kwargs): def __new__(cls, uri='sqlite://dummy.db', *args, **kwargs):
# if not hasattr(thread_local,'db_instances'): if not hasattr(thread_local,'db_instances'):
# thread_local.db_instances = {} thread_local.db_instances = {}
# try: if 'singleton_code' in kwargs:
# return thread_local.db_instances[uri] singleton_code = kwargs['singleton_code']
# except KeyError: del kwargs['singleton_code']
# instance = super(DAL, cls).__new__(cls, uri, *args, **kwargs) else:
# thread_local.db_instances[uri] = instance singleton_code = hashlib.md5(uri).hexdigest()
# return instance try:
db = thread_local.db_instances[singleton_code]
if args or kwargs:
raise RuntimeError, 'Cannot duplicate a Singleton'
except KeyError:
db = super(DAL, cls).__new__(cls, uri, *args, **kwargs)
db._singleton_code = singleton_code
thread_local.db_instances[singleton_code] = db
return db
@staticmethod @staticmethod
def set_folder(folder): def set_folder(folder):
@@ -6673,6 +6683,10 @@ class DAL(object):
:attempts (defaults to 5). Number of times to attempt connecting :attempts (defaults to 5). Number of times to attempt connecting
""" """
if hasattr(self,'_adapter'): return
print 'in init'
if not decode_credentials: if not decode_credentials:
credential_decoder = lambda cred: cred credential_decoder = lambda cred: cred
else: else:
@@ -7136,6 +7150,8 @@ def index():
adapter = self._adapter adapter = self._adapter
if adapter in thread_local.instances: if adapter in thread_local.instances:
thread_local.instances.remove(adapter) thread_local.instances.remove(adapter)
if self._singleton_code in thread_local.db_instances:
del thread_local.db_instances[self._singleton_code]
adapter.close() adapter.close()
def executesql(self, query, placeholders=None, as_dict=False, def executesql(self, query, placeholders=None, as_dict=False,
@@ -7265,6 +7281,14 @@ def index():
self[tablename].import_from_csv_file( self[tablename].import_from_csv_file(
ifile, id_map, null, unique, id_offset, *args, **kwargs) ifile, id_map, null, unique, id_offset, *args, **kwargs)
def DAL_unpickler(uri):
return DAL(uri)
def DAL_pickler(db):
return DAL_unpickler, (db._uri,)
copy_reg.pickle(DAL, DAL_pickler, DAL_unpickler)
class SQLALL(object): class SQLALL(object):
""" """
Helper class providing a comma-separated string having all the field names Helper class providing a comma-separated string having all the field names
@@ -9218,15 +9242,14 @@ class Rows(object):
import gluon.contrib.simplejson as simplejson import gluon.contrib.simplejson as simplejson
return simplejson.dumps(items) return simplejson.dumps(items)
def Rows_unpickler(data): # def Rows_unpickler(data):
return cPickle.loads(data) # return cPickle.loads(data)
#
def Rows_pickler(data): # def Rows_pickler(data):
return Rows_unpickler, \ # return Rows_unpickler, \
(cPickle.dumps(data.as_list(storage_to_dict=False, # (cPickle.dumps(data.as_list(storage_to_dict=False,
datetime_to_str=False)),) # datetime_to_str=False)),)
# copy_reg.pickle(Rows, Rows_pickler, Rows_unpickler)
copy_reg.pickle(Rows, Rows_pickler, Rows_unpickler)
################################################################################ ################################################################################
+4
View File
@@ -448,18 +448,22 @@ class TestMigrations(unittest.TestCase):
db = DAL('sqlite://.storage.db') db = DAL('sqlite://.storage.db')
db.define_table('t', Field('a'), migrate='.storage.table') db.define_table('t', Field('a'), migrate='.storage.table')
db.commit() db.commit()
db.close()
db = DAL('sqlite://.storage.db') db = DAL('sqlite://.storage.db')
db.define_table('t', Field('a'), Field('b'), db.define_table('t', Field('a'), Field('b'),
migrate='.storage.table') migrate='.storage.table')
db.commit() db.commit()
db.close()
db = DAL('sqlite://.storage.db') db = DAL('sqlite://.storage.db')
db.define_table('t', Field('a'), Field('b', 'text'), db.define_table('t', Field('a'), Field('b', 'text'),
migrate='.storage.table') migrate='.storage.table')
db.commit() db.commit()
db.close()
db = DAL('sqlite://.storage.db') db = DAL('sqlite://.storage.db')
db.define_table('t', Field('a'), migrate='.storage.table') db.define_table('t', Field('a'), migrate='.storage.table')
db.t.drop() db.t.drop()
db.commit() db.commit()
db.close()
def tearDown(self): def tearDown(self):
if os.path.exists('.storage.db'): if os.path.exists('.storage.db'):