home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Narzedzia / Inkscape / Inkscape-0.48.2-1-win32.exe / python / Lib / bsddb / dbshelve.py < prev    next >
Encoding:
Python Source  |  2010-05-29  |  10.9 KB  |  362 lines

  1. #!/bin/env python
  2. #------------------------------------------------------------------------
  3. #           Copyright (c) 1997-2001 by Total Control Software
  4. #                         All Rights Reserved
  5. #------------------------------------------------------------------------
  6. #
  7. # Module Name:  dbShelve.py
  8. #
  9. # Description:  A reimplementation of the standard shelve.py that
  10. #               forces the use of cPickle, and DB.
  11. #
  12. # Creation Date:    11/3/97 3:39:04PM
  13. #
  14. # License:      This is free software.  You may use this software for any
  15. #               purpose including modification/redistribution, so long as
  16. #               this header remains intact and that you do not claim any
  17. #               rights of ownership or authorship of this software.  This
  18. #               software has been tested, but no warranty is expressed or
  19. #               implied.
  20. #
  21. # 13-Dec-2000:  Updated to be used with the new bsddb3 package.
  22. #               Added DBShelfCursor class.
  23. #
  24. #------------------------------------------------------------------------
  25.  
  26. """Manage shelves of pickled objects using bsddb database files for the
  27. storage.
  28. """
  29.  
  30. #------------------------------------------------------------------------
  31.  
  32. import cPickle
  33. import sys
  34.  
  35. import sys
  36. absolute_import = (sys.version_info[0] >= 3)
  37. if absolute_import :
  38.     # Because this syntaxis is not valid before Python 2.5
  39.     exec("from . import db")
  40. else :
  41.     import db
  42.  
  43. #At version 2.3 cPickle switched to using protocol instead of bin
  44. if sys.version_info[:3] >= (2, 3, 0):
  45.     HIGHEST_PROTOCOL = cPickle.HIGHEST_PROTOCOL
  46. # In python 2.3.*, "cPickle.dumps" accepts no
  47. # named parameters. "pickle.dumps" accepts them,
  48. # so this seems a bug.
  49.     if sys.version_info[:3] < (2, 4, 0):
  50.         def _dumps(object, protocol):
  51.             return cPickle.dumps(object, protocol)
  52.     else :
  53.         def _dumps(object, protocol):
  54.             return cPickle.dumps(object, protocol=protocol)
  55.  
  56. else:
  57.     HIGHEST_PROTOCOL = None
  58.     def _dumps(object, protocol):
  59.         return cPickle.dumps(object, bin=protocol)
  60.  
  61.  
  62. try:
  63.     from UserDict import DictMixin
  64. except ImportError:
  65.     # DictMixin is new in Python 2.3
  66.     class DictMixin: pass
  67.  
  68. #------------------------------------------------------------------------
  69.  
  70.  
  71. def open(filename, flags=db.DB_CREATE, mode=0660, filetype=db.DB_HASH,
  72.          dbenv=None, dbname=None):
  73.     """
  74.     A simple factory function for compatibility with the standard
  75.     shleve.py module.  It can be used like this, where key is a string
  76.     and data is a pickleable object:
  77.  
  78.         from bsddb import dbshelve
  79.         db = dbshelve.open(filename)
  80.  
  81.         db[key] = data
  82.  
  83.         db.close()
  84.     """
  85.     if type(flags) == type(''):
  86.         sflag = flags
  87.         if sflag == 'r':
  88.             flags = db.DB_RDONLY
  89.         elif sflag == 'rw':
  90.             flags = 0
  91.         elif sflag == 'w':
  92.             flags =  db.DB_CREATE
  93.         elif sflag == 'c':
  94.             flags =  db.DB_CREATE
  95.         elif sflag == 'n':
  96.             flags = db.DB_TRUNCATE | db.DB_CREATE
  97.         else:
  98.             raise db.DBError, "flags should be one of 'r', 'w', 'c' or 'n' or use the bsddb.db.DB_* flags"
  99.  
  100.     d = DBShelf(dbenv)
  101.     d.open(filename, dbname, filetype, flags, mode)
  102.     return d
  103.  
  104. #---------------------------------------------------------------------------
  105.  
  106. class DBShelveError(db.DBError): pass
  107.  
  108.  
  109. class DBShelf(DictMixin):
  110.     """A shelf to hold pickled objects, built upon a bsddb DB object.  It
  111.     automatically pickles/unpickles data objects going to/from the DB.
  112.     """
  113.     def __init__(self, dbenv=None):
  114.         self.db = db.DB(dbenv)
  115.         self._closed = True
  116.         if HIGHEST_PROTOCOL:
  117.             self.protocol = HIGHEST_PROTOCOL
  118.         else:
  119.             self.protocol = 1
  120.  
  121.  
  122.     def __del__(self):
  123.         self.close()
  124.  
  125.  
  126.     def __getattr__(self, name):
  127.         """Many methods we can just pass through to the DB object.
  128.         (See below)
  129.         """
  130.         return getattr(self.db, name)
  131.  
  132.  
  133.     #-----------------------------------
  134.     # Dictionary access methods
  135.  
  136.     def __len__(self):
  137.         return len(self.db)
  138.  
  139.  
  140.     def __getitem__(self, key):
  141.         data = self.db[key]
  142.         return cPickle.loads(data)
  143.  
  144.  
  145.     def __setitem__(self, key, value):
  146.         data = _dumps(value, self.protocol)
  147.         self.db[key] = data
  148.  
  149.  
  150.     def __delitem__(self, key):
  151.         del self.db[key]
  152.  
  153.  
  154.     def keys(self, txn=None):
  155.         if txn != None:
  156.             return self.db.keys(txn)
  157.         else:
  158.             return self.db.keys()
  159.  
  160.  
  161.     def open(self, *args, **kwargs):
  162.         self.db.open(*args, **kwargs)
  163.         self._closed = False
  164.  
  165.  
  166.     def close(self, *args, **kwargs):
  167.         self.db.close(*args, **kwargs)
  168.         self._closed = True
  169.  
  170.  
  171.     def __repr__(self):
  172.         if self._closed:
  173.             return '<DBShelf @ 0x%x - closed>' % (id(self))
  174.         else:
  175.             return repr(dict(self.iteritems()))
  176.  
  177.  
  178.     def items(self, txn=None):
  179.         if txn != None:
  180.             items = self.db.items(txn)
  181.         else:
  182.             items = self.db.items()
  183.         newitems = []
  184.  
  185.         for k, v in items:
  186.             newitems.append( (k, cPickle.loads(v)) )
  187.         return newitems
  188.  
  189.     def values(self, txn=None):
  190.         if txn != None:
  191.             values = self.db.values(txn)
  192.         else:
  193.             values = self.db.values()
  194.  
  195.         return map(cPickle.loads, values)
  196.  
  197.     #-----------------------------------
  198.     # Other methods
  199.  
  200.     def __append(self, value, txn=None):
  201.         data = _dumps(value, self.protocol)
  202.         return self.db.append(data, txn)
  203.  
  204.     def append(self, value, txn=None):
  205.         if self.get_type() == db.DB_RECNO:
  206.             return self.__append(value, txn=txn)
  207.         raise DBShelveError, "append() only supported when dbshelve opened with filetype=dbshelve.db.DB_RECNO"
  208.  
  209.  
  210.     def associate(self, secondaryDB, callback, flags=0):
  211.         def _shelf_callback(priKey, priData, realCallback=callback):
  212.             # Safe in Python 2.x because expresion short circuit
  213.             if sys.version_info[0] < 3 or isinstance(priData, bytes) :
  214.                 data = cPickle.loads(priData)
  215.             else :
  216.                 data = cPickle.loads(bytes(priData, "iso8859-1"))  # 8 bits
  217.             return realCallback(priKey, data)
  218.  
  219.         return self.db.associate(secondaryDB, _shelf_callback, flags)
  220.  
  221.  
  222.     #def get(self, key, default=None, txn=None, flags=0):
  223.     def get(self, *args, **kw):
  224.         # We do it with *args and **kw so if the default value wasn't
  225.         # given nothing is passed to the extension module.  That way
  226.         # an exception can be raised if set_get_returns_none is turned
  227.         # off.
  228.         data = apply(self.db.get, args, kw)
  229.         try:
  230.             return cPickle.loads(data)
  231.         except (EOFError, TypeError, cPickle.UnpicklingError):
  232.             return data  # we may be getting the default value, or None,
  233.                          # so it doesn't need unpickled.
  234.  
  235.     def get_both(self, key, value, txn=None, flags=0):
  236.         data = _dumps(value, self.protocol)
  237.         data = self.db.get(key, data, txn, flags)
  238.         return cPickle.loads(data)
  239.  
  240.  
  241.     def cursor(self, txn=None, flags=0):
  242.         c = DBShelfCursor(self.db.cursor(txn, flags))
  243.         c.protocol = self.protocol
  244.         return c
  245.  
  246.  
  247.     def put(self, key, value, txn=None, flags=0):
  248.         data = _dumps(value, self.protocol)
  249.         return self.db.put(key, data, txn, flags)
  250.  
  251.  
  252.     def join(self, cursorList, flags=0):
  253.         raise NotImplementedError
  254.  
  255.  
  256.     #----------------------------------------------
  257.     # Methods allowed to pass-through to self.db
  258.     #
  259.     #    close,  delete, fd, get_byteswapped, get_type, has_key,
  260.     #    key_range, open, remove, rename, stat, sync,
  261.     #    upgrade, verify, and all set_* methods.
  262.  
  263.  
  264. #---------------------------------------------------------------------------
  265.  
  266. class DBShelfCursor:
  267.     """
  268.     """
  269.     def __init__(self, cursor):
  270.         self.dbc = cursor
  271.  
  272.     def __del__(self):
  273.         self.close()
  274.  
  275.  
  276.     def __getattr__(self, name):
  277.         """Some methods we can just pass through to the cursor object.  (See below)"""
  278.         return getattr(self.dbc, name)
  279.  
  280.  
  281.     #----------------------------------------------
  282.  
  283.     def dup(self, flags=0):
  284.         c = DBShelfCursor(self.dbc.dup(flags))
  285.         c.protocol = self.protocol
  286.         return c
  287.  
  288.  
  289.     def put(self, key, value, flags=0):
  290.         data = _dumps(value, self.protocol)
  291.         return self.dbc.put(key, data, flags)
  292.  
  293.  
  294.     def get(self, *args):
  295.         count = len(args)  # a method overloading hack
  296.         method = getattr(self, 'get_%d' % count)
  297.         apply(method, args)
  298.  
  299.     def get_1(self, flags):
  300.         rec = self.dbc.get(flags)
  301.         return self._extract(rec)
  302.  
  303.     def get_2(self, key, flags):
  304.         rec = self.dbc.get(key, flags)
  305.         return self._extract(rec)
  306.  
  307.     def get_3(self, key, value, flags):
  308.         data = _dumps(value, self.protocol)
  309.         rec = self.dbc.get(key, flags)
  310.         return self._extract(rec)
  311.  
  312.  
  313.     def current(self, flags=0): return self.get_1(flags|db.DB_CURRENT)
  314.     def first(self, flags=0): return self.get_1(flags|db.DB_FIRST)
  315.     def last(self, flags=0): return self.get_1(flags|db.DB_LAST)
  316.     def next(self, flags=0): return self.get_1(flags|db.DB_NEXT)
  317.     def prev(self, flags=0): return self.get_1(flags|db.DB_PREV)
  318.     def consume(self, flags=0): return self.get_1(flags|db.DB_CONSUME)
  319.     def next_dup(self, flags=0): return self.get_1(flags|db.DB_NEXT_DUP)
  320.     def next_nodup(self, flags=0): return self.get_1(flags|db.DB_NEXT_NODUP)
  321.     def prev_nodup(self, flags=0): return self.get_1(flags|db.DB_PREV_NODUP)
  322.  
  323.  
  324.     def get_both(self, key, value, flags=0):
  325.         data = _dumps(value, self.protocol)
  326.         rec = self.dbc.get_both(key, flags)
  327.         return self._extract(rec)
  328.  
  329.  
  330.     def set(self, key, flags=0):
  331.         rec = self.dbc.set(key, flags)
  332.         return self._extract(rec)
  333.  
  334.     def set_range(self, key, flags=0):
  335.         rec = self.dbc.set_range(key, flags)
  336.         return self._extract(rec)
  337.  
  338.     def set_recno(self, recno, flags=0):
  339.         rec = self.dbc.set_recno(recno, flags)
  340.         return self._extract(rec)
  341.  
  342.     set_both = get_both
  343.  
  344.     def _extract(self, rec):
  345.         if rec is None:
  346.             return None
  347.         else:
  348.             key, data = rec
  349.             # Safe in Python 2.x because expresion short circuit
  350.             if sys.version_info[0] < 3 or isinstance(data, bytes) :
  351.                 return key, cPickle.loads(data)
  352.             else :
  353.                 return key, cPickle.loads(bytes(data, "iso8859-1"))  # 8 bits
  354.  
  355.     #----------------------------------------------
  356.     # Methods allowed to pass-through to self.dbc
  357.     #
  358.     # close, count, delete, get_recno, join_item
  359.  
  360.  
  361. #---------------------------------------------------------------------------
  362.