A
download dumbdbm.py
Language: Python
LOC: 114
Project Info
NetMage
Server: SourceForge
Type: cvs
...ge\netmage\netmage\lib\Lib\
   .cvsignore
   __future__.py
   anydbm.py
   atexit.py
   base64.py
   BaseHTTPServer.py
   bdb.py
   binhex.py
   bisect.py
   calendar.py
   cgi.py
   CGIHTTPServer.py
   cmd.py
   code.py
   codecs.py
   colorsys.py
   commands.py
   compileall.py
   ConfigParser.py
   Cookie.py
   copy.py
   copy_reg.py
   dbexts.py
   difflib.py
   dircache.py
   doctest.py
   dospath.py
   dumbdbm.py
   fileinput.py
   fnmatch.py
   formatter.py
   fpformat.py
   ftplib.py
   getopt.py
   glob.py
   gopherlib.py
   gzip.py
   htmlentitydefs.py
   htmllib.py
   httplib.py
   imaplib.py
   imghdr.py
   isql.py
   javaos.py
   javapath.py
   jreload.py
   keyword.py
   linecache.py
   macpath.py
   macurl2path.py
   mailbox.py
   mailcap.py
   marshal.py
   mhlib.py
   mimetools.py
   mimetypes.py
   MimeWriter.py
   mimify.py
   multifile.py
   mutex.py
   nntplib.py
   ntpath.py
   nturl2path.py
   pdb.py
   pickle.py
   pipes.py
   popen2.py
   poplib.py
   posixfile.py
   posixpath.py
   pprint.py
   profile.py
   pstats.py
   pyclbr.py
   Queue.py
   quopri.py
   random.py
   re.py
   reconvert.py
   repr.py
   rfc822.py
   sched.py
   sgmllib.py
   shelve.py
   shutil.py
   SimpleHTTPServer.py
   site.py
   smtplib.py
   sndhdr.py
   socket.py
   SocketServer.py
   sre.py
   sre_compile.py
   sre_constants.py
   sre_parse.py
   stat.py
   string.py
   StringIO.py
   symbol.py
   telnetlib.py
   tempfile.py
   threading.py
   token.py
   tokenize.py
   traceback.py
   tzparse.py
   unittest.py
   urllib.py
   urlparse.py
   user.py
   UserDict.py
   UserList.py
   UserString.py
   warnings.py
   weakref.py
   whichdb.py
   whrandom.py
   xdrlib.py
   xmllib.py
   zipfile.py
   zlib.py

"""A dumb and slow but simple dbm clone.

For database spam, spam.dir contains the index (a text file),
spam.bak *may* contain a backup of the index (also a text file),
while spam.dat contains the data (a binary file).

XXX TO DO:

- seems to contain a bug when updating...

- reclaim free space (currently, space once occupied by deleted or expanded
items is never reused)

- support concurrent access (currently, if two processes take turns making
updates, they can mess up the index)

- support efficient access to large databases (currently, the whole index
is read when the database is opened, and some updates rewrite the whole index)

- support opening for read-only (flag = 'm')

"""

_os = __import__('os')
import __builtin__

_open = __builtin__.open

_BLOCKSIZE = 512

error = IOError                         # For anydbm

class _Database:

    def __init__(self, file):
        if _os.sep == '.':
            endsep = '/'
        else:
            endsep = '.'
        self._dirfile = file + endsep + 'dir'
        self._datfile = file + endsep + 'dat'
        self._bakfile = file + endsep + 'bak'
        # Mod by Jack: create data file if needed
        try:
            f = _open(self._datfile, 'r')
        except IOError:
            f = _open(self._datfile, 'w')
        f.close()
        self._update()

    def _update(self):
        self._index = {}
        try:
            f = _open(self._dirfile)
        except IOError:
            pass
        else:
            while 1:
                line = f.readline().rstrip()
                if not line: break
                key, (pos, siz) = eval(line)
                self._index[key] = (pos, siz)
            f.close()

    def _commit(self):
        try: _os.unlink(self._bakfile)
        except _os.error: pass
        try: _os.rename(self._dirfile, self._bakfile)
        except _os.error: pass
        f = _open(self._dirfile, 'w')
        for key, (pos, siz) in self._index.items():
            f.write("%s, (%s, %s)\n" % (`key`, `pos`, `siz`))
        f.close()

    def __getitem__(self, key):
        pos, siz = self._index[key]     # may raise KeyError
        f = _open(self._datfile, 'rb')
        f.seek(pos)
        dat = f.read(siz)
        f.close()
        return dat

    def _addval(self, val):
        f = _open(self._datfile, 'rb+')
        f.seek(0, 2)
        pos = int(f.tell())
## Does not work under MW compiler
##              pos = ((pos + _BLOCKSIZE - 1) / _BLOCKSIZE) * _BLOCKSIZE
##              f.seek(pos)
        npos = ((pos + _BLOCKSIZE - 1) / _BLOCKSIZE) * _BLOCKSIZE
        f.write('\0'*(npos-pos))
        pos = npos

        f.write(val)
        f.close()
        return (pos, len(val))

    def _setval(self, pos, val):
        f = _open(self._datfile, 'rb+')
        f.seek(pos)
        f.write(val)
        f.close()
        return (pos, len(val))

    def _addkey(self, key, (pos, siz)):
        self._index[key] = (pos, siz)
        f = _open(self._dirfile, 'a')
        f.write("%s, (%s, %s)\n" % (`key`, `pos`, `siz`))
        f.close()

    def __setitem__(self, key, val):
        if not type(key) == type('') == type(val):
            raise TypeError, "keys and values must be strings"
        if not self._index.has_key(key):
            (pos, siz) = self._addval(val)
            self._addkey(key, (pos, siz))
        else:
            pos, siz = self._index[key]
            oldblocks = (siz + _BLOCKSIZE - 1) / _BLOCKSIZE
            newblocks = (len(val) + _BLOCKSIZE - 1) / _BLOCKSIZE
            if newblocks <= oldblocks:
                pos, siz = self._setval(pos, val)
                self._index[key] = pos, siz
            else:
                pos, siz = self._addval(val)
                self._index[key] = pos, siz

    def __delitem__(self, key):
        del self._index[key]
        self._commit()

    def keys(self):
        return self._index.keys()

    def has_key(self, key):
        return self._index.has_key(key)

    def __len__(self):
        return len(self._index)

    def close(self):
        self._index = None
        self._datfile = self._dirfile = self._bakfile = None


def open(file, flag = None, mode = None):
    # flag, mode arguments are currently ignored
    return _Database(file)

About Koders | Resources | Downloads | Support | Black Duck | Terms of Service | DMCA | Privacy Policy | Contact Us