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
5from appengine_wrappers import db
6from datastore_models import PersistentObjectStoreItem
7from environment import IsDevServer
8from future import Future
9from object_store import ObjectStore
10
11class _AsyncGetFuture(object):
12  def __init__(self, object_store, keys):
13    self._futures = dict(
14        (k, db.get_async(
15            PersistentObjectStoreItem.CreateKey(object_store._namespace, k)))
16         for k in keys)
17
18  def Get(self):
19    return dict((key, future.get_result().GetValue())
20                for key, future in self._futures.iteritems()
21                if future.get_result() is not None)
22
23class PersistentObjectStore(ObjectStore):
24  '''Stores data persistently using the AppEngine Datastore API.
25  '''
26  def __init__(self, namespace):
27    self._namespace = namespace
28
29  def SetMulti(self, mapping):
30    futures = []
31    for key, value in mapping.items():
32      futures.append(db.put_async(
33          PersistentObjectStoreItem.CreateItem(self._namespace, key, value)))
34    # If running the dev server, the futures don't complete until the server is
35    # *quitting*. This is annoying. Flush now.
36    if IsDevServer():
37      [future.wait() for future in futures]
38
39  def GetMulti(self, keys):
40    return Future(delegate=_AsyncGetFuture(self, keys))
41
42  def DelMulti(self, keys):
43    futures = []
44    for key in keys:
45      futures.append(db.delete_async(
46        PersistentObjectStoreItem.CreateKey(self._namespace, key)))
47    # If running the dev server, the futures don't complete until the server is
48    # *quitting*. This is annoying. Flush now.
49    if IsDevServer():
50      [future.wait() for future in futures]
51