5 """Dbm based on sqlite -- Needed to support shelves 
    9     # ??? how to coordinate with whichdb 
   10     # ??? Any difference between blobs and text 
   11     # ??? does default encoding affect str-->bytes or PySqlite3 always use UTF-8 
   12     # ??? what is the correct isolation mode 
   16 __all__ = [
'error', 
'open']
 
   20 from collections.abc 
import MutableMapping
 
   21 from operator 
import itemgetter
 
   24 error = sqlite3.DatabaseError
 
   27     def __init__(self, filename=':memory:
', flags='r', mode=None): 
   35             if os.path.exists(filename):
 
   38         MAKE_SHELF = 
'CREATE TABLE IF NOT EXISTS shelf (key TEXT PRIMARY KEY NOT NULL, value BLOB)' 
   39         self.
conn = sqlite3.connect(filename)
 
   40         self.
conn.text_factory = str
 
   41         if 'r' not in flags 
or filename==
':memory:':
 
   46         GET_LEN = 
'SELECT COUNT(*) FROM shelf' 
   51         GET_BOOL = 
'SELECT MAX(ROWID) FROM shelf' 
   52         return self.
conn.
execute(GET_BOOL).fetchone()[0] 
is not None 
   67         GET_KEYS = 
'SELECT key FROM shelf ORDER BY ROWID' 
   71         GET_VALUES = 
'SELECT value FROM shelf ORDER BY ROWID' 
   75         GET_ITEMS = 
'SELECT key, value FROM shelf ORDER BY ROWID' 
   79         HAS_ITEM = 
'SELECT 1 FROM shelf WHERE key = ?' 
   80         return self.
conn.
execute(HAS_ITEM, (key,)).fetchone() 
is not None 
   83         GET_ITEM = 
'SELECT value FROM shelf WHERE key = ?' 
   84         item = self.
conn.
execute(GET_ITEM, (key,)).fetchone()
 
   88         return pickle.loads(item[0])
 
   91         ADD_ITEM = 
'REPLACE INTO shelf (key, value) VALUES (?,?)' 
   92         value = pickle.dumps(value)
 
   99         DEL_ITEM = 
'DELETE FROM shelf WHERE key = ?' 
  105             items = items.items()
 
  106             items = [(k,pickle.dumps(v)) 
for k,v 
in items]
 
  107         except AttributeError:
 
  110         UPDATE_ITEMS = 
'REPLACE INTO shelf (key, value) VALUES (?, ?)' 
  111         self.
conn.executemany(UPDATE_ITEMS, items)
 
  117         CLEAR_ALL = 
'DELETE FROM shelf; VACUUM;' 
  118         self.
conn.executescript(CLEAR_ALL)
 
  122         if self.
conn is not None:    
 
  126         if self.
conn is not None:
 
  134 def open(file=None, *args, **kw):
 
  136         return SQLhash(file, *args, **kw)
 
  140     _db = 
open(file, *args, **kw)
 
  141     return shelve.Shelf(_db)
 
  172         return pickle.loads(o)
 
  175         return pickle.loads(o)
 
  191         v = pickle.loads(o[1])
 
  196         v = pickle.loads(o[1])
 
  199 if __name__ 
in '__main___':
 
  209         print(
'***', d.keys())
 
  211         d.update(p=
'x', q=
'y', r=
'z')
 
  220             raise Exception(
'oh noooo!')
 
  227             raise Exception(
'drat!')
 
  234         d.update(p=
'x', q=
'y', r=
'z')
 
  238         d[
'a_list'] = 
range(5)
 
  241         d[
'a_dict'] = {1:
'one',2:
'two'}
 
  244         d[
'a_tuple'] = (1,2,3,4)