OLD | NEW |
---|---|
(Empty) | |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 | |
5 from appengine_wrappers import db | |
6 import cPickle | |
7 from future import Future | |
8 import logging | |
9 from object_store import ObjectStore | |
10 | |
11 # XXX(kalman): this appears to be global somehow. I don't know. | |
12 # Figure it out. | |
13 class _Item(db.Model): | |
14 '''The generic data store model to use for all model types. | |
15 ''' | |
16 key_ = db.StringProperty() | |
17 pickled_value = db.BlobProperty() | |
18 | |
19 class _AsyncGetFuture(object): | |
20 def __init__(self, object_store, keys): | |
21 self._object_store = object_store | |
22 self._futures = dict((k, db.get_async(object_store._ToItemKey(k))) | |
23 for k in keys) | |
24 | |
25 def Get(self): | |
26 def has_result(key, future): | |
27 item_key = self._object_store._ToItemKeyPath(key) | |
28 if future.get_result() is not None: | |
29 logging.warning('%s HAS a value!' % item_key) | |
30 return True | |
31 else: | |
32 logging.warning('%s has no value' % item_key) | |
33 return False | |
34 return dict((key, cPickle.loads(future.get_result().pickled_value)) | |
35 for key, future in self._futures.iteritems() | |
36 if has_result(key, future)) | |
37 | |
38 class PersistentObjectStore(ObjectStore): | |
39 '''Stores data persistently using the AppEngine Datastore API. | |
40 ''' | |
41 def __init__(self, namespace): | |
42 self._namespace = namespace | |
43 | |
44 def SetMulti(self, mapping): | |
45 futures = [] | |
46 for k, v in mapping.items(): | |
47 logging.warning('Setting %s' % self._ToItemKeyPath(k)) | |
48 item = _Item(key_=self._ToItemKeyPath(k), | |
方觉(Fang Jue)
2013/04/16 14:26:49
you probably need to use key_name=... here so that
| |
49 pickled_value=cPickle.dumps(v)) | |
50 futures.append(db.put_async(item)) | |
51 for future in futures: | |
52 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
| |
53 | |
54 def GetMulti(self, keys): | |
55 # XXX(kalman): make this work: | |
56 return Future(delegate=_AsyncGetFuture(self, keys)) | |
57 | |
58 def DelMulti(self, keys): | |
59 futures = [] | |
60 for key in keys: | |
61 futures.append(db.delete_async(self._ToItemKey(key))) | |
62 for future in futures: | |
63 future.wait() | |
64 | |
65 def _ToItemKey(self, key): | |
66 # XXX(kalman): users of this method aren't working. Ugh. | |
67 return db.Key.from_path('_Item', self._ToItemKeyPath(key)) | |
68 | |
69 def _ToItemKeyPath(self, key): | |
70 return '%s/%s' % (self._namespace, key) | |
OLD | NEW |