cache
authorEmmanuel Garette <egarette@cadoles.com>
Sat, 25 Jan 2014 09:15:25 +0000 (10:15 +0100)
committerEmmanuel Garette <egarette@cadoles.com>
Sat, 25 Jan 2014 09:15:25 +0000 (10:15 +0100)
test/test_dereference.py
tiramisu/config.py
tiramisu/option.py
tiramisu/storage/sqlalchemy/option.py

index eed4b72..e24e1e8 100644 (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', '')
index c9553f2..95a7685 100644 (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
index a295737..014be90 100644 (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 = []
+            init = False
+        for option in self.impl_getchildren():
+            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():
-            attr = option.impl_getname()
+            #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):
index 9d56607..b3a9042 100644 (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))