# HG changeset patch
# User Sylvain Thénault <sylvain.thenault@logilab.fr>
# Date 1276780304 -7200
#      Thu Jun 17 15:11:44 2010 +0200
# Node ID ba03d9f517373e344d42d1fe7238ec83f26b00e5
# Parent  7b111884fdde8c60d2d5eb69652219a7e81095be
rql stcheck now check for backend availability of function

diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,10 @@
 ChangeLog for RQL
 =================
 
+	--
+    * enhanced Select.replace method
+    * rql st checker now checks function avaibility according to backend (if specified)
+
 2010-06-11  --  0.26.2
     * totally remove 'IS' operator
 
diff --git a/__init__.py b/__init__.py
--- a/__init__.py
+++ b/__init__.py
@@ -38,7 +38,7 @@
       - comparison of two queries
     """
     def __init__(self, schema, uid_func_mapping=None, special_relations=None,
-                 resolver_class=None):
+                 resolver_class=None, backend=None):
         # chech schema
         #for e_type in REQUIRED_TYPES:
         #    if not schema.has_entity(e_type):
@@ -49,7 +49,7 @@
         if uid_func_mapping:
             for key in uid_func_mapping:
                 special_relations[key] = 'uid'
-        self._checker = RQLSTChecker(schema, special_relations)
+        self._checker = RQLSTChecker(schema, special_relations, backend)
         self._annotator = RQLSTAnnotator(schema, special_relations)
         self._analyser_lock = threading.Lock()
         if resolver_class is None:
@@ -76,6 +76,12 @@
         self._annotator.schema = schema
         self._analyser.set_schema(schema)
 
+    def get_backend(self):
+        return self._checker.backend
+    def set_backend(self, backend):
+        self._checker.backend = backend
+    backend = property(get_backend, set_backend)
+
     def parse(self, rqlstring, annotate=True):
         """Return a syntax tree created from a RQL string."""
         rqlst = parse(rqlstring, False)
diff --git a/base.py b/base.py
--- a/base.py
+++ b/base.py
@@ -18,8 +18,8 @@
 """Base classes for RQL syntax tree nodes.
 
 Note: this module uses __slots__ to limit memory usage.
+"""
 
-"""
 __docformat__ = "restructuredtext en"
 
 class BaseNode(object):
diff --git a/editextensions.py b/editextensions.py
--- a/editextensions.py
+++ b/editextensions.py
@@ -15,9 +15,8 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with rql. If not, see <http://www.gnu.org/licenses/>.
-"""RQL functions for manipulating syntax trees.
+"""RQL functions for manipulating syntax trees."""
 
-"""
 __docformat__ = "restructuredtext en"
 
 from rql.nodes import Constant, Variable, VariableRef, Relation, make_relation
diff --git a/stcheck.py b/stcheck.py
--- a/stcheck.py
+++ b/stcheck.py
@@ -80,9 +80,10 @@
     errors due to a bad rql input
     """
 
-    def __init__(self, schema, special_relations=None):
+    def __init__(self, schema, special_relations=None, backend=None):
         self.schema = schema
         self.special_relations = special_relations or {}
+        self.backend = backend
 
     def check(self, node):
         state = STCheckState()
@@ -417,6 +418,11 @@
                 funcdescr.check_nbargs(len(function.children))
             except BadRQLQuery, ex:
                 state.error(str(ex))
+            if self.backend is not None:
+                try:
+                    funcdescr.st_check_backend(self.backend, function)
+                except BadRQLQuery, ex:
+                    state.error(str(ex))
             if funcdescr.aggregat:
                 if isinstance(function.children[0], Function) and \
                        function.children[0].descr().aggregat:
diff --git a/utils.py b/utils.py
--- a/utils.py
+++ b/utils.py
@@ -15,11 +15,12 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with rql. If not, see <http://www.gnu.org/licenses/>.
-"""Miscellaneous utilities for RQL.
+"""Miscellaneous utilities for RQL."""
 
-"""
 __docformat__ = "restructuredtext en"
 
+from rql._exceptions import BadRQLQuery
+
 UPPERCASE = u'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 def decompose_b26(index, table=UPPERCASE):
     """Return a letter (base-26) decomposition of index."""
@@ -78,6 +79,12 @@
         ', '.join(sorted(child.get_description(mainindex, tr)
                          for child in iter_funcnode_variables(funcnode))))
 
+@monkeypatch(FunctionDescr)
+def st_check_backend(self, backend, funcnode):
+    if not self.supports(backend):
+        raise BadRQLQuery("backend %s doesn't support function %s" % (backend, self.name))
+
+
 def iter_funcnode_variables(funcnode):
     for term in funcnode.children:
         try: