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