add permissive cache
This commit is contained in:
@ -73,7 +73,7 @@ class SubConfig(object):
|
||||
|
||||
def cfgimpl_reset_cache(self,
|
||||
only_expired=False,
|
||||
only=('values', 'settings'),
|
||||
only=('values', 'properties', 'permissives', 'settings'),
|
||||
opt=None,
|
||||
path=None):
|
||||
"""reset all settings in cache
|
||||
@ -84,13 +84,15 @@ class SubConfig(object):
|
||||
context = self._cfgimpl_get_context()
|
||||
if 'values' in only:
|
||||
values = context.cfgimpl_get_values()
|
||||
if 'settings' in only:
|
||||
if 'settings' in only or 'properties' in only or 'permissives' in only:
|
||||
settings = context.cfgimpl_get_settings()
|
||||
if only_expired:
|
||||
if 'values' in only:
|
||||
values._p_.reset_expired_cache(int(time()))
|
||||
if 'settings' in only:
|
||||
if 'settings' in only or 'properties' in only:
|
||||
settings._p_.reset_expired_cache(int(time()))
|
||||
if 'settings' in only or 'permissives' in only:
|
||||
settings._pp_.reset_expired_cache(int(time()))
|
||||
elif not None in (opt, path):
|
||||
if opt.__class__.__name__ == 'DynOptionDescription':
|
||||
descr = context.cfgimpl_get_description()
|
||||
@ -102,8 +104,10 @@ class SubConfig(object):
|
||||
path = subpath + '.' + spath[-1] + suffix
|
||||
if 'values' in only:
|
||||
values._p_.delcache(path)
|
||||
if 'settings' in only:
|
||||
if 'settings' in only or 'properties' in only:
|
||||
settings._p_.delcache(path)
|
||||
if 'settings' in only or 'permissives' in only:
|
||||
settings._pp_.delcache(path)
|
||||
elif not isinstance(opt, DynSymLinkOption) and opt._is_subdyn():
|
||||
descr = context.cfgimpl_get_description()
|
||||
spath = path.split('.')
|
||||
@ -126,23 +130,33 @@ class SubConfig(object):
|
||||
path += '.' + spath3 + suffix
|
||||
if 'values' in only:
|
||||
values._p_.delcache(path)
|
||||
if 'settings' in only:
|
||||
if 'settings' in only or 'properties' in only:
|
||||
settings._p_.delcache(path)
|
||||
if 'settings' in only or 'permissives' in only:
|
||||
settings._pp_.delcache(path)
|
||||
else:
|
||||
if 'values' in only:
|
||||
values._p_.delcache(path)
|
||||
if 'settings' in only:
|
||||
if 'settings' in only or 'permissives' in only:
|
||||
settings._p_.delcache(path)
|
||||
if 'settings' in only or 'permissives' in only:
|
||||
settings._pp_.delcache(path)
|
||||
for option in getattr(opt, '_dependencies', []):
|
||||
if 'values' in only:
|
||||
option.reset_cache(opt, values, 'values')
|
||||
if 'settings' in only:
|
||||
option.reset_cache(opt, settings, 'settings')
|
||||
else:
|
||||
if 'properties' in only:
|
||||
option.reset_cache(opt, settings, 'properties')
|
||||
if 'permissives' in only:
|
||||
option.reset_cache(opt, settings, 'permissives')
|
||||
else:
|
||||
if 'values' in only:
|
||||
values._p_.reset_all_cache()
|
||||
if 'settings' in only:
|
||||
settings._p_.reset_all_cache()
|
||||
settings._pp_.reset_all_cache()
|
||||
|
||||
def cfgimpl_get_home_by_path(self, path, force_permissive=False,
|
||||
returns_raise=False, _setting_properties=undefined):
|
||||
@ -752,8 +766,8 @@ class _CommonConfig(SubConfig):
|
||||
session))
|
||||
config.cfgimpl_get_settings()._p_.set_modified_properties(self.cfgimpl_get_settings(
|
||||
)._p_.get_modified_properties())
|
||||
config.cfgimpl_get_settings()._p_.set_modified_permissives(self.cfgimpl_get_settings(
|
||||
)._p_.get_modified_permissives())
|
||||
config.cfgimpl_get_settings()._pp_.set_modified_permissives(self.cfgimpl_get_settings(
|
||||
)._pp_.get_modified_permissives())
|
||||
return config
|
||||
|
||||
|
||||
@ -781,7 +795,7 @@ class Config(_CommonConfig):
|
||||
self._impl_settings = force_settings
|
||||
self._impl_values = Values(self, force_values)
|
||||
else:
|
||||
settings, values = get_storages(self, session_id, persistent)
|
||||
properties, permissives, values = get_storages(self, session_id, persistent)
|
||||
if name is undefined:
|
||||
name = 'config'
|
||||
if session_id is not None:
|
||||
@ -790,7 +804,7 @@ class Config(_CommonConfig):
|
||||
raise ValueError(_("name is mandatory for the config").format(name))
|
||||
if name is not None and not valid_name(name): # pragma: optional cover
|
||||
raise ValueError(_("invalid name: {0} for config").format(name))
|
||||
self._impl_settings = Settings(self, settings)
|
||||
self._impl_settings = Settings(self, properties, permissives)
|
||||
self._impl_values = Values(self, values)
|
||||
super(Config, self).__init__(descr, weakref.ref(self))
|
||||
self._impl_meta = None
|
||||
@ -829,8 +843,8 @@ class GroupConfig(_CommonConfig):
|
||||
raise ConflictError(_('config name must be uniq in '
|
||||
'groupconfig for {0}').format(name))
|
||||
self._impl_children = children
|
||||
settings, values = get_storages(self, session_id, persistent)
|
||||
self._impl_settings = Settings(self, settings)
|
||||
properties, permissives, values = get_storages(self, session_id, persistent)
|
||||
self._impl_settings = Settings(self, properties, permissives)
|
||||
self._impl_values = Values(self, values)
|
||||
super(GroupConfig, self).__init__(_descr, weakref.ref(self))
|
||||
self._impl_meta = None
|
||||
|
@ -310,9 +310,9 @@ class Property(object):
|
||||
#____________________________________________________________
|
||||
class Settings(object):
|
||||
"``config.Config()``'s configuration options settings"
|
||||
__slots__ = ('context', '_owner', '_p_', '__weakref__')
|
||||
__slots__ = ('context', '_owner', '_p_', '_pp_', '__weakref__')
|
||||
|
||||
def __init__(self, context, storage):
|
||||
def __init__(self, context, properties, permissives):
|
||||
"""
|
||||
initializer
|
||||
|
||||
@ -325,7 +325,8 @@ class Settings(object):
|
||||
# generic owner
|
||||
self._owner = owners.user
|
||||
self.context = weakref.ref(context)
|
||||
self._p_ = storage
|
||||
self._p_ = properties
|
||||
self._pp_ = permissives
|
||||
|
||||
def _getcontext(self):
|
||||
"""context could be None, we need to test it
|
||||
@ -370,7 +371,7 @@ class Settings(object):
|
||||
if opt is not None and _path is None:
|
||||
_path = opt.impl_getpath(self._getcontext())
|
||||
self._p_.delproperties(_path)
|
||||
self._getcontext().cfgimpl_reset_cache(opt=opt, path=_path)
|
||||
self._getcontext().cfgimpl_reset_cache(opt=opt, path=_path, only=('settings',))
|
||||
|
||||
def _getproperties(self, opt=None, path=None,
|
||||
setting_properties=undefined, read_write=True,
|
||||
@ -378,14 +379,27 @@ class Settings(object):
|
||||
"""
|
||||
"""
|
||||
if opt is None:
|
||||
props = self._p_.getproperties(path, default_properties)
|
||||
ntime = int(time())
|
||||
if self._p_.hascache(path, index):
|
||||
is_cached, props = self._p_.getcache(path, ntime, index)
|
||||
else:
|
||||
is_cached = False
|
||||
if not is_cached or 'cache' not in props:
|
||||
props = self._p_.getproperties(path, default_properties)
|
||||
if 'cache' in props:
|
||||
if 'expire' in props:
|
||||
ntime = ntime + expires_time
|
||||
else:
|
||||
ntime = None
|
||||
self._p_.setcache(path, props, ntime, index)
|
||||
else:
|
||||
if setting_properties is undefined:
|
||||
setting_properties = self._getproperties(read_write=False)
|
||||
if path is None: # pragma: optional cover
|
||||
raise ValueError(_('if opt is not None, path should not be'
|
||||
' None in _getproperties'))
|
||||
if setting_properties is undefined:
|
||||
setting_properties = self._getproperties(read_write=False)
|
||||
is_cached = False
|
||||
|
||||
if apply_requires:
|
||||
if 'cache' in setting_properties and 'expire' in setting_properties:
|
||||
ntime = int(time())
|
||||
@ -440,6 +454,26 @@ class Settings(object):
|
||||
self._p_.setproperties(path, properties)
|
||||
self._getcontext().cfgimpl_reset_cache(opt=opt, path=path)
|
||||
|
||||
def getpermissive(self, setting_properties, path=None):
|
||||
if 'cache' in setting_properties and 'expire' in setting_properties:
|
||||
ntime = int(time())
|
||||
else:
|
||||
ntime = None
|
||||
if 'cache' in setting_properties and self._pp_.hascache(path, None):
|
||||
is_cached, perm = self._pp_.getcache(path, ntime, None)
|
||||
else:
|
||||
is_cached = False
|
||||
if not is_cached:
|
||||
if path is not None:
|
||||
perm = self._pp_.getpermissive(path)
|
||||
else:
|
||||
perm = self._pp_.getpermissive()
|
||||
if 'cache' in setting_properties:
|
||||
if 'expire' in setting_properties:
|
||||
ntime = ntime + expires_time
|
||||
self._pp_.setcache(path, perm, ntime, None)
|
||||
return perm
|
||||
|
||||
#____________________________________________________________
|
||||
def validate_properties(self, opt_or_descr, is_descr, check_frozen, path,
|
||||
value=None, force_permissive=False,
|
||||
@ -472,10 +506,10 @@ class Settings(object):
|
||||
# remove opt permissive
|
||||
# permissive affect option's permission with or without permissive
|
||||
# global property
|
||||
properties -= self._p_.getpermissive(path)
|
||||
properties -= self.getpermissive(setting_properties, path)
|
||||
# remove global permissive if need
|
||||
if force_permissive is True or 'permissive' in setting_properties:
|
||||
properties -= self._p_.getpermissive()
|
||||
properties -= self.getpermissive(setting_properties)
|
||||
|
||||
# calc properties
|
||||
properties &= setting_properties
|
||||
@ -540,8 +574,15 @@ class Settings(object):
|
||||
path = opt.impl_getpath(self._getcontext())
|
||||
if not isinstance(permissive, tuple): # pragma: optional cover
|
||||
raise TypeError(_('permissive must be a tuple'))
|
||||
self._p_.setpermissive(path, permissive)
|
||||
self._getcontext().cfgimpl_reset_cache(opt=opt, path=path)
|
||||
self._pp_.setpermissive(path, permissive)
|
||||
setting_properties = self._getproperties(read_write=False)
|
||||
self._getcontext().cfgimpl_reset_cache(opt=opt, path=path, only=('values',))
|
||||
if 'cache' in setting_properties:
|
||||
if 'expire' in setting_properties:
|
||||
ntime = int(time()) + expires_time
|
||||
else:
|
||||
ntime = None
|
||||
self._pp_.setcache(path, set(permissive), ntime, None)
|
||||
|
||||
#____________________________________________________________
|
||||
def setowner(self, owner):
|
||||
@ -549,6 +590,7 @@ class Settings(object):
|
||||
if not isinstance(owner, owners.Owner): # pragma: optional cover
|
||||
raise TypeError(_("invalid generic owner {0}").format(str(owner)))
|
||||
self._owner = owner
|
||||
#FIXME qu'est ce qui se passe si pas de owner ??
|
||||
|
||||
def getowner(self):
|
||||
return self._owner
|
||||
@ -718,16 +760,17 @@ class Settings(object):
|
||||
return self._p_.get_modified_properties()
|
||||
|
||||
def get_modified_permissives(self):
|
||||
return self._p_.get_modified_permissives()
|
||||
return self._pp_.get_modified_permissives()
|
||||
|
||||
def __getstate__(self):
|
||||
return {'_p_': self._p_, '_owner': str(self._owner)}
|
||||
return {'_p_': self._p_, '_pp_': self._pp_, '_owner': str(self._owner)}
|
||||
|
||||
def _impl_setstate(self, storage):
|
||||
self._p_._storage = storage
|
||||
|
||||
def __setstate__(self, states):
|
||||
self._p_ = states['_p_']
|
||||
self._pp_ = states['_pp_']
|
||||
try:
|
||||
self._owner = getattr(owners, states['_owner'])
|
||||
except AttributeError:
|
||||
|
@ -133,9 +133,10 @@ def get_storages(context, session_id, persistent):
|
||||
session_id = gen_id(context)
|
||||
imp = storage_type.get()
|
||||
storage = imp.Storage(session_id, persistent)
|
||||
settings = imp.Settings(storage)
|
||||
properties = imp.Properties(storage)
|
||||
permissives = imp.Permissives(storage)
|
||||
values = imp.Values(storage)
|
||||
return settings, values
|
||||
return properties, permissives, values
|
||||
|
||||
|
||||
def get_storages_option(type_):
|
||||
|
@ -23,9 +23,9 @@ The advantage of this solution is that you can easily create a Config and
|
||||
use it. But if something goes wrong, you will lost your modifications.
|
||||
"""
|
||||
from .value import Values
|
||||
from .setting import Settings
|
||||
from .setting import Properties, Permissives
|
||||
from .storage import setting, Storage, list_sessions, delete_session
|
||||
from .option import StorageBase, StorageOptionDescription, StorageMasterSlaves
|
||||
|
||||
__all__ = (setting, Values, Settings, Storage, list_sessions, delete_session,
|
||||
StorageBase, StorageOptionDescription, StorageMasterSlaves)
|
||||
__all__ = ('setting', 'Values', 'Properties', 'Permissives', 'Storage', 'list_sessions',
|
||||
'delete_session', 'StorageBase', 'StorageOptionDescription', 'StorageMasterSlaves')
|
||||
|
@ -19,16 +19,15 @@ from copy import copy
|
||||
from ..util import Cache
|
||||
|
||||
|
||||
class Settings(Cache):
|
||||
__slots__ = ('_properties', '_permissives')
|
||||
class Properties(Cache):
|
||||
__slots__ = ('_properties',)
|
||||
|
||||
def __init__(self, storage):
|
||||
# properties attribute: the name of a property enables this property
|
||||
# key is None for global properties
|
||||
self._properties = {}
|
||||
# permissive properties
|
||||
self._permissives = {}
|
||||
super(Settings, self).__init__(storage)
|
||||
super(Properties, self).__init__(storage)
|
||||
|
||||
# properties
|
||||
def setproperties(self, path, properties):
|
||||
@ -47,12 +46,6 @@ class Settings(Cache):
|
||||
if path in self._properties:
|
||||
del(self._properties[path])
|
||||
|
||||
def setpermissive(self, path, permissive):
|
||||
self._permissives[path] = frozenset(permissive)
|
||||
|
||||
def getpermissive(self, path=None):
|
||||
return self._permissives.get(path, frozenset())
|
||||
|
||||
def get_modified_properties(self):
|
||||
"""return all modified settings in a dictionary
|
||||
example: {'path1': set(['prop1', 'prop2'])}
|
||||
@ -62,6 +55,21 @@ class Settings(Cache):
|
||||
def set_modified_properties(self, properties):
|
||||
self._properties = properties
|
||||
|
||||
|
||||
class Permissives(Cache):
|
||||
__slots__ = ('_permissives',)
|
||||
|
||||
def __init__(self, storage):
|
||||
# permissive properties
|
||||
self._permissives = {}
|
||||
super(Permissives, self).__init__(storage)
|
||||
|
||||
def setpermissive(self, path, permissive):
|
||||
self._permissives[path] = frozenset(permissive)
|
||||
|
||||
def getpermissive(self, path=None):
|
||||
return self._permissives.get(path, frozenset())
|
||||
|
||||
def get_modified_permissives(self):
|
||||
"""return all modified permissives in a dictionary
|
||||
example: {'path1': set(['perm1', 'perm2'])}
|
||||
@ -70,3 +78,4 @@ class Settings(Cache):
|
||||
|
||||
def set_modified_permissives(self, permissives):
|
||||
self._permissives = permissives
|
||||
|
||||
|
@ -21,7 +21,7 @@ You should not configure differents Configs with same session_id.
|
||||
|
||||
"""
|
||||
from .value import Values
|
||||
from .setting import Settings
|
||||
from .setting import Properties, Permissives
|
||||
from .storage import Storage, list_sessions, delete_session
|
||||
|
||||
__all__ = ('Values', 'Settings', 'Storage', 'list_sessions', 'delete_session')
|
||||
__all__ = ('Values', 'Properties', 'Permissives', 'Storage', 'list_sessions', 'delete_session')
|
||||
|
@ -18,11 +18,11 @@
|
||||
from .sqlite3db import Sqlite3DB
|
||||
|
||||
|
||||
class Settings(Sqlite3DB):
|
||||
class Properties(Sqlite3DB):
|
||||
__slots__ = tuple()
|
||||
|
||||
def __init__(self, storage):
|
||||
super(Settings, self).__init__(storage)
|
||||
super(Properties, self).__init__(storage)
|
||||
|
||||
# properties
|
||||
def setproperties(self, path, properties):
|
||||
@ -63,6 +63,33 @@ class Settings(Sqlite3DB):
|
||||
self._storage.execute("DELETE FROM property WHERE path = ? AND session_id = ?",
|
||||
(path, self._session_id))
|
||||
|
||||
def get_modified_properties(self):
|
||||
"""return all modified settings in a dictionary
|
||||
example: {'path1': set(['prop1', 'prop2'])}
|
||||
"""
|
||||
ret = {}
|
||||
for path, properties, _ in self._storage.select("SELECT * FROM property "
|
||||
"WHERE session_id = ?",
|
||||
(self._session_id,),
|
||||
only_one=False):
|
||||
path = self._sqlite_decode_path(path)
|
||||
ret[path] = self._sqlite_decode(properties)
|
||||
return ret
|
||||
|
||||
def set_modified_properties(self, properties):
|
||||
self._storage.execute("DELETE FROM property", commit=False)
|
||||
for path, property_ in properties.items():
|
||||
self._storage.execute("INSERT INTO property(path, properties, session_id) "
|
||||
"VALUES (?, ?, ?)", (path,
|
||||
self._sqlite_encode(property_),
|
||||
self._session_id,
|
||||
), False)
|
||||
self._storage._conn.commit()
|
||||
|
||||
|
||||
class Permissives(Sqlite3DB):
|
||||
__slots__ = tuple()
|
||||
|
||||
# permissive
|
||||
def setpermissive(self, path, permissive):
|
||||
path = self._sqlite_encode_path(path)
|
||||
@ -83,35 +110,12 @@ class Settings(Sqlite3DB):
|
||||
else:
|
||||
return frozenset(self._sqlite_decode(permissives[0]))
|
||||
|
||||
def get_modified_properties(self):
|
||||
"""return all modified settings in a dictionary
|
||||
example: {'path1': set(['prop1', 'prop2'])}
|
||||
"""
|
||||
ret = {}
|
||||
for path, properties, _ in self._storage.select("SELECT * FROM property "
|
||||
"WHERE session_id = ?",
|
||||
(self._session_id,),
|
||||
only_one=False):
|
||||
path = self._sqlite_decode_path(path)
|
||||
ret[path] = self._sqlite_decode(properties)
|
||||
return ret
|
||||
|
||||
def set_modified_properties(self, properties):
|
||||
self._storage.execute("DELETE FROM property", commit=False)
|
||||
for path, property_ in properties.items():
|
||||
self._storage.execute("INSERT INTO property(path, property, session_id) "
|
||||
"VALUES (?, ?, ?)", (path,
|
||||
self._sqlite_encode(property_),
|
||||
self._session_id,
|
||||
), False)
|
||||
self._storage._conn.commit()
|
||||
|
||||
def get_modified_permissives(self):
|
||||
"""return all modified permissives in a dictionary
|
||||
example: {'path1': set(['perm1', 'perm2'])}
|
||||
"""
|
||||
ret = {}
|
||||
for path, permissives in self._storage.select("SELECT * FROM permissive "
|
||||
for path, permissives in self._storage.select("SELECT path, permissives FROM permissive "
|
||||
"WHERE session_id = ?",
|
||||
(self._session_id,),
|
||||
only_one=False):
|
||||
@ -122,7 +126,7 @@ class Settings(Sqlite3DB):
|
||||
def set_modified_permissives(self, permissives):
|
||||
self._storage.execute("DELETE FROM permissive", commit=False)
|
||||
for path, permissive in permissives.items():
|
||||
self._storage.execute("INSERT INTO permissive(path, permissive, session_id) "
|
||||
self._storage.execute("INSERT INTO permissive(path, permissives, session_id) "
|
||||
"VALUES (?, ?, ?)", (path,
|
||||
self._sqlite_encode(permissive),
|
||||
self._session_id,
|
||||
|
@ -231,10 +231,19 @@ class Values(Sqlite3DB):
|
||||
index = export[1][idx]
|
||||
value = export[2][idx]
|
||||
owner = export[3][idx]
|
||||
self._storage.execute("INSERT INTO value(path, value, owner, idx, session_id) VALUES "
|
||||
"(?, ?, ?, ?, ?)", (path, self._sqlite_encode(value),
|
||||
str(owner), index,
|
||||
self._session_id))
|
||||
if index is None:
|
||||
self._storage.execute("INSERT INTO value(path, value, owner, idx, session_id) VALUES "
|
||||
"(?, ?, ?, ?, ?)", (path, self._sqlite_encode(value),
|
||||
str(owner), index,
|
||||
self._session_id), commit=False)
|
||||
else:
|
||||
for val in zip(index, value, owner):
|
||||
self._storage.execute("INSERT INTO value(path, value, owner, idx, session_id)"
|
||||
"VALUES (?, ?, ?, ?, ?)", (path,
|
||||
self._sqlite_encode(val[1]),
|
||||
str(val[2]), val[0],
|
||||
self._session_id),
|
||||
commit=False)
|
||||
self._storage._conn.commit()
|
||||
|
||||
def get_max_length(self, path, session):
|
||||
|
@ -199,7 +199,7 @@ class Values(object):
|
||||
self._setvalue(opt, path, value, force_owner=owners.forced)
|
||||
else:
|
||||
self._p_.resetvalue(path, session)
|
||||
context.cfgimpl_reset_cache(opt=opt, path=path)
|
||||
context.cfgimpl_reset_cache(opt=opt, path=path, only=('values', 'properties'))
|
||||
|
||||
def _isempty(self, opt, value, force_allow_empty_list=False, index=None):
|
||||
"convenience method to know if an option is empty"
|
||||
@ -430,7 +430,7 @@ class Values(object):
|
||||
|
||||
def _setvalue(self, opt, path, value, force_owner=undefined, index=None):
|
||||
context = self._getcontext()
|
||||
context.cfgimpl_reset_cache(opt=opt, path=path)
|
||||
context.cfgimpl_reset_cache(opt=opt, path=path, only=('values', 'properties'))
|
||||
if force_owner is undefined:
|
||||
owner = context.cfgimpl_get_settings().getowner()
|
||||
else:
|
||||
|
Reference in New Issue
Block a user