Commits

Anonymous committed 2d6540a

Here we go.

Comments (0)

Files changed (2)

+A super simple datastore backed by sqlite. Should one day work like this http://bret.appspot.com/entry/how-friendfeed-uses-mysql
+"""
+Clavis is a very simple datastore.
+"""
+import cPickle as pickle
+import datetime
+import os.path
+import sqlite3
+import uuid
+import zlib
+
+class Clavis:
+    """
+    My super simple SQLITE storage based on
+    http://bret.appspot.com/entry/how-friendfeed-uses-mysql
+
+
+    >>> from clavis import Clavis, decompress #doctest: +ELLIPSIS
+    >>> c = Clavis(":memory:")
+    >>> c.put({'a':1})
+    >>> results = c._cursor.execute("SELECT * from entities").fetchall()
+    >>> r = results[0]
+    >>> decompress(r['body']) == c.get(r['id'])
+    True
+    """
+    
+    conn = None
+    _cursor = None
+
+    def __init__(self, db=None):
+        self.conn = sqlite3.connect(db)
+        self.conn.row_factory = sqlite3.Row
+        if not os.path.isfile(db) or db == ":memory:":
+            self._create(self.conn)
+
+    def _create(self, conn):
+        """
+        Create the basic table layout.
+        """
+        conn.execute("""
+        CREATE TABLE entities (
+           added_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+           id BINARY(16) NOT NULL,
+           updated TIMESTAMP NOT NULL,
+           body BLOB,
+           UNIQUE (id));""")
+        conn.execute("""
+        CREATE INDEX idx_updated ON entities (updated);
+        """)
+
+    def put(self, body):
+        """
+        Save an entity it's body being a dictionary.
+        """
+        sql = """
+        INSERT INTO entities (id, updated, body) VALUES (?,?,?)
+        """
+        id=uuid.uuid1().hex
+        updated = datetime.datetime.now()
+        body.update(id=id, updated=updated)
+        if not self._cursor:
+            self._cursor = self.conn.cursor()
+        self._cursor.execute(sql, (id, updated, compress(body)))
+        self.conn.commit()
+
+    def get(self, id):
+        sql = """
+        SELECT body FROM entities WHERE id = ? 
+        """
+        if not self._cursor:
+            self._cursor = self.conn.cursor()
+        self._cursor.execute(sql, (id,))
+        r = self._cursor.fetchone()
+        return decompress(r['body'])
+
+    
+def compress(obj):
+    """
+    Return a buffer containing the zlib-compressed form 
+    of the pickled object given in ``obj``.
+    """
+    # buffer matches sqlite's BLOB in Python!
+    return buffer(zlib.compress(pickle.dumps(obj)))
+
+def decompress(buff):
+    """
+    Restore the object from the given buffer.
+    """
+    return pickle.loads(zlib.decompress(buff))
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
+