sqlalchemy has a storage

This commit is contained in:
Emmanuel Garette 2014-01-20 14:53:08 +01:00
parent 068f68460d
commit 661f844ce6
7 changed files with 310 additions and 299 deletions

View File

@ -481,6 +481,7 @@ def test_callback_master_and_slaves_slave_list():
assert cfg.val1.val2 == ['val', 'val']
cfg.val1.val1 = ['val1']
#wrong len
print cfg.val1.val2
raises(SlaveError, 'cfg.val1.val2')

View File

@ -148,7 +148,7 @@ def carry_out_calculation(option, config, callback, callback_params,
for callbk in callbacks.params:
if callbk.option is not None:
# callbk is something link (opt, True|False)
opt = callbk.get_option(config)
opt = callbk.option
force_permissive = callbk.force_permissive
path = config.cfgimpl_get_description().impl_get_path_by_opt(
opt)

View File

@ -28,17 +28,15 @@ from IPy import IP
import warnings
#from pickle import loads, dumps
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine, Column, Integer, String, Boolean, \
PickleType, ForeignKey, Table
from sqlalchemy.orm import relationship, backref
from sqlalchemy.orm import sessionmaker
from tiramisu.error import ConfigError, ConflictError, ValueWarning
from tiramisu.setting import groups, multitypes
from tiramisu.i18n import _
from tiramisu.autolib import carry_out_calculation
#FIXME : need storage...
from tiramisu.storage.sqlalchemy.option import StorageBase, StorageOptionDescription
from sqlalchemy.ext.declarative import declarative_base, declared_attr
name_regexp = re.compile(r'^\d+')
forbidden_names = ('iter_all', 'iter_group', 'find', 'find_first',
'make_dict', 'unwrap_from_path', 'read_only',
@ -58,170 +56,7 @@ def valid_name(name):
return False
#____________________________________________________________
#
engine = create_engine('sqlite:///:memory:')
Base = declarative_base()
class _RequireExpected(Base):
__tablename__ = 'expected'
id = Column(Integer, primary_key=True)
expected = Column(PickleType)
require = Column(Integer, ForeignKey('require.id'))
def __init__(self, expected):
self.expected = expected
class _RequireOption(Base):
__tablename__ = 'require'
id = Column(Integer, primary_key=True)
option = Column(Integer, ForeignKey('baseoption.id'))
r_opt = Column(Integer)
expected = relationship("_RequireExpected")
action = Column(String, nullable=False)
inverse = Column(Boolean, default=False)
transitive = Column(Boolean, default=True)
same_action = Column(Boolean, default=True)
def __init__(self, option, expected, action, inverse, transitive,
same_action):
self.r_opt = option.id
for expect in expected:
self.expected.append(_RequireExpected(expect))
self.action = action
self.inverse = inverse
self.transitive = transitive
self.same_action = same_action
def get_expected(self):
for expected in self.expected:
yield(expected.expected)
def get_option(self, config):
return config.cfgimpl_get_description().impl_get_opt_by_id(self.r_opt)
property_table = Table('property', Base.metadata,
Column('left_id', Integer, ForeignKey('propertyoption.name')),
Column('right_id', Integer, ForeignKey('baseoption.id'))
)
class _PropertyOption(Base):
__tablename__ = 'propertyoption'
name = Column(String, primary_key=True)
def __init__(self, name):
self.name = name
class _Information(Base):
__tablename__ = 'information'
id = Column(Integer, primary_key=True)
option = Column(Integer, ForeignKey('baseoption.id'))
key = Column(String)
value = Column(PickleType)
def __init__(self, key, value):
self.key = key
self.value = value
class _CallbackParamOption(Base):
__tablename__ = 'callback_param_option'
id = Column(Integer, primary_key=True)
callback_param = Column(Integer, ForeignKey('callback_param.id'))
option = Column(Integer)
force_permissive = Column(Boolean)
value = Column(PickleType)
def __init__(self, option=None, force_permissive=None, value=None):
if value is not None:
self.value = value
else:
if isinstance(option, SymLinkOption):
option = option._opt
self.option = option.id
self.force_permissive = force_permissive
def get_option(self, config):
return config.cfgimpl_get_description().impl_get_opt_by_id(self.option)
class _CallbackParam(Base):
__tablename__ = 'callback_param'
id = Column(Integer, primary_key=True)
callback = Column(Integer, ForeignKey('baseoption.id'))
name = Column(String)
params = relationship('_CallbackParamOption')
def __init__(self, name, params):
self.name = name
for param in params:
if isinstance(param, tuple):
self.params.append(_CallbackParamOption(option=param[0],
force_permissive=param[1]))
else:
self.params.append(_CallbackParamOption(value=param))
consistency_table = Table('consistencyopt', Base.metadata,
Column('left_id', Integer, ForeignKey('consistency.id')),
Column('right_id', Integer, ForeignKey('baseoption.id'))
)
class _Consistency(Base):
__tablename__ = 'consistency'
id = Column(Integer, primary_key=True)
func = Column(PickleType)
def __init__(self, func, all_cons_opts):
self.func = func
for option in all_cons_opts:
option._consistencies.append(self)
class BaseOption(Base):
"""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
"""
__tablename__ = 'baseoption'
id = Column(Integer, primary_key=True)
_name = Column(String)
_informations = relationship('_Information')
_default = Column(PickleType)
_default_multi = Column(PickleType)
_requires = relationship('_RequireOption')
_multi = Column(Boolean)
_multitype = Column(String)
_callback = Column(PickleType)
_callback_params = relationship('_CallbackParam')
_validator = Column(PickleType)
_validator_params = relationship('_CallbackParam')
_parent = Column(Integer, ForeignKey('baseoption.id'))
_children = relationship('BaseOption', enable_typechecks=False)
_properties = relationship('_PropertyOption', secondary=property_table,
backref=backref('options', enable_typechecks=False))
_warnings_only = Column(Boolean)
_readonly = Column(Boolean, default=False)
_consistencies = relationship('_Consistency', secondary=consistency_table,
backref=backref('options', enable_typechecks=False))
_choice_values = Column(PickleType)
_choice_open_values = Column(Boolean)
_type = Column(String(50))
__mapper_args__ = {
'polymorphic_identity': 'person',
'polymorphic_on': _type
}
#FIXME devrait etre une table
_optiondescription_group_type = Column(String)
#__slots__ = ('_name', '_requires', '_properties', '_readonly',
# '_calc_properties', '_impl_informations',
# '_state_readonly', '_state_requires', '_stated')
class Base(StorageBase):
def __init__(self, name, doc, default=None, default_multi=None,
requires=None, multi=False, callback=None,
callback_params=None, validator=None, validator_params=None,
@ -235,7 +70,7 @@ class BaseOption(Base):
if requires is not None:
for values in requires.values():
for require in values.values():
self._requires.append(_RequireOption(*require))
self._add_require(require)
if not multi and default_multi is not None:
raise ValueError(_("a default_multi is set whereas multi is False"
" in option: {0}").format(name))
@ -271,7 +106,7 @@ class BaseOption(Base):
self._validator = validator
if validator_params is not None:
for key, values in validator_params.items():
self._validator_params.append(_CallbackParam(key, values))
self._add_validator(key, values)
if callback is None and callback_params is not None:
raise ValueError(_("params defined for a callback function but "
"no callback defined"
@ -281,7 +116,7 @@ class BaseOption(Base):
self._callback = callback
if callback_params is not None:
for key, values in callback_params.items():
self._callback_params.append(_CallbackParam(key, values))
self._add_callback(key, values)
if requires is not None and properties is not tuple():
set_forbidden_properties = set(properties) & set(requires.keys())
if set_forbidden_properties != frozenset():
@ -298,41 +133,19 @@ class BaseOption(Base):
else:
self._default = default
for prop in properties:
prop_obj = session.query(_PropertyOption).filter(_PropertyOption.name == prop).first()
if prop_obj is None:
prop_obj = _PropertyOption(prop)
self._properties.append(prop_obj)
self._properties.append(self._get_property_object(prop))
self._warnings_only = warnings_only
return super(Base, self).__init__()
# ____________________________________________________________
# 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")
"""
#FIXME pas append ! remplacer !
info = session.query(_Information).filter_by(option=self.id, key=key).first()
if info is None:
self._informations.append(_Information(key, value))
else:
info.value = value
def impl_get_information(self, key, default=None):
"""retrieves one information's item
:param key: the item string (ex: "help")
"""
info = session.query(_Information).filter_by(option=self.id, key=key).first()
if info is not None:
return info.value
elif default is not None:
return default
else:
raise ValueError(_("information's item not found: {0}").format(
key))
class BaseOption(Base):
"""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',
# '_calc_properties', '_impl_informations',
# '_state_readonly', '_state_requires', '_stated')
# ____________________________________________________________
# serialize object
@ -500,8 +313,6 @@ class Option(BaseOption):
validator_params, properties,
warnings_only, choice_values,
choice_open_values)
session.add(self)
session.commit()
#def __setattr__(self, name, value):
# """set once and only once some attributes in the option,
@ -749,7 +560,7 @@ class Option(BaseOption):
else:
self._launch_consistency(func, self, value, None,
None, all_cons_opts)
_Consistency(func, all_cons_opts)
self._add_consistency(func, all_cons_opts)
self.impl_validate(self.impl_getdefault())
def _cons_not_equal(self, opts, vals):
@ -856,10 +667,6 @@ class ChoiceOption(Option):
"""
#__slots__ = ('_values', '_open_values')
__mapper_args__ = {
'polymorphic_identity': 'choice',
}
def __init__(self, name, doc, values, default=None, default_multi=None,
requires=None, multi=False, callback=None,
callback_params=None, open_values=False, validator=None,
@ -901,9 +708,6 @@ class ChoiceOption(Option):
class BoolOption(Option):
"represents a choice between ``True`` and ``False``"
# __slots__ = tuple()
__mapper_args__ = {
'polymorphic_identity': 'bool',
}
def _validate(self, value):
if not isinstance(value, bool):
@ -913,9 +717,6 @@ class BoolOption(Option):
class IntOption(Option):
"represents a choice of an integer"
# __slots__ = tuple()
__mapper_args__ = {
'polymorphic_identity': 'int',
}
def _validate(self, value):
if not isinstance(value, int):
@ -925,9 +726,6 @@ class IntOption(Option):
class FloatOption(Option):
"represents a choice of a floating point number"
#__slots__ = tuple()
__mapper_args__ = {
'polymorphic_identity': 'float',
}
def _validate(self, value):
if not isinstance(value, float):
@ -937,9 +735,6 @@ class FloatOption(Option):
class StrOption(Option):
"represents the choice of a string"
#__slots__ = tuple()
__mapper_args__ = {
'polymorphic_identity': 'string',
}
def _validate(self, value):
if not isinstance(value, str):
@ -955,9 +750,6 @@ else:
class UnicodeOption(Option):
"represents the choice of a unicode string"
#__slots__ = tuple()
__mapper_args__ = {
'polymorphic_identity': 'unicode',
}
_empty = u''
def _validate(self, value):
@ -967,9 +759,6 @@ else:
class SymLinkOption(BaseOption):
#__slots__ = ('_name', '_opt', '_state_opt', '_readonly', '_parent')
__mapper_args__ = {
'polymorphic_identity': 'symlink',
}
#not return _opt consistencies
#_consistencies = None
@ -982,8 +771,7 @@ class SymLinkOption(BaseOption):
self._opt = opt
self._readonly = True
self._parent = None
session.add(self)
session.commit()
self.commit()
def __getattr__(self, name):
if name in ('_opt', '_opt_type', '_readonly', 'impl_getname'):
@ -1001,17 +789,13 @@ class SymLinkOption(BaseOption):
super(SymLinkOption, self)._impl_setstate(descr)
def impl_get_information(self, key, default=None):
#FIXME ne devrait pas etre util si ?
#FIXME ne devrait pas etre utile si ?
return self._opt.impl_get_information(key, default)
class IPOption(Option):
"represents the choice of an ip"
#__slots__ = ('_private_only', '_allow_reserved')
__mapper_args__ = {
'polymorphic_identity': 'ip',
}
def __init__(self, name, doc, default=None, default_multi=None,
requires=None, multi=False, callback=None,
callback_params=None, validator=None, validator_params=None,
@ -1061,10 +845,6 @@ class PortOption(Option):
see: http://en.wikipedia.org/wiki/Port_numbers
"""
#__slots__ = ('_allow_range', '_allow_zero', '_min_value', '_max_value')
__mapper_args__ = {
'polymorphic_identity': 'port',
}
def __init__(self, name, doc, default=None, default_multi=None,
requires=None, multi=False, callback=None,
callback_params=None, validator=None, validator_params=None,
@ -1126,10 +906,6 @@ class PortOption(Option):
class NetworkOption(Option):
"represents the choice of a network"
#__slots__ = tuple()
__mapper_args__ = {
'polymorphic_identity': 'network',
}
def _validate(self, value):
try:
IP(value)
@ -1145,9 +921,6 @@ class NetworkOption(Option):
class NetmaskOption(Option):
"represents the choice of a netmask"
#__slots__ = tuple()
__mapper_args__ = {
'polymorphic_identity': 'netmask',
}
def _validate(self, value):
try:
@ -1201,9 +974,6 @@ class NetmaskOption(Option):
class BroadcastOption(Option):
#__slots__ = tuple()
__mapper_args__ = {
'polymorphic_identity': 'broadcast',
}
def _validate(self, value):
try:
@ -1232,9 +1002,6 @@ class DomainnameOption(Option):
fqdn: with tld, not supported yet
"""
#__slots__ = ('_dom_type', '_allow_ip', '_allow_without_dot', '_domain_re')
__mapper_args__ = {
'polymorphic_identity': 'domainname',
}
def __init__(self, name, doc, default=None, default_multi=None,
requires=None, multi=False, callback=None,
@ -1297,9 +1064,6 @@ class DomainnameOption(Option):
class EmailOption(DomainnameOption):
#__slots__ = tuple()
__mapper_args__ = {
'polymorphic_identity': 'email',
}
username_re = re.compile(r"^[\w!#$%&'*+\-/=?^`{|}~.]+$")
def _validate(self, value):
@ -1316,9 +1080,6 @@ class EmailOption(DomainnameOption):
class URLOption(DomainnameOption):
#__slots__ = tuple()
__mapper_args__ = {
'polymorphic_identity': 'url',
}
proto_re = re.compile(r'(http|https)://')
path_re = re.compile(r"^[a-z0-9\-\._~:/\?#\[\]@!%\$&\'\(\)\*\+,;=]+$")
@ -1355,9 +1116,6 @@ class URLOption(DomainnameOption):
class FilenameOption(Option):
#__slots__ = tuple()
__mapper_args__ = {
'polymorphic_identity': 'file',
}
path_re = re.compile(r"^[a-zA-Z0-9\-\._~/+]+$")
def _validate(self, value):
@ -1366,7 +1124,7 @@ class FilenameOption(Option):
raise ValueError(_('invalid filename'))
class OptionDescription(BaseOption):
class OptionDescription(BaseOption, StorageOptionDescription):
"""Config's schema (organisation, group) and container of Options
The `OptionsDescription` objects lives in the `tiramisu.config.Config`.
"""
@ -1375,9 +1133,6 @@ class OptionDescription(BaseOption):
# '_cache_consistencies', '_calc_properties', '__weakref__',
# '_readonly', '_impl_informations', '_state_requires',
# '_stated', '_state_readonly')
__mapper_args__ = {
'polymorphic_identity': 'optiondescription',
}
def __init__(self, name, doc, children, requires=None, properties=None):
"""
@ -1385,8 +1140,6 @@ class OptionDescription(BaseOption):
"""
super(OptionDescription, self).__init__(name, doc=doc, requires=requires, properties=properties)
session.add(self)
session.commit()
child_names = [child.impl_getname() for child in children]
#better performance like this
valid_child = copy(child_names)
@ -1528,28 +1281,6 @@ class OptionDescription(BaseOption):
self._cache_consistencies[opt] = tuple(cons)
self._readonly = True
def impl_get_opt_by_path(self, path):
try:
#FIXME
idx = self._cache_paths[1].index(path)
opt_id = self._cache_paths[0][idx]
return session.query(BaseOption).filter_by(id=opt_id).first()
except ValueError:
raise AttributeError(_('no option for path {0}').format(path))
def impl_get_opt_by_id(self, opt_id):
try:
#FIXME
#idx = self._cache_paths[0].index(opt_id)
return session.query(BaseOption).filter_by(id=opt_id).first()
except ValueError:
raise AttributeError(_('no id {0} found').format(opt_id))
def impl_get_path_by_opt(self, opt):
try:
return self._cache_paths[1][self._cache_paths[0].index(opt.id)]
except ValueError:
raise AttributeError(_('no option {0} found').format(opt))
# ____________________________________________________________
def impl_set_group_type(self, group_type):
@ -1800,8 +1531,3 @@ def validate_callback(callback, callback_params, type_):
' not a {0} for second argument'
).format(type_, type(
force_permissive)))
#FIXME
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

View File

@ -588,7 +588,7 @@ class Settings(object):
for require in opt.impl_getrequires():
expected = tuple(require.get_expected())
inverse = require.inverse
option = require.get_option(self.context())
option = require.option
reqpath = self._get_path_by_opt(option)
if reqpath == path or reqpath.startswith(path + '.'):
raise RequirementError(_("malformed requirements "

View File

View File

@ -0,0 +1,284 @@
# -*- coding: utf-8 -*-
""
# Copyright (C) 2014 Team tiramisu (see AUTHORS for all contributors)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ____________________________________________________________
from tiramisu.setting import multitypes
from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy import create_engine, Column, Integer, String, Boolean, \
PickleType, ForeignKey, Table
from sqlalchemy.orm import relationship, backref
from sqlalchemy.orm import sessionmaker
#FIXME
engine = create_engine('sqlite:///:memory:')
SqlAlchemyBase = declarative_base()
#____________________________________________________________
#
# require
require_table = Table('require', SqlAlchemyBase.metadata,
Column('left_id', Integer, ForeignKey('requireoption.id')),
Column('right_id', Integer, ForeignKey('baseoption.id'))
)
class _RequireExpected(SqlAlchemyBase):
__tablename__ = 'expected'
id = Column(Integer, primary_key=True)
expected = Column(PickleType)
require = Column(Integer, ForeignKey('requireoption.id'))
def __init__(self, expected):
self.expected = expected
class _RequireOption(SqlAlchemyBase):
__tablename__ = 'requireoption'
id = Column(Integer, primary_key=True)
r_opt = Column(Integer)
expected = relationship("_RequireExpected")
action = Column(String, nullable=False)
inverse = Column(Boolean, default=False)
transitive = Column(Boolean, default=True)
same_action = Column(Boolean, default=True)
def __init__(self, option, expected, action, inverse, transitive,
same_action):
self.r_opt = option.id
for expect in expected:
self.expected.append(_RequireExpected(expect))
self.action = action
self.inverse = inverse
self.transitive = transitive
self.same_action = same_action
def get_expected(self):
for expected in self.expected:
yield(expected.expected)
#def get_option(self, config):
# return config.cfgimpl_get_description().impl_get_opt_by_id(self.r_opt)
#____________________________________________________________
#
# properties
property_table = Table('property', SqlAlchemyBase.metadata,
Column('left_id', Integer, ForeignKey('propertyoption.name')),
Column('right_id', Integer, ForeignKey('baseoption.id'))
)
class _PropertyOption(SqlAlchemyBase):
__tablename__ = 'propertyoption'
name = Column(String, primary_key=True)
def __init__(self, name):
self.name = name
#____________________________________________________________
#
# information
class _Information(SqlAlchemyBase):
__tablename__ = 'information'
id = Column(Integer, primary_key=True)
option = Column(Integer, ForeignKey('baseoption.id'))
key = Column(String)
value = Column(PickleType)
def __init__(self, key, value):
self.key = key
self.value = value
#____________________________________________________________
#
# callback
class _CallbackParamOption(SqlAlchemyBase):
__tablename__ = 'callback_param_option'
id = Column(Integer, primary_key=True)
callback_param = Column(Integer, ForeignKey('callback_param.id'))
option = Column(Integer)
force_permissive = Column(Boolean)
value = Column(PickleType)
def __init__(self, option=None, force_permissive=None, value=None):
if value is not None:
self.value = value
else:
self.option = option.id
self.force_permissive = force_permissive
class _CallbackParam(SqlAlchemyBase):
__tablename__ = 'callback_param'
id = Column(Integer, primary_key=True)
callback = Column(Integer, ForeignKey('baseoption.id'))
name = Column(String)
params = relationship('_CallbackParamOption')
def __init__(self, name, params):
self.name = name
for param in params:
if isinstance(param, tuple):
self.params.append(_CallbackParamOption(option=param[0],
force_permissive=param[1]))
else:
self.params.append(_CallbackParamOption(value=param))
#____________________________________________________________
#
# consistency
consistency_table = Table('consistencyopt', SqlAlchemyBase.metadata,
Column('left_id', Integer, ForeignKey('consistency.id')),
Column('right_id', Integer, ForeignKey('baseoption.id'))
)
class _Consistency(SqlAlchemyBase):
__tablename__ = 'consistency'
id = Column(Integer, primary_key=True)
func = Column(PickleType)
def __init__(self, func, all_cons_opts):
self.func = func
for option in all_cons_opts:
option._consistencies.append(self)
#____________________________________________________________
#
# Base
class _Base(SqlAlchemyBase):
__tablename__ = 'baseoption'
id = Column(Integer, primary_key=True)
_name = Column(String)
_informations = relationship('_Information')
_default = Column(PickleType)
_default_multi = Column(PickleType)
_requires = relationship('_RequireOption', secondary=require_table,
backref=backref('option', enable_typechecks=False))
_multi = Column(Boolean)
_multitype = Column(String)
_callback = Column(PickleType)
_callback_params = relationship('_CallbackParam')
_validator = Column(PickleType)
_validator_params = relationship('_CallbackParam')
_parent = Column(Integer, ForeignKey('baseoption.id'))
_children = relationship('BaseOption', enable_typechecks=False)
_properties = relationship('_PropertyOption', secondary=property_table,
backref=backref('options', enable_typechecks=False))
_warnings_only = Column(Boolean)
_readonly = Column(Boolean, default=False)
_consistencies = relationship('_Consistency', secondary=consistency_table,
backref=backref('options', enable_typechecks=False))
_choice_values = Column(PickleType)
_choice_open_values = Column(Boolean)
_type = Column(String(50))
__mapper_args__ = {
'polymorphic_identity': 'option',
'polymorphic_on': _type
}
#FIXME devrait etre une table
_optiondescription_group_type = Column(String)
def __init__(self):
self.commit()
def commit(self):
session.add(self)
session.commit()
def _get_property_object(self, propname):
prop_obj = session.query(_PropertyOption).filter(_PropertyOption.name == propname).first()
if prop_obj is None:
prop_obj = _PropertyOption(propname)
return prop_obj
def _add_require(self, require):
self._requires.append(_RequireOption(*require))
def _add_callback(self, key, values):
self._callback_params.append(_CallbackParam(key, values))
def _add_validator(self, key, values):
self._validator_params.append(_CallbackParam(key, values))
def _add_consistency(self, func, all_cons_opts):
_Consistency(func, all_cons_opts)
# ____________________________________________________________
# 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")
"""
info = session.query(_Information).filter_by(option=self.id, key=key).first()
#FIXME pas append ! remplacer !
if info is None:
self._informations.append(_Information(key, value))
else:
info.value = value
def impl_get_information(self, key, default=None):
"""retrieves one information's item
:param key: the item string (ex: "help")
"""
info = session.query(_Information).filter_by(option=self.id, key=key).first()
if info is not None:
return info.value
elif default is not None:
return default
else:
raise ValueError(_("information's item not found: {0}").format(
key))
class StorageOptionDescription(object):
def impl_get_opt_by_path(self, path):
try:
#FIXME
idx = self._cache_paths[1].index(path)
opt_id = self._cache_paths[0][idx]
return session.query(_Base).filter_by(id=opt_id).first()
except ValueError:
raise AttributeError(_('no option for path {0}').format(path))
def impl_get_path_by_opt(self, opt):
try:
return self._cache_paths[1][self._cache_paths[0].index(opt)]
except ValueError:
raise AttributeError(_('no option {0} found').format(opt))
class StorageBase(_Base):
@declared_attr
def __mapper_args__(self):
return {'polymorphic_identity': self.__name__.lower()}
#FIXME
SqlAlchemyBase.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
"default plugin for cache: set it in a simple dictionary"
"utils used by storage"
# Copyright (C) 2013 Team tiramisu (see AUTHORS for all contributors)
#
# This program is free software; you can redistribute it and/or modify