summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 65fc5d0)
raw | patch | inline | side by side (parent: 65fc5d0)
| author | kedder <kedder@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
| Sat, 15 Feb 2003 23:19:01 +0000 (23:19 +0000) | ||
| committer | kedder <kedder@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
| Sat, 15 Feb 2003 23:19:01 +0000 (23:19 +0000) |
added mechanism for backends to detect and clear database
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1512 57a73879-2fb5-44c3-a270-3262357dd7e2
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1512 57a73879-2fb5-44c3-a270-3262357dd7e2
diff --git a/CHANGES.txt b/CHANGES.txt
index 45ab7bf5cb70f7564e3710d9c523ba428e58bbcf..e1879208eedd139e138d193863934c0175204d52 100644 (file)
--- a/CHANGES.txt
+++ b/CHANGES.txt
- cleaning old unused sessions only once per hour, not on every cgi
request. It is greatly improves web interface performance, especially
on trackers under high load
-- added mysql backend
+- added mysql backend (see doc/mysql.txt for details)
- fixes to CGI form handling
- switch metakit to use "compressed" multilink journal change representation
- fixed bug in metakit unlink journalling
diff --git a/doc/mysql.txt b/doc/mysql.txt
index f64cb529a358e3b4e35a2c1d199382b3d81d0cc3..f807ef80f7da457658e88e9af72464b9c8ad1b0a 100644 (file)
--- a/doc/mysql.txt
+++ b/doc/mysql.txt
drop database with data.
+Additional configuration
+========================
+
+To initialise and use mysql database roundup' configuration file (config.py in
+the tracker' home directory) should be appended with the following constants:
+
+ MYSQL_DBHOST = 'localhost'
+ MYSQL_DBUSER = 'rounduptest'
+ MYSQL_DBPASSWORD = 'rounduptest'
+ MYSQL_DBNAME = 'rounduptest'
+ MYSQL_DATABASE = ( MYSQL_DBHOST, MYSQL_DBUSER, MYSQL_DBPASSWORD, MYSQL_DBNAME )
+
+Fill first four constants with real values before running
+"roundup-admin initialise".
+
+
+
Andrey Lebedev <andrey@micro.lt>
diff --git a/roundup/admin.py b/roundup/admin.py
index 8dfde0d0d23bf70579f6a0cde1412a970a825169..e13ee775f5df944d10ad30cee6562822cd26f1a8 100644 (file)
--- a/roundup/admin.py
+++ b/roundup/admin.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: admin.py,v 1.36 2003-02-06 05:43:47 richard Exp $
+# $Id: admin.py,v 1.37 2003-02-15 23:19:01 kedder Exp $
'''Administration commands for maintaining Roundup trackers.
'''
# make sure the tracker home is installed
if not os.path.exists(tracker_home):
raise UsageError, _('Instance home does not exist')%locals()
- if not os.path.exists(os.path.join(tracker_home, 'html')):
+ try:
+ tracker = roundup.instance.open(tracker_home)
+ except roundup.instance.TrackerError:
raise UsageError, _('Instance has not been installed')%locals()
# is there already a database?
- if os.path.exists(os.path.join(tracker_home, 'db')):
+ try:
+ db_exists = tracker.select_db.Database.exists(tracker.config)
+ except AttributeError:
+ # TODO: move this code to exists() static method in every backend
+ db_exists = os.path.exists(os.path.join(tracker_home, 'db'))
+ if db_exists:
print _('WARNING: The database is already initialised!')
print _('If you re-initialise it, you will lose all the data!')
ok = raw_input(_('Erase it? Y/[N]: ')).strip()
if ok.lower() != 'y':
return 0
- # nuke it
- shutil.rmtree(os.path.join(tracker_home, 'db'))
+ # Get a database backend in use by tracker
+ try:
+ # nuke it
+ tracker.select_db.Database.nuke(tracker.config)
+ except AttributeError:
+ # TODO: move this code to nuke() static method in every backend
+ shutil.rmtree(os.path.join(tracker_home, 'db'))
# GO
init.initialise(tracker_home, adminpw)
index 7ff747f23361f52aea3a95750bea53d17cadc7f3..ef3d53859f8e336797b7a5b5a794daa313ab8ac0 100644 (file)
from roundup.backends.rdbms_common import *
from roundup.backends import rdbms_common
import MySQLdb
+import os, shutil
from MySQLdb.constants import ER
+class Maintenance:
+ """ Database maintenance functions """
+ def db_nuke(self, config):
+ """Clear all database contents and drop database itself"""
+ db = Database(config, 'admin')
+ db.sql("DROP DATABASE %s" % config.MYSQL_DBNAME)
+ db.sql("CREATE DATABASE %s" % config.MYSQL_DBNAME)
+ if os.path.exists(config.DATABASE):
+ shutil.rmtree(config.DATABASE)
+
+ def db_exists(self, config):
+ """Check if database already exists"""
+ # Yes, this is a hack, but we must must open connection without
+ # selecting a database to prevent creation of some tables
+ config.MYSQL_DATABASE = (config.MYSQL_DBHOST, config.MYSQL_DBUSER, config.MYSQL_DBPASSWORD)
+ db = Database(config, 'admin')
+ db.conn.select_db(config.MYSQL_DBNAME)
+ config.MYSQL_DATABASE = (config.MYSQL_DBHOST, config.MYSQL_DBUSER, config.MYSQL_DBPASSWORD, config.MYSQL_DBNAME)
+ db.sql("SHOW TABLES")
+ tables = db.sql_fetchall()
+ if tables or os.path.exists(config.DATABASE):
+ return 1
+ return 0
+
class Database(Database):
arg = '%s'
print >>hyperdb.DEBUG, 'create_class', (self, sql)
self.cursor.execute(sql)
+ # Static methods
+ nuke = Maintenance().db_nuke
+ exists = Maintenance().db_exists
+
class MysqlClass:
def find(self, **propspec):
'''Get the ids of nodes in this class which link to the given nodes.
self.db.sql(query, vals)
l += [x[0] for x in self.db.sql_fetchall()]
if __debug__:
- print >>hyperdb.DEBUG, 'find ... ', l #db.sql("DROP DATABASE %s" % config.MYSQL_DBNAME)
+ print >>hyperdb.DEBUG, 'find ... ', l
# Remove duplicated ids
d = {}
class FileClass(MysqlClass, rdbms_common.FileClass):
pass
-def nuke(config):
- """ Clear all database contents and drop database itself"""
- # Connect to db
- db = Database(config, 'admin')
- db.sql("DROP DATABASE %s" % config.MYSQL_DBNAME)
- db.sql("CREATE DATABASE %s" % config.MYSQL_DBNAME)
+#vim: set et
diff --git a/test/test_db.py b/test/test_db.py
index a582e6531deb72ca77939eedcc8912b23d42c459..62520a8a136f7bbaa964a9de09d43f9fbf46fa33 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.70 2003-02-15 14:26:38 kedder Exp $
+# $Id: test_db.py,v 1.71 2003-02-15 23:19:01 kedder Exp $
import unittest, os, shutil, time
def tearDown(self):
from roundup.backends import mysql
self.db.close()
- mysql.nuke(config)
- anydbmDBTestCase.tearDown(self)
+ mysql.Database.nuke(config)
class mysqlReadOnlyDBTestCase(anydbmReadOnlyDBTestCase):
def setUp(self):
def tearDown(self):
from roundup.backends import mysql
self.db.close()
- mysql.nuke(config)
- anydbmReadOnlyDBTestCase.tearDown(self)
+ mysql.Database.nuke(config)
class sqliteDBTestCase(anydbmDBTestCase):
def setUp(self):
if tables:
# Database should be empty. We don't dare to delete any data
raise DatabaseError, "(Database %s contains tables)" % config.MYSQL_DBNAME
- db.sql("DROP DATABASE IF EXISTS %s" % config.MYSQL_DBNAME)
+ db.sql("DROP DATABASE %s" % config.MYSQL_DBNAME)
db.sql("CREATE DATABASE %s" % config.MYSQL_DBNAME)
db.close()
except (MySQLdb.ProgrammingError, DatabaseError), msg: