Index: chrome/common/extensions/docs/server2/persistent_object_store.py |
diff --git a/chrome/common/extensions/docs/server2/persistent_object_store.py b/chrome/common/extensions/docs/server2/persistent_object_store.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..28f7e11f3095db8b1524a28b27bb45894ec62374 |
--- /dev/null |
+++ b/chrome/common/extensions/docs/server2/persistent_object_store.py |
@@ -0,0 +1,70 @@ |
+# Copyright 2013 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+from appengine_wrappers import db |
+import cPickle |
+from future import Future |
+import logging |
+from object_store import ObjectStore |
+ |
+# XXX(kalman): this appears to be global somehow. I don't know. |
+# Figure it out. |
+class _Item(db.Model): |
+ '''The generic data store model to use for all model types. |
+ ''' |
+ key_ = db.StringProperty() |
+ pickled_value = db.BlobProperty() |
+ |
+class _AsyncGetFuture(object): |
+ def __init__(self, object_store, keys): |
+ self._object_store = object_store |
+ self._futures = dict((k, db.get_async(object_store._ToItemKey(k))) |
+ for k in keys) |
+ |
+ def Get(self): |
+ def has_result(key, future): |
+ item_key = self._object_store._ToItemKeyPath(key) |
+ if future.get_result() is not None: |
+ logging.warning('%s HAS a value!' % item_key) |
+ return True |
+ else: |
+ logging.warning('%s has no value' % item_key) |
+ return False |
+ return dict((key, cPickle.loads(future.get_result().pickled_value)) |
+ for key, future in self._futures.iteritems() |
+ if has_result(key, future)) |
+ |
+class PersistentObjectStore(ObjectStore): |
+ '''Stores data persistently using the AppEngine Datastore API. |
+ ''' |
+ def __init__(self, namespace): |
+ self._namespace = namespace |
+ |
+ def SetMulti(self, mapping): |
+ futures = [] |
+ for k, v in mapping.items(): |
+ logging.warning('Setting %s' % self._ToItemKeyPath(k)) |
+ item = _Item(key_=self._ToItemKeyPath(k), |
方觉(Fang Jue)
2013/04/16 14:26:49
you probably need to use key_name=... here so that
|
+ pickled_value=cPickle.dumps(v)) |
+ futures.append(db.put_async(item)) |
+ for future in futures: |
+ future.wait() |
方觉(Fang Jue)
2013/04/16 14:26:49
why not use synchronous api here?
not at google - send to devlin
2013/04/17 18:00:50
So that while each of these is wait()ing the other
|
+ |
+ def GetMulti(self, keys): |
+ # XXX(kalman): make this work: |
+ return Future(delegate=_AsyncGetFuture(self, keys)) |
+ |
+ def DelMulti(self, keys): |
+ futures = [] |
+ for key in keys: |
+ futures.append(db.delete_async(self._ToItemKey(key))) |
+ for future in futures: |
+ future.wait() |
+ |
+ def _ToItemKey(self, key): |
+ # XXX(kalman): users of this method aren't working. Ugh. |
+ return db.Key.from_path('_Item', self._ToItemKeyPath(key)) |
+ |
+ def _ToItemKeyPath(self, key): |
+ return '%s/%s' % (self._namespace, key) |