Index: chrome/common/extensions/docs/server2/object_store_creator.py |
diff --git a/chrome/common/extensions/docs/server2/object_store_creator.py b/chrome/common/extensions/docs/server2/object_store_creator.py |
index c21627331e235acd2677c795bb77e2d6008a87f4..2f797c52755e1abdb8f2deb82f17018d6e11b55f 100644 |
--- a/chrome/common/extensions/docs/server2/object_store_creator.py |
+++ b/chrome/common/extensions/docs/server2/object_store_creator.py |
@@ -2,88 +2,85 @@ |
# Use of this source code is governed by a BSD-style license that can be |
# found in the LICENSE file. |
+from appengine_wrappers import GetAppVersion |
from cache_chain_object_store import CacheChainObjectStore |
from memcache_object_store import MemcacheObjectStore |
from test_object_store import TestObjectStore |
from persistent_object_store import PersistentObjectStore |
-class ObjectStoreCreator(object): |
- class Factory(object): |
- '''Parameters: |
- - |branch| The branch to create object stores for. This becomes part of the |
- namespace for the object stores that are created. |
- - |start_empty| Whether the caching object store that gets created should |
- start empty, or start with the content of its delegate object stores. |
- ''' |
- def __init__(self, app_version, branch): |
- self._app_version = app_version |
- self._branch = branch |
- |
- def Create(self, cls, store_type=None): |
- return ObjectStoreCreator(cls, |
- self._app_version, |
- self._branch, |
- store_type=store_type) |
+_unspecified = object() |
- class SharedFactory(object): |
- '''A |Factory| for creating object stores shared across branches. |
- ''' |
- def __init__(self, app_version): |
- # TODO(kalman): Pass in (app_version, None) here. |
- self._factory = ObjectStoreCreator.Factory(app_version, 'shared') |
- |
- def Create(self, cls, store_type=None): |
- return self._factory.Create(cls, store_type=store_type) |
+class ObjectStoreCreator(object): |
+ '''Creates ObjectStores with a namespacing and behaviour configuration. |
- class GlobalFactory(object): |
- '''A |Factory| for creating object stores shared across all branches and |
- app versions. |
- ''' |
- def __init__(self): |
- # TODO(kalman): Pass in (None, None) here. |
- self._factory = ObjectStoreCreator.Factory('all', 'shared') |
+ The initial configuration is specified on object store construction. When |
+ creating ObjectStores via Create this configuration can be overridden (or |
+ via the variants of Create which do this automatically). |
+ ''' |
+ def __init__(self, |
+ channel, |
+ start_empty=_unspecified, |
+ # Override for testing. A custom ObjectStore type to construct |
+ # on Create(). Useful with TestObjectStore, for example. |
+ store_type=None, |
+ # Override for testing. Whether the ObjectStore type specified |
+ # with |store_type| should be wrapped e.g. with Caching. This is |
+ # useful to override when specific state tests/manipulations are |
+ # being done on the underlying object store. |
+ disable_wrappers=False): |
+ self._channel = channel |
+ if start_empty is _unspecified: |
+ raise ValueError('start_empty must be specified (typically False)') |
+ self._start_empty = start_empty |
+ self._store_type = store_type |
+ if disable_wrappers and store_type is None: |
+ raise ValueError('disable_wrappers much specify a store_type') |
+ self._disable_wrappers = disable_wrappers |
- def Create(self, cls, store_type=None): |
- return self._factory.Create(cls, store_type=store_type) |
+ @staticmethod |
+ def ForTest(start_empty=False, |
+ store_type=TestObjectStore, |
+ disable_wrappers=True): |
+ return ObjectStoreCreator('test', |
+ start_empty=start_empty, |
+ store_type=store_type, |
+ disable_wrappers=disable_wrappers) |
- class TestFactory(object): |
- '''A |Factory| for creating object stores for tests, with fake defaults. |
- ''' |
- def __init__(self, |
- # TODO(kalman): make these version=None and branch=None. |
- version='test-version', |
- branch='test-branch', |
- store_type=TestObjectStore): |
- self._factory = ObjectStoreCreator.Factory(version, branch) |
- self._store_type = store_type |
+ def Create(self, |
+ cls, |
+ category=None, |
+ # Override any of these for a custom configuration. |
+ start_empty=_unspecified, |
+ channel=_unspecified, |
+ app_version=_unspecified): |
+ # Resolve namespace components. |
+ if start_empty is not _unspecified: |
+ start_empty = bool(start_empty) |
+ else: |
+ start_empty = self._start_empty |
+ if channel is _unspecified: |
+ channel = self._channel |
+ if app_version is _unspecified: |
+ app_version = GetAppVersion() |
- def Create(self, cls): |
- return self._factory.Create(cls, store_type=self._store_type) |
+ # Reserve & and = for namespace separators. |
+ for component in (category, channel, app_version): |
+ if component and ('&' in component or '=' in component): |
+ raise ValueError('%s cannot be used in a namespace') |
- def __init__(self, cls, app_version, branch, store_type=None): |
- '''Creates stores with a top-level namespace given by the name of |cls| |
- combined with |branch|. Set an explicit |store_type| if necessary for tests. |
+ namespace = '&'.join( |
+ '%s=%s' % (key, value) |
+ for key, value in (('class', cls.__name__), |
+ ('category', category), |
+ ('channel', channel), |
+ ('app_version', app_version)) |
+ if value is not None) |
- By convention this should be the name of the class which owns the object |
- store. If a class needs multiple object stores it should use Create with the |
- |category| argument. |
- ''' |
- assert isinstance(cls, type) |
- assert not cls.__name__[0].islower() # guard against non-class types |
- self._name = '%s/%s@%s' % (app_version, cls.__name__, branch) |
- self._store_type = store_type |
+ if self._disable_wrappers: |
+ return self._store_type(namespace, start_empty=start_empty) |
- def Create(self, category=None, start_empty=False): |
- '''Creates a new object store with the top namespace given in the |
- constructor with an optional |category| for classes that need multiple |
- object stores (e.g. one for stat and one for read). |
- ''' |
- namespace = self._name |
- if category is not None: |
- assert not any(c.isdigit() for c in category) |
- namespace = '%s/%s' % (namespace, category) |
if self._store_type is not None: |
- return self._store_type(namespace, start_empty=start_empty) |
- return CacheChainObjectStore( |
- (MemcacheObjectStore(namespace), PersistentObjectStore(namespace)), |
- start_empty=start_empty) |
+ chain = (self._store_type(namespace),) |
+ else: |
+ chain = (MemcacheObjectStore(namespace), PersistentObjectStore(namespace)) |
+ return CacheChainObjectStore(chain, start_empty=start_empty) |