Commit f117cdaa authored by Yoshinori Okuji's avatar Yoshinori Okuji

Implement more methods for mysqldb. This should be sufficient.

git-svn-id: https://svn.erp5.org/repos/neo/branches/prototype3@50 71dcc9de-d417-0410-9af5-da40c76e7ee4
parent 0c3b1e65
...@@ -66,22 +66,15 @@ class DatabaseManager(object): ...@@ -66,22 +66,15 @@ class DatabaseManager(object):
"""Return a list of unfinished transaction's IDs.""" """Return a list of unfinished transaction's IDs."""
raise NotImplementedError('this method must be overridden') raise NotImplementedError('this method must be overridden')
def getOIDListByTID(self, tid, all = False):
"""Return a list of the IDs of objects belonging to a given
transaction. If such a transaction does not exist, return
None rather than an empty list. If all is true, the data must
be searched from unfinished transactions as well."""
raise NotImplementedError('this method must be overridden')
def objectPresent(self, oid, tid, all = True): def objectPresent(self, oid, tid, all = True):
"""Return true iff an object specified by a given pair of an """Return true iff an object specified by a given pair of an
object ID and a transaction ID is present in a database. object ID and a transaction ID is present in a database.
Otherwise, return false. If all is true, the object must be Otherwise, return false. If all is true, the object must be
search from unfinished transactions as well.""" searched from unfinished transactions as well."""
raise NotImplementedError('this method must be overridden') raise NotImplementedError('this method must be overridden')
def getObject(self, oid, tid = None, before_tid = None): def getObject(self, oid, tid = None, before_tid = None):
"""Return a tuple of an object ID, a serial, a compression """Return a tuple of a serial, a compression
specification, a checksum, and object data, if a given object specification, a checksum, and object data, if a given object
ID is present. Otherwise, return None. If tid is None and ID is present. Otherwise, return None. If tid is None and
before_tid is None, the latest revision is taken. If tid is before_tid is None, the latest revision is taken. If tid is
...@@ -108,7 +101,7 @@ class DatabaseManager(object): ...@@ -108,7 +101,7 @@ class DatabaseManager(object):
is not finished yet. The list of objects contains tuples, is not finished yet. The list of objects contains tuples,
each of which consists of an object ID, a compression specification, each of which consists of an object ID, a compression specification,
a checksum and object data. The transaction is either None or a checksum and object data. The transaction is either None or
a tuple of the list of oids, user information, a description and a tuple of the list of OIDs, user information, a description and
extension information.""" extension information."""
raise NotImplementedError('this method must be overridden') raise NotImplementedError('this method must be overridden')
...@@ -116,3 +109,24 @@ class DatabaseManager(object): ...@@ -116,3 +109,24 @@ class DatabaseManager(object):
"""Finish a transaction specified by a given ID, by moving """Finish a transaction specified by a given ID, by moving
temporarily data to a finished area.""" temporarily data to a finished area."""
raise NotImplementedError('this method must be overridden') raise NotImplementedError('this method must be overridden')
def deleteTransaction(self, tid, all = False):
"""Delete a transaction specified by a given ID from a temporarily
area. If all is true, it must be deleted even from a finished
area."""
raise NotImplementedError('this method must be overridden')
def getTransaction(self, tid, all = False):
"""Return a tuple of the list of OIDs, user information,
a description, and extension information, for a given transaction
ID. If there is no such transaction ID in a database, return None.
If all is true, the transaction must be searched from a temporary
area as well."""
raise NotImplementedError('this method must be overridden')
def getObjectHistory(self, oid, length = 1):
"""Return a list of serials for a given object ID. The length
specifies the maximum size of such a list. The first serial
must be the last serial, and the list must be sorted in descending
order. If there is no such object ID in a database, return None."""
raise NotImplementedError('this method must be overridden')
...@@ -27,15 +27,25 @@ class MySQLDatabaseManager(DatabaseManager): ...@@ -27,15 +27,25 @@ class MySQLDatabaseManager(DatabaseManager):
self.db, self.user) self.db, self.user)
self.conn = MySQLdb.connect(**kwd) self.conn = MySQLdb.connect(**kwd)
self.conn.autocommit(False) self.conn.autocommit(False)
self.under_transaction = False
def begin(self): def begin(self):
if self.under_transaction:
try:
self.commit()
except:
# Ignore any error for this implicit commit.
pass
self.query("""BEGIN""") self.query("""BEGIN""")
self.under_transaction = True
def commit(self): def commit(self):
self.conn.commit() self.conn.commit()
self.under_transaction = False
def rollback(self): def rollback(self):
self.conn.rollback() self.conn.rollback()
self.under_transaction = False
def query(self, query): def query(self, query):
"""Query data from a database.""" """Query data from a database."""
...@@ -232,25 +242,6 @@ class MySQLDatabaseManager(DatabaseManager): ...@@ -232,25 +242,6 @@ class MySQLDatabaseManager(DatabaseManager):
tid_set.add((t[0] for t in r)) tid_set.add((t[0] for t in r))
return list(tid_set) return list(tid_set)
def getOIDListByTID(self, tid, all = False):
q = self.query
e = self.escape
tid = e(tid)
self.begin()
r = q("""SELECT oids FROM trans WHERE tid = '%s'""" % tid)
if not r and all:
r = q("""SELECT oids FROM ttrans WHERE tid = '%s'""" % tid)
self.commit()
if r:
oids = r[0][0]
if (len(oids) % 8) != 0 or len(oids) == 0:
raise DatabaseFailure('invalid oids for tid %s' % dump(tid))
oid_list = []
for i in xrange(0, len(oids), 8):
oid_list.append(oids[i:i+8])
return oid_list
return None
def objectPresent(self, oid, tid, all = True): def objectPresent(self, oid, tid, all = True):
q = self.query q = self.query
e = self.escape e = self.escape
...@@ -273,16 +264,20 @@ class MySQLDatabaseManager(DatabaseManager): ...@@ -273,16 +264,20 @@ class MySQLDatabaseManager(DatabaseManager):
oid = e(oid) oid = e(oid)
if tid is not None: if tid is not None:
tid = e(tid) tid = e(tid)
r = q("""SELECT * FROM obj WHERE oid = '%s' AND serial = '%s'""" \ r = q("""SELECT serial, compression, checksum, data FROM obj
WHERE oid = '%s' AND serial = '%s'""" \
% (oid, tid)) % (oid, tid))
elif before_tid is not None: elif before_tid is not None:
before_tid = e(before_tid) before_tid = e(before_tid)
r = q("""SELECT * FROM obj WHERE oid = '%s' AND serial < '%s' ORDER BY serial DESC LIMIT 1""" \ r = q("""SELECT serial, compression, checksum, data FROM obj
WHERE oid = '%s' AND serial < '%s'
ORDER BY serial DESC LIMIT 1""" \
% (oid, before_tid)) % (oid, before_tid))
else: else:
# XXX I want to express "HAVING serial = MAX(serial)", but # XXX I want to express "HAVING serial = MAX(serial)", but
# MySQL does not use an index for a HAVING clause! # MySQL does not use an index for a HAVING clause!
r = q("""SELECT * FROM obj WHERE oid = '%s' ORDER BY serial DESC LIMIT 1""" \ r = q("""SELECT serial, compression, checksum, data FROM obj
WHERE oid = '%s' ORDER BY serial DESC LIMIT 1""" \
% oid) % oid)
try: try:
return r[0] return r[0]
...@@ -365,3 +360,52 @@ class MySQLDatabaseManager(DatabaseManager): ...@@ -365,3 +360,52 @@ class MySQLDatabaseManager(DatabaseManager):
raise raise
self.commit() self.commit()
def deleteTransaction(self, tid, all = False):
q = self.query
e = self.escape
tid = e(tid)
self.begin()
try:
q("""DELETE FROM tobj WHERE serial = '%s'""" % tid)
q("""DELETE FROM ttrans WHERE tid = '%s'""" % tid)
if all:
# Note that this can be very slow.
q("""DELETE FROM obj WHERE serial = '%s'""" % tid)
q("""DELETE FROM trans WHERE tid = '%s'""" % tid)
except:
self.rollback()
raise
self.commit()
def getTransaction(self, tid, all = False):
q = self.query
e = self.escape
tid = e(tid)
self.begin()
r = q("""SELECT oids, user, desc, ext FROM trans WHERE tid = '%s'""" \
% tid)
if not r and all:
r = q("""SELECT oids, user, desc, ext FROM ttrans
WHERE tid = '%s'""" \
% tid)
self.commit()
if r:
oids, user, desc, ext = r[0]
if (len(oids) % 8) != 0 or len(oids) == 0:
raise DatabaseFailure('invalid oids for tid %s' % dump(tid))
oid_list = []
for i in xrange(0, len(oids), 8):
oid_list.append(oids[i:i+8])
return oid_list, user, desc, ext
return None
def getObjectHistory(self, oid, length = 1):
q = self.query
e = self.escape
oid = e(oid)
r = q("""SELECT serial FROM obj WHERE oid = '%s'
ORDER BY serial DESC LIMIT %d""" \
% (oid, length))
if r:
return [t[0] for t in r]
return None
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment