Skip to content

Commit 7ceba0d

Browse files
author
Andrey Lebedev
committed
trackers on mysql can be initialised
added mechanism for backends to detect and clear database
1 parent 3031702 commit 7ceba0d

File tree

5 files changed

+70
-19
lines changed

5 files changed

+70
-19
lines changed

CHANGES.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ are given with the most recent entry first.
1212
- cleaning old unused sessions only once per hour, not on every cgi
1313
request. It is greatly improves web interface performance, especially
1414
on trackers under high load
15-
- added mysql backend
15+
- added mysql backend (see doc/mysql.txt for details)
1616
- fixes to CGI form handling
1717
- switch metakit to use "compressed" multilink journal change representation
1818
- fixed bug in metakit unlink journalling

doc/mysql.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,23 @@ Note, that mysql database should not contain any tables. Tests will not dare to
3838
drop database with data.
3939

4040

41+
Additional configuration
42+
========================
43+
44+
To initialise and use mysql database roundup' configuration file (config.py in
45+
the tracker' home directory) should be appended with the following constants:
46+
47+
MYSQL_DBHOST = 'localhost'
48+
MYSQL_DBUSER = 'rounduptest'
49+
MYSQL_DBPASSWORD = 'rounduptest'
50+
MYSQL_DBNAME = 'rounduptest'
51+
MYSQL_DATABASE = ( MYSQL_DBHOST, MYSQL_DBUSER, MYSQL_DBPASSWORD, MYSQL_DBNAME )
52+
53+
Fill first four constants with real values before running
54+
"roundup-admin initialise".
55+
56+
57+
4158
Andrey Lebedev <[email protected]>
4259

4360

roundup/admin.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1717
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1818
#
19-
# $Id: admin.py,v 1.36 2003-02-06 05:43:47 richard Exp $
19+
# $Id: admin.py,v 1.37 2003-02-15 23:19:01 kedder Exp $
2020

2121
'''Administration commands for maintaining Roundup trackers.
2222
'''
@@ -368,19 +368,31 @@ def do_initialise(self, tracker_home, args):
368368
# make sure the tracker home is installed
369369
if not os.path.exists(tracker_home):
370370
raise UsageError, _('Instance home does not exist')%locals()
371-
if not os.path.exists(os.path.join(tracker_home, 'html')):
371+
try:
372+
tracker = roundup.instance.open(tracker_home)
373+
except roundup.instance.TrackerError:
372374
raise UsageError, _('Instance has not been installed')%locals()
373375

374376
# is there already a database?
375-
if os.path.exists(os.path.join(tracker_home, 'db')):
377+
try:
378+
db_exists = tracker.select_db.Database.exists(tracker.config)
379+
except AttributeError:
380+
# TODO: move this code to exists() static method in every backend
381+
db_exists = os.path.exists(os.path.join(tracker_home, 'db'))
382+
if db_exists:
376383
print _('WARNING: The database is already initialised!')
377384
print _('If you re-initialise it, you will lose all the data!')
378385
ok = raw_input(_('Erase it? Y/[N]: ')).strip()
379386
if ok.lower() != 'y':
380387
return 0
381388

382-
# nuke it
383-
shutil.rmtree(os.path.join(tracker_home, 'db'))
389+
# Get a database backend in use by tracker
390+
try:
391+
# nuke it
392+
tracker.select_db.Database.nuke(tracker.config)
393+
except AttributeError:
394+
# TODO: move this code to nuke() static method in every backend
395+
shutil.rmtree(os.path.join(tracker_home, 'db'))
384396

385397
# GO
386398
init.initialise(tracker_home, adminpw)

roundup/backends/back_mysql.py

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,33 @@
1111
from roundup.backends.rdbms_common import *
1212
from roundup.backends import rdbms_common
1313
import MySQLdb
14+
import os, shutil
1415
from MySQLdb.constants import ER
1516

17+
class Maintenance:
18+
""" Database maintenance functions """
19+
def db_nuke(self, config):
20+
"""Clear all database contents and drop database itself"""
21+
db = Database(config, 'admin')
22+
db.sql("DROP DATABASE %s" % config.MYSQL_DBNAME)
23+
db.sql("CREATE DATABASE %s" % config.MYSQL_DBNAME)
24+
if os.path.exists(config.DATABASE):
25+
shutil.rmtree(config.DATABASE)
26+
27+
def db_exists(self, config):
28+
"""Check if database already exists"""
29+
# Yes, this is a hack, but we must must open connection without
30+
# selecting a database to prevent creation of some tables
31+
config.MYSQL_DATABASE = (config.MYSQL_DBHOST, config.MYSQL_DBUSER, config.MYSQL_DBPASSWORD)
32+
db = Database(config, 'admin')
33+
db.conn.select_db(config.MYSQL_DBNAME)
34+
config.MYSQL_DATABASE = (config.MYSQL_DBHOST, config.MYSQL_DBUSER, config.MYSQL_DBPASSWORD, config.MYSQL_DBNAME)
35+
db.sql("SHOW TABLES")
36+
tables = db.sql_fetchall()
37+
if tables or os.path.exists(config.DATABASE):
38+
return 1
39+
return 0
40+
1641
class Database(Database):
1742
arg = '%s'
1843

@@ -115,6 +140,10 @@ def create_multilink_table(self, spec, ml):
115140
print >>hyperdb.DEBUG, 'create_class', (self, sql)
116141
self.cursor.execute(sql)
117142

143+
# Static methods
144+
nuke = Maintenance().db_nuke
145+
exists = Maintenance().db_exists
146+
118147
class MysqlClass:
119148
def find(self, **propspec):
120149
'''Get the ids of nodes in this class which link to the given nodes.
@@ -174,7 +203,7 @@ def find(self, **propspec):
174203
self.db.sql(query, vals)
175204
l += [x[0] for x in self.db.sql_fetchall()]
176205
if __debug__:
177-
print >>hyperdb.DEBUG, 'find ... ', l #db.sql("DROP DATABASE %s" % config.MYSQL_DBNAME)
206+
print >>hyperdb.DEBUG, 'find ... ', l
178207

179208
# Remove duplicated ids
180209
d = {}
@@ -191,9 +220,4 @@ class IssueClass(MysqlClass, rdbms_common.IssueClass):
191220
class FileClass(MysqlClass, rdbms_common.FileClass):
192221
pass
193222

194-
def nuke(config):
195-
""" Clear all database contents and drop database itself"""
196-
# Connect to db
197-
db = Database(config, 'admin')
198-
db.sql("DROP DATABASE %s" % config.MYSQL_DBNAME)
199-
db.sql("CREATE DATABASE %s" % config.MYSQL_DBNAME)
223+
#vim: set et

test/test_db.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: test_db.py,v 1.70 2003-02-15 14:26:38 kedder Exp $
18+
# $Id: test_db.py,v 1.71 2003-02-15 23:19:01 kedder Exp $
1919

2020
import unittest, os, shutil, time
2121

@@ -738,8 +738,7 @@ def setUp(self):
738738
def tearDown(self):
739739
from roundup.backends import mysql
740740
self.db.close()
741-
mysql.nuke(config)
742-
anydbmDBTestCase.tearDown(self)
741+
mysql.Database.nuke(config)
743742

744743
class mysqlReadOnlyDBTestCase(anydbmReadOnlyDBTestCase):
745744
def setUp(self):
@@ -754,8 +753,7 @@ def setUp(self):
754753
def tearDown(self):
755754
from roundup.backends import mysql
756755
self.db.close()
757-
mysql.nuke(config)
758-
anydbmReadOnlyDBTestCase.tearDown(self)
756+
mysql.Database.nuke(config)
759757

760758
class sqliteDBTestCase(anydbmDBTestCase):
761759
def setUp(self):
@@ -873,7 +871,7 @@ def suite():
873871
if tables:
874872
# Database should be empty. We don't dare to delete any data
875873
raise DatabaseError, "(Database %s contains tables)" % config.MYSQL_DBNAME
876-
db.sql("DROP DATABASE IF EXISTS %s" % config.MYSQL_DBNAME)
874+
db.sql("DROP DATABASE %s" % config.MYSQL_DBNAME)
877875
db.sql("CREATE DATABASE %s" % config.MYSQL_DBNAME)
878876
db.close()
879877
except (MySQLdb.ProgrammingError, DatabaseError), msg:

0 commit comments

Comments
 (0)