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):
"""Return a list of unfinished transaction's IDs."""
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):
"""Return true iff an object specified by a given pair of an
object ID and a transaction ID is present in a database.
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')
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
ID is present. Otherwise, return None. If tid is None and
before_tid is None, the latest revision is taken. If tid is
......@@ -108,7 +101,7 @@ class DatabaseManager(object):
is not finished yet. The list of objects contains tuples,
each of which consists of an object ID, a compression specification,
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."""
raise NotImplementedError('this method must be overridden')
......@@ -116,3 +109,24 @@ class DatabaseManager(object):
"""Finish a transaction specified by a given ID, by moving
temporarily data to a finished area."""
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):
self.db, self.user)
self.conn = MySQLdb.connect(**kwd)
self.conn.autocommit(False)
self.under_transaction = False
def begin(self):
if self.under_transaction:
try:
self.commit()
except:
# Ignore any error for this implicit commit.
pass
self.query("""BEGIN""")
self.under_transaction = True
def commit(self):
self.conn.commit()
self.under_transaction = False
def rollback(self):
self.conn.rollback()
self.under_transaction = False
def query(self, query):
"""Query data from a database."""
......@@ -232,25 +242,6 @@ class MySQLDatabaseManager(DatabaseManager):
tid_set.add((t[0] for t in r))
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):
q = self.query
e = self.escape
......@@ -273,16 +264,20 @@ class MySQLDatabaseManager(DatabaseManager):
oid = e(oid)
if tid is not None:
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))
elif before_tid is not None:
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))
else:
# XXX I want to express "HAVING serial = MAX(serial)", but
# 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)
try:
return r[0]
......@@ -365,3 +360,52 @@ class MySQLDatabaseManager(DatabaseManager):
raise
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