summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 73749ea)
raw | patch | inline | side by side (parent: 73749ea)
author | kedder <kedder@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Sat, 8 Feb 2003 15:31:28 +0000 (15:31 +0000) | ||
committer | kedder <kedder@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Sat, 8 Feb 2003 15:31:28 +0000 (15:31 +0000) |
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1493 57a73879-2fb5-44c3-a270-3262357dd7e2
roundup/backends/back_mysql.py | patch | blob | history | |
roundup/backends/rdbms_common.py | patch | blob | history | |
test/test_db.py | patch | blob | history |
index fc7162b0ee7ccf8f42dea6712852570b0afade86..4c9c8af34ea8a3b797f0276e17c5397b9041d90f 100644 (file)
+#
+# Copyright (c) 2003 Martynas Sklyzmantas, Andrey Lebedev
+#
+# This module is free software, and you may redistribute it and/or modify
+# under the same terms as Python, so long as this copyright message and
+# disclaimer are retained in their original form.
+#
+# Mysql backend for roundup
+#
+
from roundup.backends.rdbms_common import *
+from roundup.backends import rdbms_common
import MySQLdb
from MySQLdb.constants import ER
raise DatabaseError, message
self.cursor = self.conn.cursor()
+ # start transaction
+ self.sql("SET AUTOCOMMIT=0")
+ self.sql("BEGIN")
try:
self.database_schema = self.load_dbschema()
except MySQLdb.ProgrammingError, message:
if message[0] != ER.NO_SUCH_TABLE:
raise DatabaseError, message
self.database_schema = {}
- self.cursor.execute("CREATE TABLE schema (schema TEXT)")
- self.cursor.execute("CREATE TABLE ids (name varchar(255), num INT)")
+ self.sql("CREATE TABLE schema (schema TEXT) TYPE=BDB")
+ self.sql("CREATE TABLE ids (name varchar(255), num INT) TYPE=BDB")
def close(self):
try:
def load_dbschema(self):
self.cursor.execute('SELECT schema FROM schema')
- return eval(self.cursor.fetchone()[0])
+ schema = self.cursor.fetchone()
+ if schema:
+ return eval(schema[0])
+ return None
def save_journal(self, classname, cols, nodeid, journaldate,
journaltag, action, params):
cols.append('id')
cols.append('__retired__')
scols = ',' . join(['`%s` VARCHAR(255)'%x for x in cols])
- sql = 'CREATE TABLE `_%s` (%s)'%(spec.classname, scols)
+ sql = 'CREATE TABLE `_%s` (%s) TYPE=BDB'%(spec.classname, scols)
if __debug__:
print >>hyperdb.DEBUG, 'create_class', (self, sql)
self.cursor.execute(sql)
def create_journal_table(self, spec):
cols = ',' . join(['`%s` VARCHAR(255)'%x
for x in 'nodeid date tag action params' . split()])
- sql = 'CREATE TABLE `%s__journal` (%s)'%(spec.classname, cols)
+ sql = 'CREATE TABLE `%s__journal` (%s) TYPE=BDB'%(spec.classname, cols)
if __debug__:
print >>hyperdb.DEBUG, 'create_class', (self, sql)
self.cursor.execute(sql)
def create_multilink_table(self, spec, ml):
sql = '''CREATE TABLE `%s_%s` (linkid VARCHAR(255),
- nodeid VARCHAR(255))'''%(spec.classname, ml)
+ nodeid VARCHAR(255)) TYPE=BDB'''%(spec.classname, ml)
if __debug__:
print >>hyperdb.DEBUG, 'create_class', (self, sql)
self.cursor.execute(sql)
+class MysqlClass:
+ def find(self, **propspec):
+ '''Get the ids of nodes in this class which link to the given nodes.
+
+ Since MySQL < 4.0.0 does not support unions, so we overrideg this
+ method without using this keyword
+
+ '''
+ if __debug__:
+ print >>hyperdb.DEBUG, 'find', (self, propspec)
+
+ # shortcut
+ if not propspec:
+ return []
+
+ # validate the args
+ props = self.getprops()
+ propspec = propspec.items()
+ for propname, nodeids in propspec:
+ # check the prop is OK
+ prop = props[propname]
+ if not isinstance(prop, Link) and not isinstance(prop, Multilink):
+ raise TypeError, "'%s' not a Link/Multilink property"%propname
+
+ # first, links
+ l = []
+ where = []
+ allvalues = ()
+ a = self.db.arg
+ for prop, values in propspec:
+ if not isinstance(props[prop], hyperdb.Link):
+ continue
+ if type(values) is type(''):
+ allvalues += (values,)
+ where.append('_%s = %s'%(prop, a))
+ else:
+ allvalues += tuple(values.keys())
+ where.append('_%s in (%s)'%(prop, ','.join([a]*len(values))))
+ tables = []
+ if where:
+ self.db.sql('select id as nodeid from _%s where %s' % (self.classname, ' and '.join(where)), allvalues)
+ l += [x[0] for x in self.db.sql_fetchall()]
+
+ # now multilinks
+ for prop, values in propspec:
+ vals = ()
+ if not isinstance(props[prop], hyperdb.Multilink):
+ continue
+ if type(values) is type(''):
+ vals = (values,)
+ s = a
+ else:
+ vals = tuple(values.keys())
+ s = ','.join([a]*len(values))
+ query = 'select nodeid from %s_%s where linkid in (%s)'%(
+ self.classname, prop, s)
+ self.db.sql(query, vals)
+ l += [x[0] for x in self.db.sql_fetchall()]
+ if __debug__:
+ print >>hyperdb.DEBUG, 'find ... ', l
+
+ # Remove duplicated ids
+ d = {}
+ for k in l:
+ d[k] = 1
+ return d.keys()
+
+ return l
+
+class Class(MysqlClass, rdbms_common.Class):
+ pass
+class IssueClass(MysqlClass, rdbms_common.IssueClass):
+ pass
+class FileClass(MysqlClass, rdbms_common.FileClass):
+ pass
index 002f5a721fceaac5f8901343d8bca066fa6873e6..3d41cafeafb3e85ea2aa12f4c0f713c92fd96fc0 100644 (file)
-# $Id: rdbms_common.py,v 1.30 2003-02-06 05:43:47 richard Exp $
+# $Id: rdbms_common.py,v 1.31 2003-02-08 15:31:28 kedder Exp $
''' Relational database (SQL) backend common code.
Basics:
p = password.Password()
p.unpack(v)
d[k] = p
+ elif (isinstance(prop, Boolean) or isinstance(prop, Number)) and v is not None:
+ d[k]=float(v)
else:
d[k] = v
return d
diff --git a/test/test_db.py b/test/test_db.py
index 7f2a209f1786b7204659ebb7121b3fd3730a3cbd..5c078bbeb21985d0fdadd0632fbcad3421cd1628 100644 (file)
--- a/test/test_db.py
+++ b/test/test_db.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: test_db.py,v 1.68 2003-01-20 23:03:41 richard Exp $
+# $Id: test_db.py,v 1.69 2003-02-08 15:31:28 kedder Exp $
import unittest, os, shutil, time
config.MYSQL_DATABASE = ('localhost', 'rounduptest', 'rounduptest',
'rounduptest')
os.makedirs(config.DATABASE + '/files')
+ # open database for cleaning
self.db = mysql.Database(config, 'admin')
+ self.db.sql("DROP DATABASE %s" % config.MYSQL_DATABASE[1])
+ self.db.sql("CREATE DATABASE %s" % config.MYSQL_DATABASE[1])
+ self.db.close()
+ # open database for testing
+ self.db = mysql.Database(config, 'admin')
+
setupSchema(self.db, 1, mysql)
class mysqlReadOnlyDBTestCase(anydbmReadOnlyDBTestCase):
config.MYSQL_DATABASE = ('localhost', 'rounduptest', 'rounduptest',
'rounduptest')
os.makedirs(config.DATABASE + '/files')
- db = mysql.Database(config, 'admin')
- setupSchema(db, 1, mysql)
- db.close()
- self.db = sqlite.Database(config)
+ # open database for cleaning
+ self.db = mysql.Database(config, 'admin')
+ self.db.sql("DROP DATABASE %s" % config.MYSQL_DATABASE[1])
+ self.db.sql("CREATE DATABASE %s" % config.MYSQL_DATABASE[1])
+ self.db.close()
+ # open database for testing
+ self.db = mysql.Database(config)
setupSchema(self.db, 0, mysql)
-
class sqliteDBTestCase(anydbmDBTestCase):
def setUp(self):
from roundup.backends import sqlite
setupSchema(self.db, 0, metakit)
def suite():
- l = [
- unittest.makeSuite(anydbmDBTestCase, 'test'),
- unittest.makeSuite(anydbmReadOnlyDBTestCase, 'test')
- ]
+ l = []
+# l = [
+# unittest.makeSuite(anydbmDBTestCase, 'test'),
+# unittest.makeSuite(anydbmReadOnlyDBTestCase, 'test')
+# ]
# return unittest.TestSuite(l)
from roundup import backends
p = []
-# if hasattr(backends, 'mysql'):
-# p.append('mysql')
-# l.append(unittest.makeSuite(mysqlDBTestCase, 'test'))
-# l.append(unittest.makeSuite(mysqlReadOnlyDBTestCase, 'test'))
-# return unittest.TestSuite(l)
+ if hasattr(backends, 'mysql'):
+ p.append('mysql')
+ l.append(unittest.makeSuite(mysqlDBTestCase, 'test'))
+ l.append(unittest.makeSuite(mysqlReadOnlyDBTestCase, 'test'))
+ #return unittest.TestSuite(l)
if hasattr(backends, 'gadfly'):
p.append('gadfly')