better sqlalchemy integration

This commit is contained in:
2016-09-30 22:45:33 +02:00
parent 6fbc4accb9
commit 69de44bbb4
14 changed files with 492 additions and 251 deletions

View File

@ -29,6 +29,7 @@ from ..autolib import carry_out_calculation
from ..error import (ConfigError, ValueWarning, PropertiesOptionError,
display_list)
from ..storage import get_storages_option
from . import MasterSlaves
StorageBase = get_storages_option('base')
@ -99,7 +100,7 @@ class Base(StorageBase):
requires=None, multi=False, callback=None,
callback_params=None, validator=None, validator_params=None,
properties=None, warnings_only=False, extra=None,
allow_empty_list=undefined):
allow_empty_list=undefined, session=None):
if not valid_name(name): # pragma: optional cover
raise ValueError(_("invalid name: {0} for option").format(name))
if not multi and default_multi is not None: # pragma: optional cover
@ -138,9 +139,11 @@ class Base(StorageBase):
raise ValueError('conflict: properties already set in '
'requirement {0}'.format(
list(set_forbidden_properties)))
if session is None:
session = self.getsession()
StorageBase.__init__(self, name, _multi, warnings_only, doc, extra,
calc_properties, requires, properties,
allow_empty_list)
allow_empty_list, session=session)
if multi is not False and default is None:
default = []
err = self.impl_validate(default, is_multi=is_multi)
@ -150,7 +153,7 @@ class Base(StorageBase):
##callback is False in optiondescription
if callback is not False:
self.impl_set_callback(callback, callback_params, _init=True)
self.commit()
self.commit(session)
def impl_set_callback(self, callback, callback_params=None, _init=False):
if callback is None and callback_params is not None: # pragma: optional cover
@ -342,9 +345,6 @@ class BaseOption(Base):
def _is_subdyn(self):
return getattr(self, '_subdyn', None) is not None
def impl_getproperties(self):
return self._properties
def _impl_valid_unicode(self, value):
if sys.version_info[0] >= 3:
if not isinstance(value, str):
@ -590,10 +590,13 @@ class Option(OnlyOption):
return self._valid_consistency(current_opt, None, context,
None, None)
def impl_is_dynsymlinkoption(self):
return False
def impl_is_master_slaves(self, type_='both'):
"""FIXME
"""
master_slaves = getattr(self, '_master_slaves', None)
master_slaves = self.impl_get_master_slaves()
if master_slaves is not None:
if type_ in ('both', 'master') and \
master_slaves.is_master(self):
@ -604,7 +607,12 @@ class Option(OnlyOption):
return False
def impl_get_master_slaves(self):
return self._master_slaves
masterslaves = self._get_master_slave()
if masterslaves is None:
return None
if not isinstance(masterslaves, MasterSlaves):
return MasterSlaves(masterslaves)
return masterslaves
def impl_getdoc(self):
"accesses the Option's doc"
@ -876,10 +884,11 @@ class SymLinkOption(OnlyOption):
raise ValueError(_('malformed symlinkoption '
'must be an option '
'for symlink {0}').format(name))
session = self.getsession()
super(Base, self).__init__(name, undefined, undefined, undefined,
undefined, undefined, undefined, undefined,
undefined, opt)
self.commit()
undefined, opt, session=session)
self.commit(session)
def __getattr__(self, name, context=undefined):
if name in ('_opt', '_readonly', 'impl_getpath', '_name',
@ -964,3 +973,6 @@ class DynSymLinkOption(object):
force_submulti_index,
current_opt=self,
is_multi=is_multi)
def impl_is_dynsymlinkoption(self):
return True

View File

@ -22,87 +22,81 @@
from ..i18n import _
from ..setting import log, undefined, debug
from ..error import SlaveError, PropertiesOptionError
from .baseoption import DynSymLinkOption, SymLinkOption, Option
from ..storage import get_storages_option
StorageMasterSlaves = get_storages_option('masterslaves')
class MasterSlaves(object):
__slots__ = ('master', 'slaves')
__slots__ = ('_p_')
def __init__(self, name, childs, validate=True):
def __init__(self, name, childs=None, validate=True, add=True):
#if master (same name has group) is set
#for collect all slaves
self.master = None
slaves = []
for child in childs:
if isinstance(child, SymLinkOption): # pragma: optional cover
raise ValueError(_("master group {0} shall not have "
"a symlinkoption").format(name))
if not isinstance(child, Option): # pragma: optional cover
raise ValueError(_("master group {0} shall not have "
"a subgroup").format(name))
if not child.impl_is_multi(): # pragma: optional cover
raise ValueError(_("not allowed option {0} "
"in group {1}"
": this option is not a multi"
"").format(child.impl_getname(), name))
if child.impl_getname() == name:
self.master = child
if isinstance(name, StorageMasterSlaves):
self._p_ = name
else:
slaves = []
if childs[0].impl_getname() == name:
master = childs[0]
else:
raise ValueError(_('master group with wrong'
' master name for {0}'
).format(name))
for child in childs[1:]:
if child.impl_getdefault() != []:
raise ValueError(_("not allowed default value for option {0} "
"in group {1}").format(child.impl_getname(),
name))
slaves.append(child)
if self.master is None: # pragma: optional cover
raise ValueError(_('master group with wrong'
' master name for {0}'
).format(name))
if validate:
callback, callback_params = self.master.impl_get_callback()
if callback is not None and callback_params != {}: # pragma: optional cover
for key, callbacks in callback_params.items():
for callbk in callbacks:
if isinstance(callbk, tuple):
if callbk[0] in slaves:
raise ValueError(_("callback of master's option shall "
"not refered a slave's ones"))
#everything is ok, store references
self.slaves = tuple(slaves)
for child in childs:
child._master_slaves = self
if validate:
callback, callback_params = master.impl_get_callback()
if callback is not None and callback_params != {}: # pragma: optional cover
for key, callbacks in callback_params.items():
for callbk in callbacks:
if isinstance(callbk, tuple):
if callbk[0] in slaves:
raise ValueError(_("callback of master's option shall "
"not refered a slave's ones"))
#everything is ok, store references
self._p_ = StorageMasterSlaves(master, slaves)
if add:
for child in childs:
child._set_master_slaves(self)
def is_master(self, opt):
return opt == self.master or (isinstance(opt, DynSymLinkOption) and
opt._opt == self.master)
master = self._p_._sm_getmaster().impl_getname()
return opt.impl_getname() == master or (opt.impl_is_dynsymlinkoption() and
opt._opt.impl_getname() == master)
def getmaster(self, opt):
if isinstance(opt, DynSymLinkOption):
master = self._p_._sm_getmaster()
if opt.impl_is_dynsymlinkoption():
suffix = opt.impl_getsuffix()
name = self.master.impl_getname() + suffix
name = master.impl_getname() + suffix
base_path = opt._dyn.split('.')[0] + '.'
path = base_path + name
master = self.master._impl_to_dyn(name, path)
else: # pragma: no dynoptiondescription cover
master = self.master
master = master._impl_to_dyn(name, path)
return master
def getslaves(self, opt):
if isinstance(opt, DynSymLinkOption):
for slave in self.slaves:
if opt.impl_is_dynsymlinkoption():
for slave in self._p_._sm_getslaves():
suffix = opt.impl_getsuffix()
name = slave.impl_getname() + suffix
base_path = opt._dyn.split('.')[0] + '.'
path = base_path + name
yield slave._impl_to_dyn(name, path)
else: # pragma: no dynoptiondescription cover
for slave in self.slaves:
for slave in self._p_._sm_getslaves():
yield slave
def in_same_group(self, opt):
if isinstance(opt, DynSymLinkOption):
return opt._opt == self.master or opt._opt in self.slaves
if opt.impl_is_dynsymlinkoption():
return opt._opt == self._p_._sm_getmaster() or opt._opt in self._p_._sm_getslaves()
else: # pragma: no dynoptiondescription cover
return opt == self.master or opt in self.slaves
return opt == self._p_._sm_getmaster() or opt in self._p_._sm_getslaves()
def reset(self, opt, values, setting_properties):
for slave in self.getslaves(opt):

View File

@ -55,9 +55,8 @@ class ChoiceOption(Option):
if not isinstance(values, tuple): # pragma: optional cover
raise TypeError(_('values must be a tuple or a function for {0}'
).format(name))
_setattr = object.__setattr__
_setattr(self, '_choice_values', values)
_setattr(self, '_choice_values_params', values_params)
self.impl_set_choice_values_params(values, values_params)
super(ChoiceOption, self).__init__(name, doc, default=default,
default_multi=default_multi,
callback=callback,
@ -79,9 +78,7 @@ class ChoiceOption(Option):
if context is None:
values = []
else:
values_params = self._choice_values_params
if values_params is None:
values_params = {}
values_params = self.impl_get_choice_values_params()
values = carry_out_calculation(current_opt, context=context,
callback=values,
callback_params=values_params,
@ -93,6 +90,7 @@ class ChoiceOption(Option):
'').format(self.impl_getname()))
return values
def _validate(self, value, context=undefined, current_opt=undefined,
returns_raise=False):
values = self.impl_get_values(context, current_opt=current_opt,

View File

@ -24,7 +24,7 @@ import re
from ..i18n import _
from ..setting import groups, undefined, owners # , log
from .baseoption import BaseOption, SymLinkOption
from .baseoption import BaseOption, SymLinkOption, Option
from . import MasterSlaves
from ..error import ConfigError, ConflictError
from ..storage import get_storages_option
@ -229,7 +229,20 @@ class OptionDescription(BaseOption, StorageOptionDescription):
if isinstance(group_type, groups.GroupType):
self._group_type = group_type
if isinstance(group_type, groups.MasterGroupType):
MasterSlaves(self.impl_getname(), self.impl_getchildren())
children = self.impl_getchildren()
for child in children:
if isinstance(child, SymLinkOption): # pragma: optional cover
raise ValueError(_("master group {0} shall not have "
"a symlinkoption").format(self.impl_getname()))
if not isinstance(child, Option): # pragma: optional cover
raise ValueError(_("master group {0} shall not have "
"a subgroup").format(self.impl_getname()))
if not child.impl_is_multi(): # pragma: optional cover
raise ValueError(_("not allowed option {0} "
"in group {1}"
": this option is not a multi"
"").format(child.impl_getname(), self.impl_getname()))
MasterSlaves(self.impl_getname(), children)
else: # pragma: optional cover
raise ValueError(_('group_type: {0}'
' not allowed').format(group_type))
@ -365,7 +378,6 @@ class DynOptionDescription(OptionDescription):
'dynoptiondescription'))
child._impl_setsubdyn(self)
self.impl_set_callback(callback, callback_params)
self.commit()
def _validate_callback(self, callback, callback_params):
if callback is None: