[Python-checkins] r69142 - in sandbox/trunk/dbm_sqlite/alt: dbsqlite.py

raymond.hettinger python-checkins at python.org
Sat Jan 31 21:57:03 CET 2009


Author: raymond.hettinger
Date: Sat Jan 31 21:57:02 2009
New Revision: 69142
Log:
Save alternative code for dbsqlite.
Added:
 sandbox/trunk/dbm_sqlite/alt/
 sandbox/trunk/dbm_sqlite/alt/dbsqlite.py (contents, props changed)
Added: sandbox/trunk/dbm_sqlite/alt/dbsqlite.py
==============================================================================
--- (empty file)
+++ sandbox/trunk/dbm_sqlite/alt/dbsqlite.py	Sat Jan 31 21:57:02 2009
@@ -0,0 +1,169 @@
+#!/usr/bin/env python3.0
+''' Dbm based on sqlite -- Needed to support shelves
+
+Key and values are always stored as bytes. This means that when strings are
+used they are implicitly converted to the default encoding before being
+stored.
+
+Issues:
+
+ # ??? how to coordinate with whichdb
+ # ??? Size of text fields fixed or varchar (do we need blobs)
+ # ??? does default encoding affect str-->bytes or PySqlite3 always use UTF-8
+ # ??? if pure python overhead and pysqlite overhead is too high, rewrite in C
+'''
+
+__all__ = ['error', 'open']
+
+import sqlite3
+import collections
+from operator import itemgetter
+
+error = sqlite3.DatabaseError
+
+class SQLhash(collections.MutableMapping):
+
+ def __init__(self, filename=':memory:', flags='r', mode=None):
+ # XXX add flag/mode handling
+ # c -- create if it doesn't exist
+ # n -- new empty
+ # w -- open existing
+ # r -- readonly
+
+ MAKE_SHELF = 'CREATE TABLE IF NOT EXISTS shelf (key TEXT NOT NULL, value TEXT NOT NULL)'
+ MAKE_INDEX = 'CREATE UNIQUE INDEX IF NOT EXISTS keyndx ON shelf (key)'
+ self.conn = sqlite3.connect(filename)
+ self.conn.text_factory = bytes
+ self.conn.execute(MAKE_SHELF)
+ self.conn.execute(MAKE_INDEX)
+ self.conn.commit()
+
+ def __len__(self):
+ GET_LEN = 'SELECT COUNT(*) FROM shelf'
+ return self.conn.execute(GET_LEN).fetchone()[0]
+
+ def keys(self):
+ return SQLhashKeysView(self)
+
+ def values(self):
+ return SQLhashValuesView(self)
+
+ def items(self):
+ return SQLhashItemsView(self)
+
+ def __iter__(self):
+ return iter(self.keys())
+
+ def __contains__(self, key):
+ GET_ITEM = 'SELECT value FROM shelf WHERE key = ?'
+ return self.conn.execute(GET_ITEM, (key,)).fetchone() is not None
+
+ def __getitem__(self, key):
+ GET_ITEM = 'SELECT value FROM shelf WHERE key = ?'
+ item = self.conn.execute(GET_ITEM, (key,)).fetchone()
+ if item is None:
+ raise KeyError(key)
+ return item[0]
+
+ def __setitem__(self, key, value): 
+ ADD_ITEM = 'REPLACE INTO shelf (key, value) VALUES (?,?)'
+ self.conn.execute(ADD_ITEM, (key, value))
+ #self.conn.commit()
+
+ def __delitem__(self, key):
+ if key not in self:
+ raise KeyError(key)
+ DEL_ITEM = 'DELETE FROM shelf WHERE key = ?' 
+ self.conn.execute(DEL_ITEM, (key,))
+ #self.conn.commit()
+
+ def update(self, items=(), **kwds):
+ if isinstance(items, collections.Mapping):
+ items = items.items()
+ UPDATE_ITEMS = 'REPLACE INTO shelf (key, value) VALUES (?, ?)'
+ self.conn.executemany(UPDATE_ITEMS, items)
+ self.conn.commit()
+ if kwds:
+ self.update(kwds)
+
+ def clear(self): 
+ CLEAR_ALL = 'DELETE FROM shelf; VACUUM;' 
+ self.conn.executescript(CLEAR_ALL)
+ self.conn.commit()
+
+ def close(self):
+ if self.conn is not None:
+ self.conn.commit()
+ self.conn.close()
+ self.conn = None
+
+ def __del__(self):
+ self.close() 
+
+class ListRepr:
+
+ def __repr__(self):
+ return repr(list(self)) 
+
+class SQLhashKeysView(collections.KeysView, ListRepr):
+ 
+ def __iter__(self):
+ GET_KEYS = 'SELECT key FROM shelf ORDER BY ROWID' # ??? does order by result in diff opcodes
+ return map(itemgetter(0), self._mapping.conn.cursor().execute(GET_KEYS))
+
+class SQLhashValuesView(collections.ValuesView, ListRepr):
+ 
+ def __iter__(self):
+ GET_VALUES = 'SELECT value FROM shelf ORDER BY ROWID'
+ return map(itemgetter(0), self._mapping.conn.cursor().execute(GET_VALUES))
+
+class SQLhashItemsView(collections.ValuesView, ListRepr):
+ 
+ def __iter__(self):
+ GET_ITEMS = 'SELECT key, value FROM shelf ORDER BY ROWID'
+ return iter(self._mapping.conn.cursor().execute(GET_ITEMS))
+
+def open(file=None, *args):
+ if file is not None:
+ return SQLhash(file)
+ return SQLhash()
+
+
+if __name__ in '__main___':
+ for d in SQLhash(), SQLhash('example'):
+ print(list(d), "start")
+ d['abc'] = 'lmno'
+ print(d['abc']) 
+ d['abc'] = 'rsvp'
+ d['xyz'] = 'pdq'
+ print(d.items())
+ print(d.values())
+ print(d.keys())
+ print(list(d), 'list')
+ d.update(p='x', q='y', r='z')
+ print(d.items())
+ 
+ del d['abc']
+ try:
+ print(d['abc'])
+ except KeyError:
+ pass
+ else:
+ raise Exception('oh noooo!')
+ 
+ try:
+ del d['abc']
+ except KeyError:
+ pass
+ else:
+ raise Exception('drat!')
+
+ print(list(d))
+ d.clear()
+ print(list(d))
+ d.update(p='x', q='y', r='z')
+ print(list(d))
+ d['xyz'] = 'pdq'
+
+ print()
+ d.close()


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /