Package pycosmicstar :: Module filedict_old
[hide private]
[frames] | no frames]

Source Code for Module pycosmicstar.filedict_old

  1  """filedict.py 
  2  a Persistent Dictionary in Python 
  3    
  4  Author: Erez Shinan 
  5  Date  : 24-May-2009 
  6  """ 
  7    
  8  import sqlite3 
  9  import cPickle as pickle 
10 11 -class DefaultArg:
12 pass
13
14 -class Solutions:
15 Sqlite3 = 0
16
17 -class FileDict(object):
18 "A dictionary that stores its data persistantly in a file" 19
20 - def __init__(self, solution=Solutions.Sqlite3, **options):
21 assert solution == Solutions.Sqlite3 22 try: 23 self.__conn = options.pop('connection') 24 except KeyError: 25 filename = options.pop('filename') 26 self.__conn = sqlite3.connect(filename) 27 28 self.__tablename = options.pop('table', 'dict') 29 30 self._nocommit = False 31 32 assert not options, "Unrecognized options: %s" % options 33 34 self.__conn.execute('create table if not exists %s (hash integer, key blob, value blob);'%self.__tablename) 35 self.__conn.execute('create index if not exists %s_index ON %s(hash);' % (self.__tablename, self.__tablename)) 36 self.__conn.commit()
37
38 - def _commit(self):
39 if self._nocommit: 40 return 41 42 self.__conn.commit()
43
44 - def __pack_key(self, key):
45 return sqlite3.Binary(pickle.dumps(key, 1))
46 - def __pack_value(self, value):
47 return sqlite3.Binary(pickle.dumps(value, -1))
48 - def __unpack_value(self, value):
49 return pickle.loads(str(value))
50
51 - def get(self, key, default=None):
52 try: 53 return self.__getitem__(key) 54 except KeyError: 55 return default
56
57 - def __getitem__(self, key):
58 tbl = self.__tablename 59 key_hash = hash(key) 60 key_pickle = self.__pack_key(key) 61 c = self.__conn.execute('select value from %s where hash=? and key=?;'%tbl, (key_hash, key_pickle)) 62 res = c.fetchone() 63 if res is None: 64 raise KeyError(key) 65 66 [value_pickle] = res 67 return self.__unpack_value(value_pickle)
68
69 - def __setitem(self, key, value):
70 tbl = self.__tablename 71 key_hash = hash(key) 72 key_pickle = self.__pack_key(key) 73 value_pickle = self.__pack_value(value) 74 75 res = self.__conn.execute('update %s set value=? where hash=? and key=?;'%tbl, (value_pickle, key_hash, key_pickle) ) 76 if res.rowcount <= 0: 77 res = self.__conn.execute('insert into %s values (?, ?, ?);'%tbl, (key_hash, key_pickle, value_pickle) ) 78 79 assert res.rowcount == 1
80
81 - def __setitem__(self, key, value):
82 self.__setitem(key, value) 83 self._commit()
84
85 - def __delitem__(self, key):
86 tbl = self.__tablename 87 key_hash = hash(key) 88 key_pickle = self.__pack_key(key) 89 90 res = self.__conn.execute('delete from %s where hash=? and key=?;'%tbl, (key_hash, key_pickle)) 91 if res.rowcount <= 0: 92 raise KeyError(key) 93 94 self._commit()
95
96 - def update(self, d):
97 for k,v in d.iteritems(): 98 self.__setitem(k, v) 99 self._commit()
100
101 - def pop(self, key, default=DefaultArg):
102 try: 103 value = self[key] 104 except KeyError: 105 if default is DefaultArg: 106 raise 107 else: 108 value = self.get(key, default) 109 else: 110 del self[key] 111 return value
112
113 - def keys(self):
114 return (self.__unpack_value(x[0]) for x in self.__conn.execute('select key from %s;'%self.__tablename) )
115 - def values(self):
116 return (self.__unpack_value(x[0]) for x in self.__conn.execute('select value from %s;'%self.__tablename) )
117 - def items(self):
118 return (map(self.__unpack_value, x) for x in self.__conn.execute('select key,value from %s;'%self.__tablename) )
119 - def iterkeys(self):
120 return self.keys()
121 - def itervalues(self):
122 return self.values()
123 - def iteritems(self):
124 return self.items()
125
126 - def has_key(self, key):
127 tbl = self.__tablename 128 key_hash = hash(key) 129 key_pickle = self.__pack_key(key) 130 c = self.__conn.execute('select count(*) from %(tbl)s where hash=%(key_hash)d and key=%(key_pickle)r;' % locals()) 131 res = c.fetchone() 132 assert res 133 assert 0 <= res[0] <= 1 134 135 return bool(res[0])
136
137 - def __contains__(self, key):
138 return self.has_key(key)
139
140 - def __len__(self):
141 return self.__conn.execute('select count(*) from %s;' % self.__tablename).fetchone()[0]
142
143 - def __del__(self):
144 try: 145 self.__conn 146 except AttributeError: 147 pass 148 else: 149 self.__conn.commit() 150 self.__conn.close()
151 152 @property
153 - def batch(self):
154 return self._Batch(self)
155
156 - class _Batch:
157 - def __init__(self, d):
158 self.__d = d
159
160 - def __enter__(self):
161 self.__d._nocommit = True 162 return self.__d
163
164 - def __exit__(self, type, value, traceback):
165 self.__d._nocommit = False 166 self.__d._commit() 167 return True
168