better sqlalchemy integration

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

View File

@ -82,7 +82,7 @@ def make_description4():
def test_mandatory_ro():
descr = make_description()
config = Config(descr)
config = Config(descr, session_id='man001')
config.read_only()
prop = []
try:
@ -94,21 +94,31 @@ def test_mandatory_ro():
config.str1 = 'yes'
config.read_only()
assert config.str1 == 'yes'
try:
delete_session('config', config.impl_getsessionid())
except ValueError:
pass
del(config)
def test_mandatory_rw():
descr = make_description()
config = Config(descr)
config = Config(descr, session_id='man002')
config.read_write()
#not mandatory in rw
config.str1
config.str1 = 'yes'
assert config.str1 == 'yes'
try:
delete_session('config', config.impl_getsessionid())
except ValueError:
pass
del(config)
def test_mandatory_default():
descr = make_description()
config = Config(descr)
config = Config(descr, session_id='man003')
config.read_only()
#not mandatory in rw
config.str
@ -125,11 +135,16 @@ def test_mandatory_default():
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
try:
delete_session('config', config.impl_getsessionid())
except ValueError:
pass
del(config)
def test_mandatory_delete():
descr = make_description()
config = Config(descr)
config = Config(descr, session_id='man004')
config.read_only()
config.str
try:
@ -150,12 +165,17 @@ def test_mandatory_delete():
assert 'mandatory' in prop
del(config.str)
assert config.str1 == 'yes'
try:
delete_session('config', config.impl_getsessionid())
except ValueError:
pass
del(config)
#valeur vide : None, '', u'', ...
def test_mandatory_none():
descr = make_description()
config = Config(descr)
config = Config(descr, session_id='man005')
config.str1 = None
assert config.getowner(config.unwrap_from_path('str1')) == 'user'
config.read_only()
@ -165,11 +185,16 @@ def test_mandatory_none():
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
try:
delete_session('config', config.impl_getsessionid())
except ValueError:
pass
del(config)
def test_mandatory_empty():
descr = make_description()
config = Config(descr)
config = Config(descr, session_id='man006')
config.str1 = ''
assert config.getowner(config.unwrap_from_path('str1')) == 'user'
config.read_only()
@ -179,11 +204,16 @@ def test_mandatory_empty():
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
try:
delete_session('config', config.impl_getsessionid())
except ValueError:
pass
del(config)
def test_mandatory_multi_none():
descr = make_description()
config = Config(descr)
config = Config(descr, session_id='man007')
config.str3 = [None]
assert config.getowner(config.unwrap_from_path('str3')) == 'user'
config.read_only()
@ -203,11 +233,16 @@ def test_mandatory_multi_none():
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
try:
delete_session('config', config.impl_getsessionid())
except ValueError:
pass
del(config)
def test_mandatory_multi_empty():
descr = make_description()
config = Config(descr)
config = Config(descr, session_id='man008')
config.str3 = []
assert config.getowner(config.unwrap_from_path('str3')) == 'user'
config.read_only()
@ -239,11 +274,16 @@ def test_mandatory_multi_empty():
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
try:
delete_session('config', config.impl_getsessionid())
except ValueError:
pass
del(config)
def test_mandatory_multi_empty_allow_empty_list():
descr = make_description()
config = Config(descr)
config = Config(descr, session_id='man009')
config.str4 = []
assert config.getowner(config.unwrap_from_path('str4')) == 'user'
config.read_only()
@ -271,19 +311,29 @@ def test_mandatory_multi_empty_allow_empty_list():
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
try:
delete_session('config', config.impl_getsessionid())
except ValueError:
pass
del(config)
def test_mandatory_multi_append():
descr = make_description()
config = Config(descr)
config = Config(descr, session_id='man010')
config.str3 = ['yes']
config.read_write()
config.str3.append(None)
try:
delete_session('config', config.impl_getsessionid())
except ValueError:
pass
del(config)
def test_mandatory_disabled():
descr = make_description()
config = Config(descr)
config = Config(descr, session_id='man011')
setting = config.cfgimpl_get_settings()
config.str1
config.read_only()
@ -300,11 +350,16 @@ def test_mandatory_disabled():
except PropertiesOptionError as err:
prop = err.proptype
assert set(prop) == set(['disabled', 'mandatory'])
try:
delete_session('config', config.impl_getsessionid())
except ValueError:
pass
del(config)
def test_mandatory_unicode():
descr = make_description()
config = Config(descr)
config = Config(descr, session_id='man012')
config.unicode2
config.read_only()
prop = []
@ -322,11 +377,16 @@ def test_mandatory_unicode():
except PropertiesOptionError as err:
prop = err.proptype
assert prop == ['mandatory']
try:
delete_session('config', config.impl_getsessionid())
except ValueError:
pass
del(config)
def test_mandatory_warnings_ro():
descr = make_description()
config = Config(descr)
config = Config(descr, session_id='man013')
config.str = ''
config.read_only()
proc = []
@ -341,11 +401,16 @@ def test_mandatory_warnings_ro():
config.read_only()
assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str1', 'unicode2', 'str3']
try:
delete_session('config', config.impl_getsessionid())
except ValueError:
pass
del(config)
def test_mandatory_warnings_rw():
descr = make_description()
config = Config(descr)
config = Config(descr, session_id='man100')
config.str = ''
config.read_write()
config.str
@ -354,7 +419,7 @@ def test_mandatory_warnings_rw():
assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str1', 'unicode2', 'str3']
try:
delete_session('config', config.impl_getsessionid())
delete_session('config', 'man100')
except ValueError:
pass
del(config)
@ -362,7 +427,7 @@ def test_mandatory_warnings_rw():
def test_mandatory_warnings_disabled():
descr = make_description()
config = Config(descr)
config = Config(descr, session_id='man101')
config.str = ''
setting = config.cfgimpl_get_settings()
config.read_write()
@ -372,7 +437,7 @@ def test_mandatory_warnings_disabled():
assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str1', 'unicode2', 'str3']
try:
delete_session('config', config.impl_getsessionid())
delete_session('config', 'man101')
except ValueError:
pass
del(config)
@ -380,7 +445,7 @@ def test_mandatory_warnings_disabled():
def test_mandatory_warnings_hidden():
descr = make_description()
config = Config(descr)
config = Config(descr, session_id='man102')
config.str = ''
setting = config.cfgimpl_get_settings()
config.read_write()
@ -391,7 +456,7 @@ def test_mandatory_warnings_hidden():
assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str', 'str1', 'unicode2', 'str3']
try:
delete_session('config', config.impl_getsessionid())
delete_session('config', 'man102')
except ValueError:
pass
del(config)
@ -399,7 +464,7 @@ def test_mandatory_warnings_hidden():
def test_mandatory_warnings_frozen():
descr = make_description()
config = Config(descr)
config = Config(descr, session_id='man103')
config.str = ''
setting = config.cfgimpl_get_settings()
config.read_write()
@ -409,7 +474,7 @@ def test_mandatory_warnings_frozen():
config.read_only()
assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
try:
delete_session('config', config.impl_getsessionid())
delete_session('config', 'man103')
except ValueError:
pass
del(config)
@ -423,12 +488,12 @@ def test_mandatory_master():
interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
interface1.impl_set_group_type(groups.master)
o = OptionDescription('o', '', [interface1])
config = Config(o)
config = Config(o, session_id='man104')
config.read_only()
raises(PropertiesOptionError, 'config.ip_admin_eth0.ip_admin_eth0')
raises(PropertiesOptionError, 'config.ip_admin_eth0.netmask_admin_eth0')
try:
delete_session('config', config.impl_getsessionid())
delete_session('config', 'man104')
except ValueError:
pass
del(config)
@ -442,10 +507,10 @@ def test_mandatory_warnings_master():
interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
interface1.impl_set_group_type(groups.master)
o = OptionDescription('o', '', [interface1])
config = Config(o)
config = Config(o, session_id='man105')
assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['ip_admin_eth0.ip_admin_eth0']
try:
delete_session('config', config.impl_getsessionid())
delete_session('config', 'man105')
except ValueError:
pass
del(config)
@ -458,7 +523,7 @@ def test_mandatory_master_empty():
interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
interface1.impl_set_group_type(groups.master)
o = OptionDescription('o', '', [interface1])
config = Config(o)
config = Config(o, session_id='man106')
config.read_write()
assert config.ip_admin_eth0.ip_admin_eth0 == []
assert config.ip_admin_eth0.netmask_admin_eth0 == []
@ -489,7 +554,7 @@ def test_mandatory_master_empty():
assert config.ip_admin_eth0.ip_admin_eth0 == ['ip']
assert config.ip_admin_eth0.netmask_admin_eth0 == [None]
try:
delete_session('config', config.impl_getsessionid())
delete_session('config', 'man106')
except ValueError:
pass
del(config)
@ -502,7 +567,7 @@ def test_mandatory_warnings_master_empty():
interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
interface1.impl_set_group_type(groups.master)
o = OptionDescription('o', '', [interface1])
config = Config(o)
config = Config(o, session_id='man107')
config.read_write()
config.ip_admin_eth0.ip_admin_eth0.append()
assert config.ip_admin_eth0.ip_admin_eth0 == [None]
@ -520,7 +585,7 @@ def test_mandatory_warnings_master_empty():
config.ip_admin_eth0.ip_admin_eth0 = ['ip']
assert list(config.cfgimpl_get_values().mandatory_warnings()) == []
try:
delete_session('config', config.impl_getsessionid())
delete_session('config', 'man107')
except ValueError:
pass
del(config)
@ -533,7 +598,7 @@ def test_mandatory_slave():
interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
interface1.impl_set_group_type(groups.master)
o = OptionDescription('o', '', [interface1])
config = Config(o)
config = Config(o, session_id='man108')
config.read_only()
assert config.ip_admin_eth0.ip_admin_eth0 == []
assert config.ip_admin_eth0.netmask_admin_eth0 == []
@ -556,7 +621,7 @@ def test_mandatory_slave():
assert config.ip_admin_eth0.ip_admin_eth0 == ['ip']
assert config.ip_admin_eth0.netmask_admin_eth0 == ['ip']
try:
delete_session('config', config.impl_getsessionid())
delete_session('config', 'man108')
except ValueError:
pass
del(config)
@ -569,7 +634,7 @@ def test_mandatory_warnings_slave():
interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
interface1.impl_set_group_type(groups.master)
o = OptionDescription('o', '', [interface1])
config = Config(o)
config = Config(o, session_id='man109')
config.read_only()
assert config.ip_admin_eth0.ip_admin_eth0 == []
assert config.ip_admin_eth0.netmask_admin_eth0 == []
@ -579,7 +644,7 @@ def test_mandatory_warnings_slave():
config.ip_admin_eth0.ip_admin_eth0.append('ip')
assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['ip_admin_eth0.netmask_admin_eth0']
try:
delete_session('config', config.impl_getsessionid())
delete_session('config', 'man109')
except ValueError:
pass
del(config)
@ -587,7 +652,7 @@ def test_mandatory_warnings_slave():
def test_mandatory_warnings_symlink():
descr = make_description_sym()
config = Config(descr)
config = Config(descr, session_id='man110')
config.str = ''
setting = config.cfgimpl_get_settings()
config.read_write()
@ -597,7 +662,7 @@ def test_mandatory_warnings_symlink():
config.read_only()
assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'str3']
try:
delete_session('config', config.impl_getsessionid())
delete_session('config', 'man110')
except ValueError:
pass
del(config)
@ -605,7 +670,7 @@ def test_mandatory_warnings_symlink():
def test_mandatory_warnings_validate():
descr = make_description3()
config = Config(descr)
config = Config(descr, session_id='man111')
config.str = ''
raises(ValueError, "list(config.cfgimpl_get_values().mandatory_warnings())")
assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str', 'str1', 'str3', 'unicode1', 'int1']
@ -613,7 +678,7 @@ def test_mandatory_warnings_validate():
raises(ValueError, "list(config.cfgimpl_get_values().mandatory_warnings())")
assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str1', 'str3']
try:
delete_session('config', config.impl_getsessionid())
delete_session('config', 'man111')
except ValueError:
pass
del(config)
@ -621,13 +686,13 @@ def test_mandatory_warnings_validate():
def test_mandatory_warnings_validate_empty():
descr = make_description2()
config = Config(descr)
config = Config(descr, session_id='man112')
config.str = ''
config.read_only()
raises(ConfigError, "list(config.cfgimpl_get_values().mandatory_warnings())")
assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str', 'str1', 'str3', 'unicode1']
try:
delete_session('config', config.impl_getsessionid())
delete_session('config', 'man112')
except ValueError:
pass
del(config)
@ -635,7 +700,7 @@ def test_mandatory_warnings_validate_empty():
def test_mandatory_warnings_requires():
descr = make_description4()
config = Config(descr)
config = Config(descr, session_id='man113')
config.str = ''
config.read_write()
config.str
@ -646,7 +711,7 @@ def test_mandatory_warnings_requires():
config.str = 'yes'
assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
try:
delete_session('config', config.impl_getsessionid())
delete_session('config', 'man113')
except ValueError:
pass
del(config)
@ -655,13 +720,13 @@ def test_mandatory_warnings_requires():
def test_mandatory_od_disabled():
descr = make_description()
od = OptionDescription('od', '', [descr])
config = Config(od)
config = Config(od, session_id='man114')
config.read_only()
assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['tiram.str1', 'tiram.unicode2', 'tiram.str3']
config.cfgimpl_get_settings()[descr].append('disabled')
assert list(config.cfgimpl_get_values().mandatory_warnings()) == []
try:
delete_session('config', config.impl_getsessionid())
delete_session('config', 'man114')
except ValueError:
pass
del(config)

View File

@ -11,6 +11,9 @@ from tiramisu.option import ChoiceOption, BoolOption, IntOption, FloatOption,\
URLOption, FilenameOption
print "FIXME slot pour un masterslaves !!"
def test_slots_option():
c = ChoiceOption('a', '', ('a',))
raises(AttributeError, "c.x = 1")

View File

@ -107,9 +107,9 @@ def _diff_opt(opt1, opt2):
else:
assert v[1] == val2[idx][1]
elif attr == '_master_slaves':
assert val1.master.impl_getname() == val2.master.impl_getname()
sval1 = [opt.impl_getname() for opt in val1.slaves]
sval2 = [opt.impl_getname() for opt in val2.slaves]
assert val1._p_._sm_getmaster().impl_getname() == val2._p_._sm_getmaster().impl_getname()
sval1 = [opt.impl_getname() for opt in val1._p_._sm_getslaves()]
sval2 = [opt.impl_getname() for opt in val2._p_._sm_getslaves()]
assert sval1 == sval2
elif attr == '_subdyn':
try:
@ -222,6 +222,10 @@ def test_diff_information_config():
_diff_conf(cfg, q)
assert cfg.impl_get_information('info') == 'oh'
assert q.impl_get_information('info') == 'oh'
try:
delete_session('config', '29090938')
except ValueError:
pass
def test_diff_opt_multi():
@ -353,6 +357,10 @@ def test_diff_opt_config():
q = loads(a)
_diff_opts(cfg.cfgimpl_get_description(), q.cfgimpl_get_description())
_diff_conf(cfg, q)
try:
delete_session('config', '29090940')
except ValueError:
pass
def test_state_properties():
@ -422,6 +430,9 @@ def test_state_metaconfig():
i1 = IntOption('i1', '')
od1 = OptionDescription('od1', '', [i1])
od2 = OptionDescription('od2', '', [od1])
try:
cfg = Config(od2, persistent=True, session_id='29090935')
except ValueError:
conf1 = Config(od2, session_id='29090935')
conf1._impl_test = True
conf2 = Config(od2, session_id='29090936')
@ -431,8 +442,6 @@ def test_state_metaconfig():
raises(ConfigError, "dumps(meta)")
try:
delete_session('config', '29090935')
delete_session('config', '29090936')
delete_session('config', '29090937')
except ValueError:
pass
@ -441,19 +450,20 @@ def test_state_groupconfig():
i1 = IntOption('i1', '')
od1 = OptionDescription('od1', '', [i1])
od2 = OptionDescription('od2', '', [od1])
conf1 = Config(od2, session_id='29090935')
try:
cfg = Config(od2, persistent=True, session_id='29090938')
except ValueError:
conf1 = Config(od2, session_id='29090938')
conf1._impl_test = True
conf2 = Config(od2, session_id='29090936')
conf2 = Config(od2, session_id='29090939')
conf2._impl_test = True
meta = GroupConfig([conf1, conf2], session_id='29090937')
meta = GroupConfig([conf1, conf2], session_id='29090940')
meta._impl_test = True
a = dumps(meta)
q = loads(a)
_diff_conf(meta, q)
try:
delete_session('config', '29090935')
delete_session('config', '29090936')
delete_session('config', '29090937')
delete_session('config', '29090938')
except ValueError:
pass

View File

@ -258,7 +258,7 @@ class SubConfig(object):
return subpath
def getattr(self, name, force_permissive=False, validate=True,
_setting_properties=undefined, index=None,
_setting_properties=undefined, _self_properties=undefined, index=None,
returns_raise=False):
"""
attribute notation mechanism for accessing the value of an option
@ -277,6 +277,7 @@ class SubConfig(object):
return homeconfig.getattr(name, force_permissive=force_permissive,
validate=validate,
_setting_properties=_setting_properties,
_self_properties=_self_properties,
index=index, returns_raise=returns_raise)
context = self._cfgimpl_get_context()
option = self.cfgimpl_get_description().__getattr__(name,
@ -287,7 +288,9 @@ class SubConfig(object):
option, path=subpath,
validate=validate,
force_permissive=force_permissive,
setting_properties=_setting_properties, index=index,
setting_properties=_setting_properties,
self_properties=_self_properties,
index=index,
returns_raise=returns_raise)
elif isinstance(option, SymLinkOption): # pragma: no dynoptiondescription cover
path = context.cfgimpl_get_description().impl_get_path_by_opt(
@ -295,11 +298,13 @@ class SubConfig(object):
return context.getattr(path, validate=validate,
force_permissive=force_permissive,
_setting_properties=_setting_properties,
_self_properties=_self_properties,
index=index, returns_raise=returns_raise)
elif option.impl_is_optiondescription():
props = self.cfgimpl_get_settings().validate_properties(
option, True, False, path=subpath,
force_permissive=force_permissive,
self_properties=_self_properties,
setting_properties=_setting_properties)
if props:
if returns_raise:
@ -313,6 +318,7 @@ class SubConfig(object):
validate=validate,
force_permissive=force_permissive,
setting_properties=_setting_properties,
self_properties=_self_properties,
index=index, returns_raise=returns_raise)
def find(self, bytype=None, byname=None, byvalue=undefined, type_='option',
@ -656,7 +662,8 @@ class _CommonConfig(SubConfig):
def duplicate(self):
config = Config(self._impl_descr)
config.cfgimpl_get_values()._p_._values = self.cfgimpl_get_values()._p_._values
session = self.cfgimpl_get_values()._p_.getsession()
config.cfgimpl_get_values()._p_.importation(self.cfgimpl_get_values()._p_.exportation(session))
config.cfgimpl_get_settings()._p_._properties = self.cfgimpl_get_settings()._p_.get_modified_properties()
config.cfgimpl_get_settings()._p_._permissives = self.cfgimpl_get_settings()._p_.get_modified_permissives()
return config

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,43 +22,36 @@
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()
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:
@ -67,42 +60,43 @@ class MasterSlaves(object):
raise ValueError(_("callback of master's option shall "
"not refered a slave's ones"))
#everything is ok, store references
self.slaves = tuple(slaves)
self._p_ = StorageMasterSlaves(master, slaves)
if add:
for child in childs:
child._master_slaves = self
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:

View File

@ -135,6 +135,8 @@ def get_storages_option(type_):
imp = storage_option_type.get()
if type_ == 'base':
return imp.StorageBase
elif type_ == 'masterslaves':
return imp.StorageMasterSlaves
else:
return imp.StorageOptionDescription

View File

@ -25,7 +25,7 @@ use it. But if something goes wrong, you will lost your modifications.
from .value import Values
from .setting import Settings
from .storage import setting, Storage, list_sessions, delete_session
from .option import StorageBase, StorageOptionDescription
from .option import StorageBase, StorageOptionDescription, StorageMasterSlaves
__all__ = (setting, Values, Settings, Storage, list_sessions, delete_session,
StorageBase, StorageOptionDescription)
StorageBase, StorageOptionDescription, StorageMasterSlaves)

View File

@ -65,7 +65,8 @@ class StorageBase(object):
)
def __init__(self, name, multi, warnings_only, doc, extra, calc_properties,
requires, properties, allow_empty_list, opt=undefined):
requires, properties, allow_empty_list, opt=undefined,
session=None):
_setattr = object.__setattr__
_setattr(self, '_name', name)
if doc is not undefined:
@ -164,6 +165,12 @@ class StorageBase(object):
val_call = tuple([callback, callback_params])
self._val_call = (val, val_call)
def impl_set_choice_values_params(self, values, values_params):
self._choice_values = values
if values_params is not None:
self._choice_values_params = values_params
def impl_get_callback(self):
call = getattr(self, '_val_call', (None, None))[1]
if call is None:
@ -174,6 +181,9 @@ class StorageBase(object):
ret_call = call
return ret_call
def impl_get_choice_values_params(self):
return getattr(self, '_choice_values_params', {})
def impl_get_calc_properties(self):
return getattr(self, '_calc_properties', static_set)
@ -259,6 +269,9 @@ class StorageBase(object):
if extra is not None:
_setattr(self, '_extra', tuple([tuple(extra.keys()), tuple(extra.values())]))
def impl_getproperties(self):
return self._properties
def _impl_setsubdyn(self, subdyn):
self._subdyn = subdyn
@ -357,7 +370,16 @@ class StorageBase(object):
"accessing the default value for a multi"
return getattr(self, '_default_multi', None)
def commit(self):
def _get_master_slave(self):
return getattr(self, '_master_slaves', None)
def _set_master_slaves(self, option):
self._master_slaves = option
def getsession(self):
pass
def commit(self, session):
pass
@ -549,3 +571,17 @@ class StorageOptionDescription(StorageBase):
raise AttributeError(_('unknown Option {0} '
'in OptionDescription {1}'
'').format(name, self.impl_getname()))
class StorageMasterSlaves(object):
__slots__ = ('master', 'slaves')
def __init__(self, master, slaves):
self.master = master
self.slaves = slaves
def _sm_getmaster(self):
return self.master
def _sm_getslaves(self):
return tuple(self.slaves)

View File

@ -25,7 +25,7 @@ use it. But if something goes wrong, you will lost your modifications.
from .value import Values
from .setting import Settings
from .storage import Storage, list_sessions, delete_session, storage_setting
from .option import StorageBase, StorageOptionDescription
from .option import StorageBase, StorageOptionDescription, StorageMasterSlaves
from .util import load
@ -33,5 +33,5 @@ load()
__all__ = (storage_setting, Values, Settings, Storage, list_sessions, delete_session,
StorageBase, StorageOptionDescription)
StorageBase, StorageOptionDescription, StorageMasterSlaves)
# Base, OptionDescription)

View File

@ -40,8 +40,9 @@ def load_requires(collection_type, proxy):
return None
ret = []
requires = getattr(obj, proxy.value_attr)
session = util.Session()
for require in requires:
option = util.session.query(_Base).filter_by(id=require.option).first()
option = session.query(_Base).filter_by(id=require.option).first()
ret.append(tuple([option, require.expected, require.action, require.inverse, require.transitive, require.same_action]))
return tuple(ret)
@ -128,11 +129,12 @@ class _PropertyOption(SqlAlchemyBase):
class _Information(SqlAlchemyBase):
__tablename__ = 'information'
id = Column(Integer, primary_key=True)
option = Column(Integer, ForeignKey('baseoption.id'), nullable=False)
option = Column(String, index=True, nullable=False)
key = Column(String)
value = Column(PickleType)
def __init__(self, key, value):
def __init__(self, option, key, value):
self.option = option
self.key = key
self.value = value
@ -146,11 +148,12 @@ def load_callback_parm(collection_type, proxy):
return None
ret = []
requires = getattr(obj, proxy.value_attr)
session = util.Session()
for require in requires:
if require.value is not None:
ret.append(require.value)
else:
option = util.session.query(_Base).filter_by(id=require.option).first()
option = session.query(_Base).filter_by(id=require.option).first()
ret.append((option, require.force_permissive))
return tuple(ret)
@ -239,20 +242,20 @@ class _Base(SqlAlchemyBase):
id = Column(Integer, primary_key=True)
_name = Column(String)
#FIXME not autoload
_infos = relationship("_Information",
collection_class=attribute_mapped_collection('key'),
cascade="all, delete-orphan")
_informations = association_proxy("_infos", "value")
# _infos = relationship("_Information",
# collection_class=attribute_mapped_collection('key'),
# cascade="all, delete-orphan")
# _informations = association_proxy("_infos", "value")
_default = Column(PickleType)
_default_multi = Column(PickleType)
_subdyn = Column(Integer)
_dyn = Column(String)
_opt = Column(Integer)
_master_slaves = Column(Integer)
_choice_values = Column(PickleType)
_cho_params = relationship('_CallbackParam',
collection_class=
attribute_mapped_collection('key'))
_choice_params = association_proxy("_cho_params", "params",
collection_class=attribute_mapped_collection('key'))
_choice_values_params = association_proxy("_cho_params", "params",
getset_factory=load_callback_parm)
_reqs = relationship("_Require", collection_class=list)
_requires = association_proxy("_reqs", "requires", getset_factory=load_requires)
@ -260,14 +263,12 @@ class _Base(SqlAlchemyBase):
######
_callback = Column(PickleType)
_call_params = relationship('_CallbackParam',
collection_class=
attribute_mapped_collection('key'))
collection_class=attribute_mapped_collection('key'))
_callback_params = association_proxy("_call_params", "params",
getset_factory=load_callback_parm)
_validator = Column(PickleType)
_val_params = relationship('_CallbackParam',
collection_class=
attribute_mapped_collection('key'))
collection_class=attribute_mapped_collection('key'))
_validator_params = association_proxy("_val_params", "params",
getset_factory=load_callback_parm)
######
@ -282,10 +283,10 @@ class _Base(SqlAlchemyBase):
_consistencies = relationship('_Consistency', secondary=consistency_table,
backref=backref('options',
enable_typechecks=False))
_type = Column(String(50))
_stated = Column(Boolean)
_type = Column(String(50))
__mapper_args__ = {
'polymorphic_identity': 'option',
'polymorphic_identity': 'optionsql',
'polymorphic_on': _type
}
_extra = Column(PickleType)
@ -293,10 +294,8 @@ class _Base(SqlAlchemyBase):
_group_type = Column(String)
_is_build_cache = Column(Boolean, default=False)
#def __init__(self):
def __init__(self, name, multi, warnings_only, doc, extra, calc_properties,
requires, properties, allow_empty_list, opt=undefined):
util.session.add(self)
requires, properties, allow_empty_list, opt=undefined, session=None):
self._name = name
if multi is not undefined:
self._multi = multi
@ -316,14 +315,19 @@ class _Base(SqlAlchemyBase):
self._requires = requires
if properties is not undefined:
self._properties = properties
session.add(self)
def commit(self):
util.session.commit()
def getsession(self):
return util.Session()
def commit(self, session):
session.commit()
del(session)
def _add_consistency(self, func, all_cons_opts, params):
_Consistency(func, all_cons_opts, params)
def _set_default_values(self, default, default_multi):
def _set_default_values(self, default, default_multi, is_multi):
self._default = default
if self.impl_is_multi() and default_multi is not None:
err = self._validate(default_multi)
@ -344,6 +348,9 @@ class _Base(SqlAlchemyBase):
return (None, {})
return ret, self._callback_params
def impl_get_choice_values_params(self):
return self._choice_values_params
def impl_get_validator(self):
ret = self._validator
if ret is None:
@ -351,16 +358,30 @@ class _Base(SqlAlchemyBase):
return ret, self._validator_params
def _impl_getsubdyn(self):
return util.session.query(_Base).filter_by(id=self._subdyn).first()
session = self.getsession()
return session.query(_Base).filter_by(id=self._subdyn).first()
def _impl_getopt(self):
return util.session.query(_Base).filter_by(id=self._opt).first()
session = self.getsession()
return session.query(_Base).filter_by(id=self._opt).first()
def impl_getname(self):
return self._name
def impl_getrequires(self):
return self._requires
session = self.getsession()
requires = session.query(_Require).filter_by(requires_id=self.id).all()
for require in requires:
_ret = []
for req in require.requires:
_ret.append((session.query(_Base).filter_by(id=req.option).first(),
req.expected,
req.action,
req.inverse,
req.transitive,
req.same_action))
yield(_ret)
def impl_getdefault(self):
ret = self._default
@ -381,10 +402,11 @@ class _Base(SqlAlchemyBase):
self._opt = opt.id
def _impl_setsubdyn(self, subdyn):
session = self.getsession()
self._subdyn = subdyn.id
self.commit()
self.commit(session)
def _set_readonly(self):
def _set_readonly(self, has_extra):
self._readonly = True
def _set_callback(self, callback, callback_params):
@ -392,6 +414,11 @@ class _Base(SqlAlchemyBase):
if callback_params is not None:
self._callback_params = callback_params
def impl_set_choice_values_params(self, values, values_params):
self._choice_values = values
if values_params is not None:
self._choice_values_params = values_params
def _set_validator(self, validator, validator_params):
self._validator = validator
if validator_params is not None:
@ -419,27 +446,39 @@ class _Base(SqlAlchemyBase):
return self._warnings_only
def impl_get_calc_properties(self):
try:
return self._calc_properties
except AttributeError:
return frozenset()
session = self.getsession()
return session.query(_CalcProperties).filter_by(require=self.id).all()
#try:
# return self._calc_properties
#except AttributeError:
# return frozenset()
# information
def impl_set_information(self, key, value):
self._informations[key] = value
session = self.getsession()
# self._informations[key] = value
val = session.query(_Information).filter_by(
option=self.id, key=key).first()
if val is None:
session.add(_Information(self.id, key, value))
else:
val.value = value
session.commit()
def impl_get_information(self, key, default=undefined):
"""retrieves one information's item
:param key: the item string (ex: "help")
"""
session = self.getsession()
val = session.query(_Information).filter_by(
option=self.id, key=key).first()
if not val:
if default is not undefined:
return self._informations.get(key, default)
try:
return self._informations[key]
except KeyError: # pragma: optional cover
return default
raise ValueError(_("information's item not found: {0}").format(
key))
return val.value
def _impl_getattributes(self):
slots = set()
@ -448,6 +487,20 @@ class _Base(SqlAlchemyBase):
slots.add(column.key)
return slots
def impl_getproperties(self):
session = self.getsession()
return session.query(_PropertyOption).filter_by(option=self.id).all()
def _set_master_slaves(self, option):
session = self.getsession()
opt = session.query(_Base).filter_by(id=self.id).first()
opt._master_slaves = option.id
self.commit(session)
def _get_master_slave(self):
session = self.getsession()
return session.query(StorageMasterSlaves).filter_by(id=self._master_slaves).first()
class Cache(SqlAlchemyBase):
__tablename__ = 'cache'
@ -477,19 +530,24 @@ class Cache(SqlAlchemyBase):
class StorageOptionDescription(object):
def impl_already_build_caches(self):
return self._is_build_cache
cache = self._is_build_cache
if cache is None:
cache = False
return cache
def impl_get_opt_by_path(self, path):
ret = util.session.query(Cache).filter_by(descr=self.id, path=path).first()
session = self.getsession()
ret = session.query(Cache).filter_by(descr=self.id, path=path).first()
if ret is None:
raise AttributeError(_('no option for path {0}').format(path))
return util.session.query(_Base).filter_by(id=ret.option).first()
return session.query(_Base).filter_by(id=ret.option).first()
def impl_get_path_by_opt(self, opt):
ret = util.session.query(Cache).filter_by(descr=self.id,
session = self.getsession()
ret = session.query(Cache).filter_by(descr=self.id,
option=opt.id).first()
if ret is None:
ret = util.session.query(Cache).filter_by(descr=self.id).first()
ret = session.query(Cache).filter_by(descr=self.id).first()
if ret is None:
raise ConfigError(_('use impl_get_path_by_opt only with root OptionDescription'))
raise AttributeError(_('no option {0} found').format(opt))
@ -499,11 +557,12 @@ class StorageOptionDescription(object):
return getattr(groups, self._group_type)
def impl_build_cache_option(self, descr=None, _currpath=None,
subdyn_path=None):
subdyn_path=None, session=None):
if descr is None:
save = True
descr = self
_currpath = []
session = self.getsession()
else:
save = False
for option in self._impl_getchildren(dyn=False):
@ -512,23 +571,23 @@ class StorageOptionDescription(object):
sub = subdyn_path
if option.impl_is_dynoptiondescription():
sub = '.'.join(_currpath)
util.session.add(Cache(descr, self, option,
session.add(Cache(descr, self, option,
str('.'.join(_currpath + [attr])),
sub))
_currpath.append(attr)
option.impl_build_cache_option(descr,
_currpath,
sub)
sub, session)
_currpath.pop()
else:
if subdyn_path:
subdyn_path = '.'.join(_currpath)
util.session.add(Cache(descr, self, option,
session.add(Cache(descr, self, option,
str('.'.join(_currpath + [attr])),
subdyn_path))
if save:
self._is_build_cache = True
util.session.commit()
self.commit(session)
def impl_get_options_paths(self, bytype, byname, _subpath, only_first,
context):
@ -546,7 +605,8 @@ class StorageOptionDescription(object):
_opt = option._impl_to_dyn(name + suffix, path)
return (path, _opt)
sqlquery = util.session.query(Cache).filter_by(descr=self.id)
session = self.getsession()
sqlquery = session.query(Cache).filter_by(descr=self.id)
if bytype is None:
sqlquery = sqlquery.filter(and_(not_(
Cache.opt_type == 'OptionDescription'),
@ -575,7 +635,7 @@ class StorageOptionDescription(object):
#else:
ret = []
for opt in sqlquery.all():
option = util.session.query(_Base).filter_by(id=opt.option).first()
option = session.query(_Base).filter_by(id=opt.option).first()
if opt.is_subdyn:
name = option.impl_getname()
if byname is not None:
@ -616,21 +676,24 @@ class StorageOptionDescription(object):
return ret
def _add_children(self, child_names, children):
session = self.getsession()
for child in children:
util.session.add(_Parent(self, child))
session.add(_Parent(self, child))
self.commit(session)
def _impl_st_getchildren(self, context, only_dyn=False):
session = self.getsession()
if only_dyn is False or context is undefined:
for child in util.session.query(_Parent).filter_by(
for child in session.query(_Parent).filter_by(
parent_id=self.id).all():
yield(util.session.query(_Base).filter_by(id=child.child_id
yield(session.query(_Base).filter_by(id=child.child_id
).first())
else:
descr = context.cfgimpl_get_description().id
for child in util.session.query(Cache).filter_by(descr=descr,
for child in session.query(Cache).filter_by(descr=descr,
parent=self.id
).all():
yield(util.session.query(_Base).filter_by(id=child.option).first())
yield(session.query(_Base).filter_by(id=child.option).first())
def _getattr(self, name, suffix=undefined, context=undefined, dyn=True):
error = False
@ -640,14 +703,15 @@ class StorageOptionDescription(object):
raise ConfigError(_("suffix and context needed if "
"it's a dyn option"))
if name.endswith(suffix):
session = self.getsession()
oname = name[:-len(suffix)]
#child = self._children[1][self._children[0].index(oname)]
child = util.session.query(_Parent).filter_by(
child = session.query(_Parent).filter_by(
parent_id=self.id, child_name=oname).first()
if child is None:
error = True
else:
opt = util.session.query(_Base).filter_by(
opt = session.query(_Base).filter_by(
id=child.child_id).first()
return self._impl_get_dynchild(opt, suffix)
else:
@ -655,7 +719,8 @@ class StorageOptionDescription(object):
except ValueError: # pragma: optional cover
error = True
else:
child = util.session.query(_Parent).filter_by(parent_id=self.id,
session = self.getsession()
child = session.query(_Parent).filter_by(parent_id=self.id,
child_name=name
).first()
if child is None:
@ -664,7 +729,7 @@ class StorageOptionDescription(object):
return child
error = True
if error is False:
return util.session.query(_Base).filter_by(id=child.child_id
return session.query(_Base).filter_by(id=child.child_id
).first()
if error:
raise AttributeError(_('unknown Option {0} in OptionDescription {1}'
@ -672,12 +737,13 @@ class StorageOptionDescription(object):
def _get_force_store_value(self):
#only option in current tree
current_ids = tuple(chain(*util.session.query(Cache.option).filter_by(
session = self.getsession()
current_ids = tuple(chain(*session.query(Cache.option).filter_by(
descr=self.id).all()))
for prop in util.session.query(_PropertyOption).filter(
for prop in session.query(_PropertyOption).filter(
_PropertyOption.option.in_(current_ids),
_PropertyOption.name == 'force_store_value').all():
opt = util.session.query(_Base).filter_by(id=prop.option).first()
opt = session.query(_Base).filter_by(id=prop.option).first()
path = self.impl_get_path_by_opt(opt)
yield (opt, path)
@ -686,3 +752,39 @@ class StorageBase(_Base):
@declared_attr
def __mapper_args__(self):
return {'polymorphic_identity': self.__name__.lower()}
class _Slave(SqlAlchemyBase):
__tablename__ = 'slaves'
id = Column(Integer, primary_key=True)
master_id = Column(Integer, index=True, nullable=False)
slave_id = Column(Integer)
def __init__(self, master, slave):
self.master_id = master.id
self.slave_id = slave.id
class StorageMasterSlaves(SqlAlchemyBase):
__tablename__ = 'masterslaves2'
id = Column(Integer, primary_key=True)
master = Column(Integer)
def __init__(self, master, slaves):
session = util.Session()
self.master = master.id
session.add(self)
session.commit()
for slave in slaves:
sl = _Slave(self, slave)
session.add(sl)
session.commit()
def _sm_getslaves(self):
session = util.Session()
for slave in session.query(_Slave).filter_by(master_id=self.master).all():
yield(session.query(_Base).filter_by(id=slave.slave_id).first())
def _sm_getmaster(self):
session = util.Session()
return session.query(_Base).filter_by(id=self.master).first()