Modified:
branches/unhork/grassyknoll/backend/sql/MysqlCollection.py
branches/unhork/grassyknoll/backend/sql/SqlCollection.py
branches/unhork/grassyknoll/backend/sql/SqliteCollection.py
branches/unhork/grassyknoll/collection/Collection.py
Log:
Issue #161: Refactored some code to allow more sharing in
SqlCollection.py.
Modified: branches/unhork/grassyknoll/backend/sql/MysqlCollection.py
==============================================================================
--- branches/unhork/grassyknoll/backend/sql/MysqlCollection.py (original)
+++ branches/unhork/grassyknoll/backend/sql/MysqlCollection.py Mon Dec 29
09:09:55 2008
@@ -21,7 +21,6 @@
_namesRe = re.compile(r':\w+')
def execute(self, *args, **kwargs):
- print 'Before:', args
if len(args) > 1:
(sql, parameters) = args
if isinstance(parameters, dict):
@@ -32,7 +31,6 @@
new_parameters.append(parameters[name[1:]])
sql = sql.replace(name, self.placeholder, 1)
args = (sql, new_parameters)
- print 'After:', args
return super(MysqlCollection, self).execute(*args, **kwargs)
@classmethod
@@ -44,27 +42,9 @@
passwd=passwd, db=db)
@classmethod
- def _allocate(cls, location):
- assert isinstance(location.table, TableMaker.Table)
- connection = cls.connect(location)
- location.table.create(connection.cursor())
- connection.commit()
-
- @classmethod
- def _deallocate(cls, location):
+ def tableExists(cls, location):
connection = cls.connect(location)
cursor = connection.cursor()
- cursor.execute("""DROP TABLE %s""" % location.table.name)
+ cursor.execute("""SHOW TABLES LIKE '%s'""" % location.table.name)
connection.close()
-
- @classmethod
- def exists(cls, location):
- try:
- connection = cls.connect(location)
- except Exception:
- return False
- else:
- cursor = connection.cursor()
- cursor.execute("""SHOW TABLES LIKE '%s'""" %
location.table.name)
- connection.close()
- return bool(cursor.rowcount)
+ return bool(cursor.rowcount)
Modified: branches/unhork/grassyknoll/backend/sql/SqlCollection.py
==============================================================================
--- branches/unhork/grassyknoll/backend/sql/SqlCollection.py (original)
+++ branches/unhork/grassyknoll/backend/sql/SqlCollection.py Mon Dec 29
09:09:55 2008
@@ -1,4 +1,3 @@
-"""a L{Collection} based on L{sqlite3}"""
from itertools import izip
from functools import wraps
@@ -50,19 +49,36 @@
class SqlCollection(Collection):
placeholder = '?' # Other dbapi unnamed quoting schemes use %s, etc.
- def __init__(self, location, cache_size=None,
- synchronous_writes=None, cached_statements=100):
- """
- @param cache_size: A value to give the SQLite cache_size PRAGMA,
which determines how many disk pages will be held in memory cache.
- @type cache_size: int
-
- @param synchronous_writes: A value to give the SQLite synchronous
PRAGMA, which determines how frequently SQLite will pause to ensure data is
written to disk
- @type synchronous_writes: str, either 'FULL', 'NORMAL', or 'OFF'
-
- @cvar placeholder: A value to be used as a placeholder in unnamed
dbapi quoting.
- @type placeholder: str
- """
- super(SqlCollection, self).__init__(location)
+
+ def __init__(self, location, **kwargs):
+ self.connection = self.connect(location, **kwargs)
+ super(SqlCollection, self).__init__(location, **kwargs)
+
+ @classmethod
+ def exists(cls, location):
+ return super(SqlCollection, cls).exists(location) and
cls.tableExists(location)
+
+ @classmethod
+ def tableExists(cls, location):
+ raise NotImplementedError
+
+ @classmethod
+ def _allocate(cls, location):
+ super(SqlCollection, cls)._allocate(location)
+ assert isinstance(location.table, TableMaker.Table)
+ connection = cls.connect(location)
+ location.table.create(connection.cursor())
+ connection.commit()
+ return connection
+
+ @classmethod
+ def _deallocate(cls, location):
+ connection = cls.connect(location)
+ cursor = connection.cursor()
+ cursor.execute("""DROP TABLE %s""" % location.table.name)
+ connection.commit()
+ connection.close()
+ super(SqlCollection, cls)._deallocate(location)
def cursor(self):
return self.connection.cursor()
Modified: branches/unhork/grassyknoll/backend/sql/SqliteCollection.py
==============================================================================
--- branches/unhork/grassyknoll/backend/sql/SqliteCollection.py (original)
+++ branches/unhork/grassyknoll/backend/sql/SqliteCollection.py Mon Dec 29
09:09:55 2008
@@ -108,7 +108,7 @@
self.connection.commit()
@classmethod
- def connect(cls, location, cached_statements=None):
+ def connect(cls, location, cached_statements=0):
## disable check_same_thread s.t. connections can be used in a
## different thread than they're created. As of sqlite 3.3.1, this
is
## safe. See:
@@ -124,18 +124,21 @@
connection.execute('PRAGMA %s = %s' % (name, value))
@classmethod
- def exists(cls, location):
- return FileBasedCollection.exists(location) and \
- True # XXX: check whether the table exists
+ def tableExists(cls, location):
+ connection = cls.connect(location)
+ cursor = connection.cursor()
+ cursor.execute("""SELECT 1 FROM sqlite_master WHERE name=?""",
[location.table.name])
+ connection.close()
+ return bool(cursor.rowcount)
@classmethod
def _allocate(cls, location, page_size=None):
- assert isinstance(location.table, TableMaker.Table)
- connection = cls.connect(location, 0)
+ super(SqliteCollection, cls)._allocate(location)
if page_size is not None:
+ connection = cls.connect(location)
cls.pragma(connection, 'page_size', page_size)
- location.table.create(connection.cursor())
- connection.commit()
+ connection.commit()
+ connection.close()
@tryCommit
def optimize(self):
Modified: branches/unhork/grassyknoll/collection/Collection.py
==============================================================================
--- branches/unhork/grassyknoll/collection/Collection.py (original)
+++ branches/unhork/grassyknoll/collection/Collection.py Mon Dec 29
09:09:55 2008
@@ -201,7 +201,7 @@
@type location: L{Bunch}
"""
- def __init__(self, location):
+ def __init__(self, location, **kwargs):
"""
Instantiates a collection with the location specified.
@@ -336,7 +336,7 @@
@arg location: See class docstring.
@type location: L{Bunch}
"""
- raise NotImplementedError
+ return True # So it can be called cooperatively.
@classmethod
def _allocate(cls, location):
@@ -356,7 +356,7 @@
@arg location: See class docstring.
@type location: L{Bunch}
"""
- raise NotImplementedError
+ pass #pragma: no cover -- need to pass for cooperative super calls.
class FileBasedCollection(Collection):
"""A convenience subclass of Collection which provides reasonable
classmethods for
@@ -375,10 +375,12 @@
dirpath = os.path.dirname(location.path)
if not os.path.exists(dirpath):
os.makedirs(dirpath)
+ super(FileBasedCollection, cls)._allocate(location)
@classmethod
def _deallocate(cls, location):
os.remove(location.path)
+ super(FileBasedCollection, cls)._deallocate(location)
class DirBasedCollection(Collection):
"""A convenience subclass of Collection which provides reasonable
classmethods for
@@ -388,6 +390,7 @@
@classmethod
def _allocate(cls, location, **kwargs):
os.makedirs(location.path)
+ super(DirBasedCollection, cls)._allocate(location)
@classmethod
def exists(cls, location):
@@ -396,6 +399,7 @@
@classmethod
def _deallocate(cls, location):
shutil.rmtree(location.path)
+ super(DirBasedCollection, cls)._deallocate(location)
class MemoryBasedCollection(Collection):
"""A convenience subclass of Collection which provides reasonable
classmethod stubs
@@ -408,8 +412,8 @@
@classmethod
def _allocate(cls, location):
- pass
+ super(MemoryBasedCollection, cls)._allocate(location)
@classmethod
def _deallocate(cls, location):
- pass #pragma: no cover
+ super(MemoryBasedCollection, cls)._deallocate(location)