[Spambayes-checkins] spambayes dbdict.py,1.1,1.1.2.1

Tim Stone timstone4@users.sourceforge.net
Wed Nov 20 04:28:36 2002


Update of /cvsroot/spambayes/spambayes
In directory sc8-pr-cvs1:/tmp/cvs-serv32342

Modified Files:
      Tag: hammie-playground
	dbdict.py 
Log Message:
Added LSDBDict class, supports load/store/restore

Index: dbdict.py
===================================================================
RCS file: /cvsroot/spambayes/spambayes/dbdict.py,v
retrieving revision 1.1
retrieving revision 1.1.2.1
diff -C2 -d -r1.1 -r1.1.2.1
*** dbdict.py	19 Nov 2002 23:31:44 -0000	1.1
--- dbdict.py	20 Nov 2002 04:28:34 -0000	1.1.2.1
***************
*** 1,4 ****
--- 1,55 ----
  #! /usr/bin/env python
  
+ '''DBDict.py - Dictionary access to dbhash
+ 
+ Classes:
+     DBDict - wraps an anydbm file
+     LSDBDict - adds load/store/restore semantic to DBDict
+ 
+ Abstract:
+     DBDict class wraps an anydbm file with a reasonably complete set
+     of dictionary access methods.  DBDicts can be iterated like a dictionary.
+ 
+     DBDict accepts an iterskip operand on the constructor.  This is a tuple
+     of hash keys that will be skipped (not seen) during iteration.  This
+     is for iteration only.  Methods such as keys() will return the entire
+     complement of keys in the dbm hash, even if they're in iterskip.  An
+     iterkeys() method is provided for iterating with skipped keys, and
+     itervaluess() is provided for iterating values with skipped keys.
+ 
+         >>> d = DBDict('/tmp/goober.db', MODE_CREATE, ('skipme', 'skipmetoo'))
+         >>> d['skipme'] = 'booga'
+         >>> d['countme'] = 'wakka'
+         >>> print d.keys()
+         ['skipme', 'countme']
+         >>> for k in d.iterkeys():
+         ...     print k
+         countme
+         >>> for v in d.itervalues():
+         ...     print v
+         wakka
+         >>> for k,v in d.iteritems():
+         ...     print k,v
+         countme wakka
+ 
+     LSDBDict class addes load/store/restore functions to DBDict.  It does this
+     by creating a working copy of the dbm file, and using that for all
+     working access.  When the store() method is called, the working dbm hash
+     is closed, copied to the real copy, then reopened, in effect
+     committing any changes.  When restore() is called, the working copy
+     is closed, replaced with the real copy, then reopened.  Store and restore
+     methods are disallowed for readonly (mode MODE_READONLY) LSDBDicts.
+ 
+ To Do:
+     '''
+ 
+ # This module is part of the spambayes project, which is Copyright 2002
+ # The Python Software Foundation and is covered by the Python Software
+ # Foundation license.
+ 
+ __author__ = "Neale Pickett <neale@woozle.org>, \
+               Tim Stone <tim@fourstonesExpressions.com>"
+ __credits__ = "Tim Peters (author of DBDict class), \
+                all the spambayes contributors."
  from __future__ import generators
  import dbhash
***************
*** 7,10 ****
--- 58,72 ----
  except ImportError:
      import pickle
+     
+ import errno
+ import copy
+ import shutil
+ import os
+ 
+ MODE_CREATE = 'c'       # create file if necessary, open for readwrite
+ MODE_NEW = 'n'          # always create new file, open for readwrite
+ MODE_READWRITE = 'w'    # open existing file for readwrite
+ MODE_READONLY = 'r'     # open existing file for read only
+ 
  
  class DBDict:
***************
*** 80,83 ****
--- 142,201 ----
          return self.__iter__(lambda k: k[1])
  
+ 
+ class LSDBDict(DBDict):
+     """Database Dictionary that supports Load/Store semantic."""
+ 
+     def __init__(self, dbname, mode=MODE_CREATE, iterskip=()):
+         '''Constructor, dbname, mode {c|n|r|w}, iteration skip tuple'''
+ 
+         self.mode = mode
+         self.dbname = dbname
+         self.wdbname = self.dbname+'.working'
+         self.iterskip = iterskip
+ 
+         if self.mode == MODE_READWRITE or self.mode == MODE_CREATE:
+             try:
+                 shutil.copyfile(self.dbname, self.wdbname)
+             except (IOError, os.error), why:
+                 pass           # don't blow up for now
+         elif self.mode == MODE_READONLY:
+             # for readonly access, use the real dbm file
+             self.wdbname = self.dbname
+         elif self.mode == MODE_NEW:
+             try:
+                 os.unlink(self.wdbname)
+             except OSError, e:
+                 if e.errno != errno.ENOENT:
+                     raise
+         else:
+             raise ValueError, "Mode must be MODE_CREATE, MODE_NEW, MODE_READONLY, or MODE_READWRITE"
+ 
+         self.hash = dbhash.open(self.wdbname, self.mode)
+ 
+ 
+     def store(self):
+         '''store the working dbm into the 'real' dbm file'''
+ 
+         if self.mode != MODE_READONLY:
+             self.hash.close()
+             shutil.copyfile(self.wdbname, self.dbname)
+             self.hash = dbhash.open(self.wdbname, MODE_CREATE)
+         else:
+             raise error, 'Store operation not permitted on readonly dbm'
+ 
+     def restore(self):
+         '''restore the working dbm to the 'real' dbm condition'''
+ 
+         if self.mode == MODE_READONLY:
+             raise error, \
+                    'Restore operation not permitted on readonly dbm'
+         else:
+            self.hash.close()
+ 
+            if self.mode != MODE_NEW:
+                shutil.copyfile(self.dbname, self.wdbname)
+ 
+            self.hash = dbhash.open(self.wdbname, self.mode)
+            
  open = DBDict
  





More information about the Spambayes-checkins mailing list