Merge branch 'master' of ssh://git.labs.libre-entreprise.org/gitroot/tiramisu

This commit is contained in:
gwen 2013-09-03 11:01:37 +02:00
commit fc9f6ce816
7 changed files with 143 additions and 54 deletions

View File

@ -141,6 +141,7 @@ def test_information_config():
string = 'some informations'
config.impl_set_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():

View File

@ -18,7 +18,6 @@ def test_list():
b = BoolOption('b', '')
o = OptionDescription('od', '', [b])
c = Config(o, session_id='test_non_persistent')
from tiramisu.setting import list_sessions
assert 'test_non_persistent' in list_sessions()
del(c)
assert 'test_non_persistent' not in list_sessions()
@ -43,7 +42,6 @@ def test_list_sessions_persistent():
# storage is not persistent
pass
else:
from tiramisu.setting import list_sessions
assert 'test_persistent' in list_sessions()
@ -124,3 +122,19 @@ def test_two_persistent_owner():
assert c.getowner(b) == owners.persistent
assert c2.getowner(b) == owners.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
from tiramisu.error import PropertiesOptionError, ConfigError
from tiramisu.option import OptionDescription, Option, SymLinkOption, \
BaseInformation
from tiramisu.option import OptionDescription, Option, SymLinkOption
from tiramisu.setting import groups, Settings, default_encoding, get_storage
from tiramisu.value import Values
from tiramisu.i18n import _
class SubConfig(BaseInformation):
class SubConfig(object):
"sub configuration management entry"
__slots__ = ('_impl_context', '_impl_descr', '_impl_path')
@ -252,10 +251,10 @@ class SubConfig(BaseInformation):
:returns: list of matching Option objects
"""
return self._cfgimpl_get_context()._find(bytype, byname, byvalue,
first=False,
type_=type_,
_subpath=self.cfgimpl_get_path()
)
first=False,
type_=type_,
_subpath=self.cfgimpl_get_path()
)
def find_first(self, bytype=None, byname=None, byvalue=None,
type_='option', display_error=True):
@ -501,6 +500,22 @@ class CommonConfig(SubConfig):
def cfgimpl_get_meta(self):
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):
@ -526,7 +541,6 @@ class Config(CommonConfig):
super(Config, self).__init__(descr, weakref.ref(self))
self._impl_build_all_paths()
self._impl_meta = None
self._impl_informations = {}
def cfgimpl_reset_cache(self,
only_expired=False,
@ -565,7 +579,6 @@ class Config(CommonConfig):
# self._impl_settings = Settings(self, storage)
# self._impl_values = Values(self, storage)
# self._impl_meta = None
# self._impl_informations = {}
# def cfgimpl_get_children(self):
# return self._impl_children

View File

@ -54,51 +54,15 @@ def valid_name(name):
#
class BaseInformation(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):
class BaseOption(object):
"""This abstract base class stands for attribute access
in options that have to be set only once, it is of course done in the
__setattr__ method
"""
__slots__ = ('_name', '_requires', '_properties', '_readonly',
'_consistencies', '_calc_properties', '_state_consistencies',
'_state_readonly', '_state_requires', '_stated')
'_consistencies', '_calc_properties', '_impl_informations',
'_state_consistencies', '_state_readonly', '_state_requires',
'_stated')
def __init__(self, name, doc, requires, properties):
if not valid_name(name):
@ -160,6 +124,30 @@ class BaseOption(BaseInformation):
name))
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):
"""during serialization process, many things have to be done.
one of them is the localisation of the options.
@ -223,6 +211,7 @@ class BaseOption(BaseInformation):
else:
self._state_requires = new_value
# serialize
def _impl_getstate(self, descr):
"""the under the hood stuff that need to be done
before the serialization.
@ -273,6 +262,7 @@ class BaseOption(BaseInformation):
del(states['_stated'])
return states
# unserialize
def _impl_setstate(self, descr):
self._impl_convert_consistencies(descr, load=True)
self._impl_convert_requires(descr, load=True)
@ -881,7 +871,7 @@ class OptionDescription(BaseOption):
'_state_group_type', '_properties', '_children',
'_consistencies', '_calc_properties', '__weakref__',
'_readonly', '_impl_informations', '_state_requires',
'_state_consistencies', '_stated')
'_state_consistencies', '_stated', '_state_readonly')
_opt_type = 'optiondescription'
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):
__slots__ = ('_values', '__weakref__')
__slots__ = ('_values', '_informations', '__weakref__')
def __init__(self, storage):
"""init plugin means create values storage
"""
self._values = {}
self._informations = {}
# should init cache too
super(Values, self).__init__(storage)
@ -72,3 +73,22 @@ class Values(Cache):
return: owner object
"""
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)
values_table = 'CREATE TABLE IF NOT EXISTS value(path text primary '
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):
try:
getattr(owners, owner[0])
@ -114,3 +117,27 @@ class Values(Cache):
except AttributeError:
owners.addowner(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)
# 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