Code

I fixed the problems with people whose anydbm was using the dbm module at the
authorrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 12 Dec 2001 02:30:51 +0000 (02:30 +0000)
committerrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 12 Dec 2001 02:30:51 +0000 (02:30 +0000)
backend. It turns out the dbm module modifies the file name to append ".db"
and my check to determine if we're opening an existing or new db just
tested os.path.exists() on the filename. Well, no longer! We now perform a
much better check _and_ cope with the anydbm implementation module changing
too!
I also fixed the backends __init__ so only ImportError is squashed.

git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@455 57a73879-2fb5-44c3-a270-3262357dd7e2

CHANGES.txt
roundup/backends/__init__.py
roundup/backends/back_anydbm.py

index 3114b4536392166bb0ec8ee6c9fc04cf80e80687..a352a967656f9a15a744a48a32c13c2b247622ad 100644 (file)
@@ -36,6 +36,9 @@ Fixed:
  . fixed doc/index.html to include the quoting in the mail alias.
  . fixed the backends __init__ so we can pydoc the backend modules
  . web i/f reports "note added" if there are no changes but a note is entered
+ . we were assuming database files created by anydbm had the same name, but
+   this is not the case for dbm. We now perform a much better check _and_
+   cope with the anydbm implementation module changing too!
 
 
 2001-11-23 - 0.3.0 
index 2c181a2e3d1f55e727c08b42ba4e83ffc28a74b1..3a1d7b36332d052040b89497d824e32c8dd3ede6 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: __init__.py,v 1.8 2001-12-10 22:20:01 richard Exp $
+# $Id: __init__.py,v 1.9 2001-12-12 02:30:51 richard Exp $
 
 __all__ = []
 
@@ -30,25 +30,32 @@ try:
     __all__.append('anydbm')
 except AssertionError:
     del back_anydbm
-except:
+except ImportError:
     pass
 
 try:
     import back_bsddb
     bsddb = back_bsddb
     __all__.append('bsddb')
-except:
+except ImportError:
     pass
 
 try:
     import back_bsddb3
     bsddb3 = back_bsddb3
     __all__.append('bsddb3')
-except:
+except ImportError:
     pass
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.8  2001/12/10 22:20:01  richard
+# Enabled transaction support in the bsddb backend. It uses the anydbm code
+# where possible, only replacing methods where the db is opened (it uses the
+# btree opener specifically.)
+# Also cleaned up some change note generation.
+# Made the backends package work with pydoc too.
+#
 # Revision 1.7  2001/12/10 00:57:38  richard
 # From CHANGES:
 #  . Added the "display" command to the admin tool - displays a node's values
index 6a90a1d9404b5c0a24c8d1cc240c04c1f6251342..317bc3a3c9fb3153474032a41b8a15d944b26df3 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-#$Id: back_anydbm.py,v 1.14 2001-12-10 22:20:01 richard Exp $
+#$Id: back_anydbm.py,v 1.15 2001-12-12 02:30:51 richard Exp $
 '''
 This module defines a backend that saves the hyperdatabase in a database
 chosen by anydbm. It is guaranteed to always be available in python
@@ -23,7 +23,7 @@ versions >2.1.1 (the dumbdbm fallback in 2.1.1 and earlier has several
 serious bugs, and is not available)
 '''
 
-import anydbm, os, marshal
+import whichdb, anydbm, os, marshal
 from roundup import hyperdb, date, password
 
 #
@@ -88,22 +88,46 @@ class Database(hyperdb.Database):
     # Class DBs
     #
     def clear(self):
+        '''Delete all database contents
+        '''
         for cn in self.classes.keys():
-            db = os.path.join(self.dir, 'nodes.%s'%cn)
-            anydbm.open(db, 'n')
-            db = os.path.join(self.dir, 'journals.%s'%cn)
-            anydbm.open(db, 'n')
+            for type in 'nodes', 'journals':
+                path = os.path.join(self.dir, 'journals.%s'%cn)
+                if os.path.exists(path):
+                    os.remove(path)
+                elif os.path.exists(path+'.db'):    # dbm appends .db
+                    os.remove(path+'.db')
 
     def getclassdb(self, classname, mode='r'):
         ''' grab a connection to the class db that will be used for
             multiple actions
         '''
+        # determine which DB wrote the class file
         path = os.path.join(os.getcwd(), self.dir, 'nodes.%s'%classname)
-        if os.path.exists(path):
-            return anydbm.open(path, mode)
-        else:
+        db_type = whichdb.whichdb(path)
+        if not db_type:
+            # dbm appends ".db"
+            db_type = whichdb.whichdb(path+'.db')
+        db_type = whichdb.whichdb(path)
+
+        # if we can't identify it and it exists...
+        if not db_type and os.path.exists(path) or os.path.exists(path+'.db'):
+            raise hyperdb.DatabaseError, \
+                "Couldn't identify the database type"
+
+        # new database? let anydbm pick the best dbm
+        if not db_type:
             return anydbm.open(path, 'n')
 
+        # open the database with the correct module
+        try:
+            dbm = __import__(db_type)
+        except:
+            raise hyperdb.DatabaseError, \
+                "Couldn't open database - the required module '%s'"\
+                "is not available"%db_type
+        return dbm.open(path, mode)
+
     #
     # Nodes
     #
@@ -254,6 +278,13 @@ class Database(hyperdb.Database):
 
 #
 #$Log: not supported by cvs2svn $
+#Revision 1.14  2001/12/10 22:20:01  richard
+#Enabled transaction support in the bsddb backend. It uses the anydbm code
+#where possible, only replacing methods where the db is opened (it uses the
+#btree opener specifically.)
+#Also cleaned up some change note generation.
+#Made the backends package work with pydoc too.
+#
 #Revision 1.13  2001/12/02 05:06:16  richard
 #. We now use weakrefs in the Classes to keep the database reference, so
 #  the close() method on the database is no longer needed.