]> git.tokkee.org Git - roundup.git/commitdiff

Code

trackers on mysql can be initialised
authorkedder <kedder@57a73879-2fb5-44c3-a270-3262357dd7e2>
Sat, 15 Feb 2003 23:19:01 +0000 (23:19 +0000)
committerkedder <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

CHANGES.txt
doc/mysql.txt
roundup/admin.py
roundup/backends/back_mysql.py
test/test_db.py

index 45ab7bf5cb70f7564e3710d9c523ba428e58bbcf..e1879208eedd139e138d193863934c0175204d52 100644 (file)
@@ -12,7 +12,7 @@ are given with the most recent entry first.
 - 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
index f64cb529a358e3b4e35a2c1d199382b3d81d0cc3..f807ef80f7da457658e88e9af72464b9c8ad1b0a 100644 (file)
@@ -38,6 +38,23 @@ Note, that mysql database should not contain any tables. Tests will not dare to
 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>
 
 
index 8dfde0d0d23bf70579f6a0cde1412a970a825169..e13ee775f5df944d10ad30cee6562822cd26f1a8 100644 (file)
@@ -16,7 +16,7 @@
 # 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.
 '''
@@ -368,19 +368,31 @@ Command help:
         # 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'
     
@@ -115,6 +140,10 @@ class Database(Database):
           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.
@@ -174,7 +203,7 @@ class MysqlClass:
             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 = {}
@@ -191,9 +220,4 @@ class IssueClass(MysqlClass, rdbms_common.IssueClass):
 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
index a582e6531deb72ca77939eedcc8912b23d42c459..62520a8a136f7bbaa964a9de09d43f9fbf46fa33 100644 (file)
@@ -15,7 +15,7 @@
 # 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
 
@@ -738,8 +738,7 @@ class mysqlDBTestCase(anydbmDBTestCase):
     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):
@@ -754,8 +753,7 @@ class mysqlReadOnlyDBTestCase(anydbmReadOnlyDBTestCase):
     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):
@@ -873,7 +871,7 @@ def suite():
             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: