This commit is contained in:
Emmanuel Garette 2014-01-25 10:15:25 +01:00
parent 3b0b3cdfd9
commit 3b3e5216fe
4 changed files with 84 additions and 54 deletions

View File

@ -68,7 +68,7 @@ def test_deref_optiondescription():
def test_deref_option_cache():
b = BoolOption('b', '')
o = OptionDescription('od', '', [b])
o.impl_build_cache()
o.impl_build_cache_option()
w = weakref.ref(b)
del(b)
assert w() is not None
@ -81,7 +81,7 @@ def test_deref_option_cache():
def test_deref_optiondescription_cache():
b = BoolOption('b', '')
o = OptionDescription('od', '', [b])
o.impl_build_cache()
o.impl_build_cache_option()
w = weakref.ref(o)
del(b)
assert w() is not None
@ -103,6 +103,7 @@ def test_deref_option_config():
#FIXME meme chose
#assert w() is None
#FIXME rien a voir mais si je fais un config.impl_get_path_by_opt() ca me retourne la methode !
def test_deref_optiondescription_config():
b = BoolOption('b', '')

View File

@ -475,8 +475,11 @@ class CommonConfig(SubConfig):
"abstract base class for the Config and the MetaConfig"
__slots__ = ('_impl_values', '_impl_settings', '_impl_meta')
def _impl_build_all_paths(self):
self.cfgimpl_get_description().impl_build_cache()
def _impl_build_all_caches(self):
if not self.cfgimpl_get_description().impl_already_build_caches():
self.cfgimpl_get_description().impl_build_cache_consistency()
self.cfgimpl_get_description().impl_validate_options()
self.cfgimpl_get_description().impl_build_cache_option()
def read_only(self):
"read only is a global config's setting, see `settings.py`"
@ -553,7 +556,7 @@ class Config(CommonConfig):
self._impl_settings = Settings(self, settings)
self._impl_values = Values(self, values)
super(Config, self).__init__(descr, weakref.ref(self))
self._impl_build_all_paths()
self._impl_build_all_caches()
self._impl_meta = None
#undocumented option used only in test script
self._impl_test = False

View File

@ -1223,64 +1223,82 @@ class OptionDescription(BaseOption, StorageOptionDescription):
#for child in self._children:
# yield(session.query(child._type).filter_by(id=child.id).first())
def impl_build_cache(self,
cache_path=None,
cache_option=None,
_currpath=None,
_consistencies=None,
force_no_consistencies=False):
if _currpath is None and self._cache_paths is not None:
# cache already set
return
if _currpath is None:
save = True
_currpath = []
if not force_no_consistencies:
_consistencies = {}
def impl_build_cache_consistency(self, _consistencies=None):
#FIXME cache_option !
if _consistencies is None:
init = True
_consistencies = {}
else:
save = False
if cache_path is None:
cache_path = []
cache_option = []
init = False
for option in self.impl_getchildren():
attr = option.impl_getname()
if not isinstance(option, OptionDescription):
for consistency in option._consistencies:
func = consistency.func
all_cons_opts = consistency.options
for opt in all_cons_opts:
_consistencies.setdefault(opt,
[]).append((func,
all_cons_opts))
else:
option.impl_build_cache_consistency(_consistencies)
if init and _consistencies != {}:
self._cache_consistencies = {}
for opt, cons in _consistencies.items():
#FIXME dans le cache ...
#if opt.id not in cache_option:
# raise ConfigError(_('consistency with option {0} '
# 'which is not in Config').format(
# opt.impl_getname()))
self._cache_consistencies[opt] = tuple(cons)
def impl_validate_options(self, cache_option=None):
"""validate duplicate option and set option has readonly option
"""
if cache_option is None:
init = True
cache_option = []
else:
init = False
for option in self.impl_getchildren():
#FIXME specifique id for sqlalchemy?
#FIXME avec sqlalchemy ca marche le multi parent ? (dans des configs différentes)
if option.id is None:
raise SystemError(_("an option's id should not be None "
"for {0}").format(option.impl_getname()))
if option.id in cache_option:
raise ConflictError(_('duplicate option: {0}').format(option))
cache_option.append(option.id)
if not force_no_consistencies:
option._readonly = True
option._readonly = True
if isinstance(option, OptionDescription):
option.impl_validate_options(cache_option)
if init:
self._readonly = True
def impl_already_build_caches(self):
return self._cache_paths is not None
def impl_build_cache_option(self, cache_path=None, cache_option=None,
_currpath=None):
if _currpath is None:
save = True
_currpath = []
cache_path = []
cache_option = []
else:
save = False
for option in self.impl_getchildren():
attr = option.impl_getname()
#FIXME specifique sqlachemy...
cache_option.append(option.id)
cache_path.append(str('.'.join(_currpath + [attr])))
if not isinstance(option, OptionDescription):
if not force_no_consistencies and \
option._consistencies is not []:
for consistency in option._consistencies:
func = consistency.func
all_cons_opts = consistency.options
for opt in all_cons_opts:
_consistencies.setdefault(opt,
[]).append((func,
all_cons_opts))
else:
if isinstance(option, OptionDescription):
_currpath.append(attr)
option.impl_build_cache(cache_path,
cache_option,
_currpath,
_consistencies,
force_no_consistencies)
option.impl_build_cache_option(cache_path,
cache_option,
_currpath)
_currpath.pop()
if save:
self._cache_paths = (tuple(cache_option), tuple(cache_path))
if not force_no_consistencies:
if _consistencies != {}:
self._cache_consistencies = {}
for opt, cons in _consistencies.items():
if opt.id not in cache_option:
raise ConfigError(_('consistency with option {0} which is not in Config').format(opt.impl_getname()))
self._cache_consistencies[opt] = tuple(cons)
self._readonly = True
# ____________________________________________________________
def impl_set_group_type(self, group_type):

View File

@ -29,6 +29,10 @@ from sqlalchemy.orm import sessionmaker
#FIXME
engine = create_engine('sqlite:///:memory:')
SqlAlchemyBase = declarative_base()
#FIXME a voir:
# # Organization.members will be a Query object - no loading
# # of the entire collection occurs unless requested
# lazy="dynamic",
#____________________________________________________________
#
# require
@ -51,7 +55,8 @@ class _RequireExpected(SqlAlchemyBase):
class _RequireOption(SqlAlchemyBase):
__tablename__ = 'requireoption'
id = Column(Integer, primary_key=True)
r_opt = Column(Integer)
option = relationship('_Base', lazy='joined', cascade="all, delete-orphan")
#option = relationship('_Base')
expected = relationship("_RequireExpected")
action = Column(String, nullable=False)
inverse = Column(Boolean, default=False)
@ -60,7 +65,8 @@ class _RequireOption(SqlAlchemyBase):
def __init__(self, option, expected, action, inverse, transitive,
same_action):
self.r_opt = option.id
#self.r_opt = option.id
self.option = option
for expect in expected:
self.expected.append(_RequireExpected(expect))
self.action = action
@ -175,7 +181,7 @@ class _Base(SqlAlchemyBase):
_default = Column(PickleType)
_default_multi = Column(PickleType)
_requires = relationship('_RequireOption', secondary=require_table,
backref=backref('option', enable_typechecks=False))
backref=backref('self_option', enable_typechecks=False))
_multi = Column(Boolean)
_multitype = Column(String)
_callback = Column(PickleType)
@ -193,6 +199,7 @@ class _Base(SqlAlchemyBase):
_choice_values = Column(PickleType)
_choice_open_values = Column(Boolean)
_type = Column(String(50))
_r_option = Column(Integer, ForeignKey('requireoption.id'))
__mapper_args__ = {
'polymorphic_identity': 'option',
'polymorphic_on': _type
@ -268,7 +275,8 @@ class StorageOptionDescription(object):
def impl_get_path_by_opt(self, opt):
try:
return self._cache_paths[1][self._cache_paths[0].index(opt)]
print opt, type(opt)
return self._cache_paths[1][self._cache_paths[0].index(opt.id)]
except ValueError:
raise AttributeError(_('no option {0} found').format(opt))