impl_get_information and impl_set_information are, now, persistent in storage

This commit is contained in:
Emmanuel Garette 2013-09-03 10:38:28 +02:00
parent dcd6efd063
commit aeeaf6ec14
7 changed files with 143 additions and 54 deletions

View File

@ -141,6 +141,7 @@ def test_information_config():
string = 'some informations' string = 'some informations'
config.impl_set_information('info', string) config.impl_set_information('info', string)
assert config.impl_get_information('info') == string assert config.impl_get_information('info') == string
raises(ValueError, "config.impl_get_information('noinfo')")
def test_config_impl_get_path_by_opt(): def test_config_impl_get_path_by_opt():

View File

@ -18,7 +18,6 @@ def test_list():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
c = Config(o, session_id='test_non_persistent') c = Config(o, session_id='test_non_persistent')
from tiramisu.setting import list_sessions
assert 'test_non_persistent' in list_sessions() assert 'test_non_persistent' in list_sessions()
del(c) del(c)
assert 'test_non_persistent' not in list_sessions() assert 'test_non_persistent' not in list_sessions()
@ -43,7 +42,6 @@ def test_list_sessions_persistent():
# storage is not persistent # storage is not persistent
pass pass
else: else:
from tiramisu.setting import list_sessions
assert 'test_persistent' in list_sessions() assert 'test_persistent' in list_sessions()
@ -124,3 +122,19 @@ def test_two_persistent_owner():
assert c.getowner(b) == owners.persistent assert c.getowner(b) == owners.persistent
assert c2.getowner(b) == owners.persistent assert c2.getowner(b) == owners.persistent
delete_session('test_persistent') delete_session('test_persistent')
def test_two_persistent_information():
b = BoolOption('b', '')
o = OptionDescription('od', '', [b])
try:
c = Config(o, session_id='test_persistent', persistent=True)
except ValueError:
# storage is not persistent
pass
else:
c.impl_set_information('info', 'string')
assert c.impl_get_information('info') == 'string'
c2 = Config(o, session_id='test_persistent', persistent=True)
assert c2.impl_get_information('info') == 'string'
delete_session('test_persistent')

View File

@ -22,14 +22,13 @@
# ____________________________________________________________ # ____________________________________________________________
import weakref import weakref
from tiramisu.error import PropertiesOptionError, ConfigError from tiramisu.error import PropertiesOptionError, ConfigError
from tiramisu.option import OptionDescription, Option, SymLinkOption, \ from tiramisu.option import OptionDescription, Option, SymLinkOption
BaseInformation
from tiramisu.setting import groups, Settings, default_encoding, get_storage from tiramisu.setting import groups, Settings, default_encoding, get_storage
from tiramisu.value import Values from tiramisu.value import Values
from tiramisu.i18n import _ from tiramisu.i18n import _
class SubConfig(BaseInformation): class SubConfig(object):
"sub configuration management entry" "sub configuration management entry"
__slots__ = ('_impl_context', '_impl_descr', '_impl_path') __slots__ = ('_impl_context', '_impl_descr', '_impl_path')
@ -501,6 +500,22 @@ class CommonConfig(SubConfig):
def cfgimpl_get_meta(self): def cfgimpl_get_meta(self):
return self._impl_meta return self._impl_meta
# information
def impl_set_information(self, key, value):
"""updates the information's attribute
:param key: information's key (ex: "help", "doc"
:param value: information's value (ex: "the help string")
"""
self._impl_values.set_information(key, value)
def impl_get_information(self, key, default=None):
"""retrieves one information's item
:param key: the item string (ex: "help")
"""
return self._impl_values.get_information(key, default)
# ____________________________________________________________ # ____________________________________________________________
class Config(CommonConfig): class Config(CommonConfig):
@ -526,7 +541,6 @@ class Config(CommonConfig):
super(Config, self).__init__(descr, weakref.ref(self)) super(Config, self).__init__(descr, weakref.ref(self))
self._impl_build_all_paths() self._impl_build_all_paths()
self._impl_meta = None self._impl_meta = None
self._impl_informations = {}
def cfgimpl_reset_cache(self, def cfgimpl_reset_cache(self,
only_expired=False, only_expired=False,
@ -565,7 +579,6 @@ class Config(CommonConfig):
# self._impl_settings = Settings(self, storage) # self._impl_settings = Settings(self, storage)
# self._impl_values = Values(self, storage) # self._impl_values = Values(self, storage)
# self._impl_meta = None # self._impl_meta = None
# self._impl_informations = {}
# def cfgimpl_get_children(self): # def cfgimpl_get_children(self):
# return self._impl_children # return self._impl_children

View File

@ -54,51 +54,15 @@ def valid_name(name):
# #
class BaseInformation(object): class BaseOption(object):
"interface for an option's information attribute"
__slots__ = ('_impl_informations',)
def impl_set_information(self, key, value):
"""updates the information's attribute
(which is a dictionary)
:param key: information's key (ex: "help", "doc"
:param value: information's value (ex: "the help string")
"""
try:
self._impl_informations[key] = value
except AttributeError:
raise AttributeError(_('{0} has no attribute '
'impl_set_information').format(
self.__class__.__name__))
def impl_get_information(self, key, default=None):
"""retrieves one information's item
:param key: the item string (ex: "help")
"""
try:
if key in self._impl_informations:
return self._impl_informations[key]
elif default is not None:
return default
else:
raise ValueError(_("information's item"
" not found: {0}").format(key))
except AttributeError:
raise AttributeError(_('{0} has no attribute '
'impl_get_information').format(
self.__class__.__name__))
class BaseOption(BaseInformation):
"""This abstract base class stands for attribute access """This abstract base class stands for attribute access
in options that have to be set only once, it is of course done in the in options that have to be set only once, it is of course done in the
__setattr__ method __setattr__ method
""" """
__slots__ = ('_name', '_requires', '_properties', '_readonly', __slots__ = ('_name', '_requires', '_properties', '_readonly',
'_consistencies', '_calc_properties', '_state_consistencies', '_consistencies', '_calc_properties', '_impl_informations',
'_state_readonly', '_state_requires', '_stated') '_state_consistencies', '_state_readonly', '_state_requires',
'_stated')
def __init__(self, name, doc, requires, properties): def __init__(self, name, doc, requires, properties):
if not valid_name(name): if not valid_name(name):
@ -160,6 +124,30 @@ class BaseOption(BaseInformation):
name)) name))
object.__setattr__(self, name, value) object.__setattr__(self, name, value)
# information
def impl_set_information(self, key, value):
"""updates the information's attribute
(which is a dictionary)
:param key: information's key (ex: "help", "doc"
:param value: information's value (ex: "the help string")
"""
self._impl_informations[key] = value
def impl_get_information(self, key, default=None):
"""retrieves one information's item
:param key: the item string (ex: "help")
"""
if key in self._impl_informations:
return self._impl_informations[key]
elif default is not None:
return default
else:
raise ValueError(_("information's item not found: {0}").format(
key))
# serialize/unserialize
def _impl_convert_consistencies(self, descr, load=False): def _impl_convert_consistencies(self, descr, load=False):
if not load and self._consistencies is None: if not load and self._consistencies is None:
self._state_consistencies = None self._state_consistencies = None
@ -215,6 +203,7 @@ class BaseOption(BaseInformation):
else: else:
self._state_requires = new_value self._state_requires = new_value
# serialize
def _impl_getstate(self, descr): def _impl_getstate(self, descr):
self._stated = True self._stated = True
self._impl_convert_consistencies(descr) self._impl_convert_consistencies(descr)
@ -252,6 +241,7 @@ class BaseOption(BaseInformation):
del(states['_stated']) del(states['_stated'])
return states return states
# unserialize
def _impl_setstate(self, descr): def _impl_setstate(self, descr):
self._impl_convert_consistencies(descr, load=True) self._impl_convert_consistencies(descr, load=True)
self._impl_convert_requires(descr, load=True) self._impl_convert_requires(descr, load=True)
@ -860,7 +850,7 @@ class OptionDescription(BaseOption):
'_state_group_type', '_properties', '_children', '_state_group_type', '_properties', '_children',
'_consistencies', '_calc_properties', '__weakref__', '_consistencies', '_calc_properties', '__weakref__',
'_readonly', '_impl_informations', '_state_requires', '_readonly', '_impl_informations', '_state_requires',
'_state_consistencies', '_stated') '_state_consistencies', '_stated', '_state_readonly')
_opt_type = 'optiondescription' _opt_type = 'optiondescription'
def __init__(self, name, doc, children, requires=None, properties=None): def __init__(self, name, doc, children, requires=None, properties=None):

View File

@ -22,12 +22,13 @@ from tiramisu.storage.dictionary.storage import Cache
class Values(Cache): class Values(Cache):
__slots__ = ('_values', '__weakref__') __slots__ = ('_values', '_informations', '__weakref__')
def __init__(self, storage): def __init__(self, storage):
"""init plugin means create values storage """init plugin means create values storage
""" """
self._values = {} self._values = {}
self._informations = {}
# should init cache too # should init cache too
super(Values, self).__init__(storage) super(Values, self).__init__(storage)
@ -72,3 +73,22 @@ class Values(Cache):
return: owner object return: owner object
""" """
return self._values.get(path, (default, None))[0] return self._values.get(path, (default, None))[0]
def set_information(self, key, value):
"""updates the information's attribute
(which is a dictionary)
:param key: information's key (ex: "help", "doc"
:param value: information's value (ex: "the help string")
"""
self._informations[key] = value
def get_information(self, key):
"""retrieves one information's item
:param key: the item string (ex: "help")
"""
if key in self._informations:
return self._informations[key]
else:
raise ValueError("not found")

View File

@ -32,7 +32,10 @@ class Values(Cache):
super(Values, self).__init__('value', storage) super(Values, self).__init__('value', storage)
values_table = 'CREATE TABLE IF NOT EXISTS value(path text primary ' values_table = 'CREATE TABLE IF NOT EXISTS value(path text primary '
values_table += 'key, value text, owner text)' values_table += 'key, value text, owner text)'
self.storage.execute(values_table) self.storage.execute(values_table, commit=False)
informations_table = 'CREATE TABLE IF NOT EXISTS information(key text primary '
informations_table += 'key, value text)'
self.storage.execute(informations_table)
for owner in self.storage.select("SELECT DISTINCT owner FROM value", tuple(), False): for owner in self.storage.select("SELECT DISTINCT owner FROM value", tuple(), False):
try: try:
getattr(owners, owner[0]) getattr(owners, owner[0])
@ -114,3 +117,27 @@ class Values(Cache):
except AttributeError: except AttributeError:
owners.addowner(owner) owners.addowner(owner)
return getattr(owners, owner) return getattr(owners, owner)
def set_information(self, key, value):
"""updates the information's attribute
(which is a dictionary)
:param key: information's key (ex: "help", "doc"
:param value: information's value (ex: "the help string")
"""
self.storage.execute("DELETE FROM information WHERE key = ?", (key,),
False)
self.storage.execute("INSERT INTO information(key, value) VALUES "
"(?, ?)", (key, self._sqlite_encode(value)))
def get_information(self, key):
"""retrieves one information's item
:param key: the item string (ex: "help")
"""
value = self.storage.select("SELECT value FROM information WHERE key = ?",
(key,))
if value is None:
raise ValueError("not found")
else:
return self._sqlite_decode(value[0])

View File

@ -315,6 +315,30 @@ class Values(object):
""" """
return self.context().cfgimpl_get_description().impl_get_path_by_opt(opt) return self.context().cfgimpl_get_description().impl_get_path_by_opt(opt)
# information
def set_information(self, key, value):
"""updates the information's attribute
:param key: information's key (ex: "help", "doc"
:param value: information's value (ex: "the help string")
"""
self._p_.set_information(key, value)
def get_information(self, key, default=None):
"""retrieves one information's item
:param key: the item string (ex: "help")
"""
try:
return self._p_.get_information(key)
except ValueError:
if default is not None:
return default
else:
raise ValueError(_("information's item"
" not found: {0}").format(key))
# ____________________________________________________________ # ____________________________________________________________
# multi types # multi types