Commits

pfw  committed 72475ea

Latest

  • Participants
  • Parent commits bf987c7

Comments (0)

Files changed (1)

File flask_durus/durus.py

 from durus.persistent import Persistent, PersistentObject
 from durus.persistent_list import PersistentList
 from durus.persistent_dict import PersistentDict
-import durus.btree 
+import durus.btree
 
 from UserDict import IterableUserDict
 
 
 from datetime import datetime
 
+
 def with_getters_and_setters(klass):
     """
     Add getters and setters to the persistent class
     """
     add_getters_and_setters(klass)
     return klass
-    
+
 
 class Durus(IterableUserDict):
     connections = []
-    
+
     def __init__(self, app=None):
         if app is not None:
             self.app = app
         ctx = _request_ctx_stack.top
         if ctx is not None:
             return self._get_db(ctx).get_root()
-    
+
     def _get_db(self, ctx):
         if not hasattr(ctx, 'durus_db'):
             ctx.durus_db = self.connect()
         return ctx.durus_db
 
-
     def setup_app(self, app, browser=None):
         self.app = app
         self.app.config.setdefault('DURUS_PORT', 2972)
         self.app.teardown_request(self.teardown_request)
         self.app.before_request(self.before_request)
         if browser:
+            print "browse on db here"
             browsedb_on_connection(self, app, browser)
 
     def connect(self):
         ctx = _request_ctx_stack.top
         if ctx is not None:
             # walk list of changed items
-            db = self._get_db(ctx) 
-            changed = db.changed.values()
-            for changed in changed:
-                # call commit if definied on item
-                print "changed:", changed
-                on_commit = getattr(changed, 'on_commit', None)
-                if on_commit:
-                    print "changed:", changed, "calling on_commit"
-                    on_commit()
-
+            db = self._get_db(ctx)
             return db.commit()
 
     @property
         if ctx is not None:
             return self._get_db(ctx)
 
+
 class BTree(durus.btree.BTree):
-    def _with_limit(self, method, *args,  **kws):
+    def _with_limit(self, method, *args, **kws):
         limit = kws.pop('limit', None)
         for idx, item in enumerate(method(self, *args, **kws)):
-            if limit == None or idx < limit:
+            if limit is None or idx < limit:
                 yield item
             else:
                 raise StopIteration()
         If closed is false, generate all items with keys greater than the
         given key.
         """
-        return self._with_limit(durus.btree.BTree.items_from, 
-                key, closed=closed, limit=limit)
-
+        return self._with_limit(
+            durus.btree.BTree.items_from,
+            key, closed=closed, limit=limit)
 
     def items_backward_from(self, key, closed=False, limit=None):
         """(key, closed=False, limit=None) -> generator
         If closed is true, generate in reverse order all items with keys
         less than the given key.
         """
-        return self._with_limit(durus.btree.BTree.items_backward_from, 
-                key, closed=closed, limit=limit)
+        return self._with_limit(
+            durus.btree.BTree.items_backward_from,
+            key, closed=closed, limit=limit)
 
     def items_range(self, start, end, closed_start=True, closed_end=False, limit=None):
         """(start, end, closed_start=True, closed_end=False, limit=None) -> generator
         If closed_end is true, include the item with the end key,
         if it is present.
         """
-        return self._with_limit(durus.btree.BTree.items_range, 
-                start, end, closed_start=closed_start, closed_end=closed_end, 
-                limit=limit)
+        return self._with_limit(
+            durus.btree.BTree.items_range,
+            start, end, closed_start=closed_start, closed_end=closed_end,
+            limit=limit)
+
 
 def browsedb_on_connection(db, app, url_prefix):
     """(db:Durus, app:Flask, url_prefix:str)
     Add a route for a db browser to the app at url_prefix.
     """
+    print "url_prefix:", url_prefix
     @app.route("/%s" % url_prefix)
     def browseroot():
         """
         Redirect to the root object
         """
+        print 'root'
         return redirect(url_for('browsedb', oid=0))
 
     @app.route("/%s/<int:oid>" % url_prefix)
     def browsedb(oid):
-        from flask import url_for
+        try:
+            print "in browsedb"
+            from flask import url_for
 
-        def persistent_vars(obj):
-            """() -> dict
-            This is like the built-in vars() function, except that it also works
-            for PersistentObject instances or other instances that use slots for
-            data attributes.
-            """
-            if hasattr(obj, '__getstate__'):
-                return obj.__getstate__() or {}
-            elif hasattr(obj, '__dict__'):
-                return vars(obj)
-            else:
-                result = {}
-                for name in obj.__slots__:
-                    if hasattr(obj, name):
-                        result[name] = getattr(obj, name)
-                return result
+            def persistent_vars(obj):
+                """() -> dict
+                This is like the built-in vars() function, except that it also works
+                for PersistentObject instances or other instances that use slots for
+                data attributes.
+                """
+                if hasattr(obj, '__getstate__'):
+                    return obj.__getstate__() or {}
+                elif hasattr(obj, '__dict__'):
+                    return vars(obj)
+                else:
+                    result = {}
+                    for name in obj.__slots__:
+                        if hasattr(obj, name):
+                            result[name] = getattr(obj, name)
+                    return result
+            print "value:", value
+            value = db.connection.get(oid)
 
-        value = db.connection.get(oid)
+            def format(value):
+                if isinstance(value, PersistentObject):
+                    ret = """<a href="%s">%s</a>""" % (
+                        url_for("browsedb", oid=value._p_format_durus_id()),
+                        repr(value).replace('<', '&lt;').replace('>', '&gt;'))
+                elif isinstance(value, list):
+                    ret = '[' + ', '.join([format(v) for v in value]) + ']'
+                elif isinstance(value, tuple):
+                    ret = '(' + ', '.join([format(v) for v in value]) + ')'
+                elif isinstance(value, dict):
+                    ret = '<div style="margin-left:2em">{'
+                    for k, v in value.items():
+                        ret += '<div>' + format(k) + ' : ' + format(v) + '</div>'
+                    ret += '}</div>'
+                else:
+                    ret = repr(value).replace('<', '&lt;').replace('>', '&gt;')
 
-        def format(value):
-            if isinstance(value, PersistentObject):
-                ret = """<a href="%s">%s</a>""" % (url_for("browsedb", oid=value._p_format_oid()), 
-                        repr(value).replace('<', '&lt;').replace('>', '&gt;'))
-            elif isinstance(value, list):
-                ret = '[' + ', '.join([format(v) for v in value]) + ']'
-            elif isinstance(value, tuple):
-                ret = '(' + ', '.join([format(v) for v in value]) + ')'
-            elif isinstance(value, dict):
-                ret = '<div style="margin-left:2em">{'
-                for k, v in value.items():
-                    ret += '<div>' + format(k) + ' : ' + format(v) + '</div>'
-                ret += '}</div>'
-            else:
-                ret = repr(value).replace('<', '&lt;').replace('>','&gt;') 
-
-            return ret
-
-        return """<html><head><title>%s</title></head><body><div>%s</div><div>%s</div></body></html>""" % (repr(value).replace('<', '&lt;').replace('>','&gt;'), repr(value).replace('<', '&lt;').replace('>','&gt;'), format(persistent_vars(value)))
+                return ret
+            try:
+                return """<html><head><title>%s</title></head><body><div>%s</div><div>%s</div></body></html>""" % (repr(value).replace('<', '&lt;').replace('>', '&gt;'), repr(value).replace('<', '&lt;').replace('>', '&gt;'), format(persistent_vars(value)))
+            except Exception as e:
+                print e
+        except Exception as e:
+            print e
 
 class Index(BTree):
-    def _with_limit(self, method, *args,  **kws):
+    """
+    An index holds items  by keys for quick searching.
+
+    key -> PersistentList[item, item, ....]
+    """
+
+    def _with_limit(self, method, *args, **kws):
         """
-        Overload this so that only the item returned is the object as the last item in the index key.
+        Overload this so that limit is respected into the list of items for each key
         """
-        for key, value in BTree._with_limit(self, method, *args, **kws):
-            yield key[-1]
+        limit = kws.pop('limit', None)
+        count = 0
+        for key, item_list in method(self, *args, **kws):
+            for item in item_list:
+                if limit is None or count < limit:
+                    count += 1
+                    yield item
+                else:
+                    raise StopIteration()
 
 class IndexedKeyed(Keyed):
     """
     """
     KEY_PREFIX = 'key_for_'
     KEY_PREFIX_LEN = len(KEY_PREFIX)
-    
+
     _keep_is = spec(either(None, "IndexedKeep"), "Pointer to the keep this item is in")
     _indexes_is = spec(PersistentDict, "Pointers to the indexes this item exists in")
 
     def __init__(self):
-        print "in init"
+        #print "in init"
         Keyed.__init__(self)
         self._indexes = PersistentDict()
         self._keep = None
-    
+
     def _index(self):
         """()
         Return index keys for this item based on key functions
         """()
         Get all index keys and update in the keep
         """
-        print "update indexes"
+        #print "update indexes"
         if self._keep:
             # remove existing index keys
             for name, existing_key in self._indexes.items():
                 try:
-                    del(self._keep._indexes[name][existing_key])
+                    self._keep._indexes[name][existing_key].remove(self)
                     # remove index if empty
-                    if not self._keep._indexes[name]:
-                        del(self._keep._indexes[name])
+                    if not self._keep._indexes[name][existing_key]:
+                        del(self._keep._indexes[name][existing_key])
                 except KeyError:
                     """ no index """
                     # TODO - clean up, should check for index
-            
+
             # add current values
             for name, key in self._index():
-                if type(key) == tuple:
-                    key = list(key)
-                if type(key) != list:
-                    key = [key]
-                # add item to end of key to ensure uniqueness
-                key.append(self)
-
-                key=tuple(key)
-                print "key [%s]" % str(key)
-                self._keep._indexes.setdefault(name, Index())[key] = None
+                self._keep._indexes.setdefault(name, Index()).setdefault(key, PersistentList()).append(self)
 
                 # store pointer back into index
                 self._indexes[name] = key
 
+
 class IndexedKeep(Keep):
     """
     A Keep that maintains indexes for quick access to the values.
     """
-    
+
     def __init__(self, value_spec=Keyed, mapping_class=BTree, counter_class=Counter):
         Keep.__init__(self, value_spec, mapping_class, counter_class)
         self._indexes = PersistentDict()
         Keep.add(self, value)
         value._keep = self
 
-
     def by(self, name):
         """(name:str) -> BTree
         Get an index into the keep
         """
         return self._indexes.get(name, None)
 
+    def available_indexes(self):
+        """ -> list(str)
+        Return a list of indexes available.
+        """
+        return self._indexes.keys()