OLD | NEW |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 from appengine_wrappers import GetAppVersion | 5 from appengine_wrappers import GetAppVersion |
6 from cache_chain_object_store import CacheChainObjectStore | 6 from cache_chain_object_store import CacheChainObjectStore |
7 from memcache_object_store import MemcacheObjectStore | 7 from memcache_object_store import MemcacheObjectStore |
8 from test_object_store import TestObjectStore | 8 from test_object_store import TestObjectStore |
9 from persistent_object_store import PersistentObjectStore | 9 from persistent_object_store import PersistentObjectStore |
10 | 10 |
11 _unspecified = object() | 11 _unspecified = object() |
12 | 12 |
13 class ObjectStoreCreator(object): | 13 class ObjectStoreCreator(object): |
14 '''Creates ObjectStores with a namespacing and behaviour configuration. | 14 '''Creates ObjectStores with a namespacing and behaviour configuration. |
15 | 15 |
16 The initial configuration is specified on object store construction. When | 16 The initial configuration is specified on object store construction. When |
17 creating ObjectStores via Create this configuration can be overridden (or | 17 creating ObjectStores via Create this configuration can be overridden (or |
18 via the variants of Create which do this automatically). | 18 via the variants of Create which do this automatically). |
19 ''' | 19 ''' |
20 def __init__(self, | 20 def __init__(self, |
21 channel, | |
22 # TODO(kalman): rename start_dirty? | 21 # TODO(kalman): rename start_dirty? |
23 start_empty=_unspecified, | 22 start_empty=_unspecified, |
24 # Override for testing. A custom ObjectStore type to construct | 23 # Override for testing. A custom ObjectStore type to construct |
25 # on Create(). Useful with TestObjectStore, for example. | 24 # on Create(). Useful with TestObjectStore, for example. |
26 store_type=None, | 25 store_type=None, |
27 # Override for testing. Whether the ObjectStore type specified | 26 # Override for testing. Whether the ObjectStore type specified |
28 # with |store_type| should be wrapped e.g. with Caching. This is | 27 # with |store_type| should be wrapped e.g. with Caching. This is |
29 # useful to override when specific state tests/manipulations are | 28 # useful to override when specific state tests/manipulations are |
30 # being done on the underlying object store. | 29 # being done on the underlying object store. |
31 disable_wrappers=False): | 30 disable_wrappers=False): |
32 self._channel = channel | |
33 if start_empty is _unspecified: | 31 if start_empty is _unspecified: |
34 raise ValueError('start_empty must be specified (typically False)') | 32 raise ValueError('start_empty must be specified (typically False)') |
35 self._start_empty = start_empty | 33 self._start_empty = start_empty |
36 self._store_type = store_type | 34 self._store_type = store_type |
37 if disable_wrappers and store_type is None: | 35 if disable_wrappers and store_type is None: |
38 raise ValueError('disable_wrappers much specify a store_type') | 36 raise ValueError('disable_wrappers much specify a store_type') |
39 self._disable_wrappers = disable_wrappers | 37 self._disable_wrappers = disable_wrappers |
40 | 38 |
41 @staticmethod | 39 @staticmethod |
42 def ForTest(start_empty=False, | 40 def ForTest(start_empty=False, |
43 store_type=TestObjectStore, | 41 store_type=TestObjectStore, |
44 disable_wrappers=True): | 42 disable_wrappers=True): |
45 return ObjectStoreCreator('test', | 43 return ObjectStoreCreator(start_empty=start_empty, |
46 start_empty=start_empty, | |
47 store_type=store_type, | 44 store_type=store_type, |
48 disable_wrappers=disable_wrappers) | 45 disable_wrappers=disable_wrappers) |
49 | 46 |
50 def Create(self, | 47 def Create(self, |
51 cls, | 48 cls, |
52 category=None, | 49 category=None, |
53 # Override any of these for a custom configuration. | 50 # Override any of these for a custom configuration. |
54 start_empty=_unspecified, | 51 start_empty=_unspecified, |
55 channel=_unspecified, | |
56 app_version=_unspecified): | 52 app_version=_unspecified): |
57 # Resolve namespace components. | 53 # Resolve namespace components. |
58 if start_empty is not _unspecified: | 54 if start_empty is not _unspecified: |
59 start_empty = bool(start_empty) | 55 start_empty = bool(start_empty) |
60 else: | 56 else: |
61 start_empty = self._start_empty | 57 start_empty = self._start_empty |
62 if channel is _unspecified: | |
63 channel = self._channel | |
64 if app_version is _unspecified: | 58 if app_version is _unspecified: |
65 app_version = GetAppVersion() | 59 app_version = GetAppVersion() |
66 | 60 |
67 # Reserve & and = for namespace separators. | 61 # Reserve & and = for namespace separators. |
68 for component in (category, channel, app_version): | 62 for component in (category, app_version): |
69 if component and ('&' in component or '=' in component): | 63 if component and ('&' in component or '=' in component): |
70 raise ValueError('%s cannot be used in a namespace') | 64 raise ValueError('%s cannot be used in a namespace') |
71 | 65 |
72 namespace = '&'.join( | 66 namespace = '&'.join( |
73 '%s=%s' % (key, value) | 67 '%s=%s' % (key, value) |
74 for key, value in (('class', cls.__name__), | 68 for key, value in (('class', cls.__name__), |
75 ('category', category), | 69 ('category', category), |
76 ('channel', channel), | |
77 ('app_version', app_version)) | 70 ('app_version', app_version)) |
78 if value is not None) | 71 if value is not None) |
79 | 72 |
80 if self._disable_wrappers: | 73 if self._disable_wrappers: |
81 return self._store_type(namespace, start_empty=start_empty) | 74 return self._store_type(namespace, start_empty=start_empty) |
82 | 75 |
83 if self._store_type is not None: | 76 if self._store_type is not None: |
84 chain = (self._store_type(namespace),) | 77 chain = (self._store_type(namespace),) |
85 else: | 78 else: |
86 chain = (MemcacheObjectStore(namespace), PersistentObjectStore(namespace)) | 79 chain = (MemcacheObjectStore(namespace), PersistentObjectStore(namespace)) |
87 return CacheChainObjectStore(chain, start_empty=start_empty) | 80 return CacheChainObjectStore(chain, start_empty=start_empty) |
OLD | NEW |