svn keywords
[plcapi.git] / PLC / Filter.py
index 9e2640c..8a7ba31 100644 (file)
@@ -1,4 +1,5 @@
-# $Id#
+# $Id$
+# $URL$
 from types import StringTypes
 try:
     set
@@ -63,8 +64,8 @@ class Filter(Parameter, dict):
     example : filter = { '-OFFSET' : 100, '-LIMIT':25}
 
     A realistic example would read
-    GetNodes ( { 'hostname' : '*.edu' , '-SORT' : 'hostname' , '-OFFSET' : 30 , '-LIMIT' : 25 } )
-    and that would return nodes matching '*.edu' in alphabetical order from 31th to 55th
+    GetNodes ( { 'node_type' : 'regular' , 'hostname' : '*.edu' , '-SORT' : 'hostname' , '-OFFSET' : 30 , '-LIMIT' : 25 } )
+    and that would return regular (usual) nodes matching '*.edu' in alphabetical order from 31th to 55th
     """
 
     def __init__(self, fields = {}, filter = {}, doc = "Attribute filter"):
@@ -74,28 +75,13 @@ class Filter(Parameter, dict):
         # Declare ourselves as a type of parameter that can take
         # either a value or a list of values for each of the specified
         # fields.
-        self.fields = {}
-
-        for field, expected in fields.iteritems():
-            # Cannot filter on sequences
-            if python_type(expected) in (list, tuple, set):
-                continue
-            
-            # Accept either a value or a list of values of the specified type
-            self.fields[field] = Mixed(expected, [expected])
+        self.fields = dict ( [ ( field, Mixed (expected, [expected])) 
+                                 for (field,expected) in fields.iteritems()
+                                 if python_type(expected) not in (list, tuple, set) ] )
 
         # Null filter means no filter
         Parameter.__init__(self, self.fields, doc = doc, nullok = True)
 
-    # this code is not used anymore
-    # at some point the select in the DB for event objects was done on
-    # the events table directly, that is stored as a timestamp, thus comparisons
-    # needed to be done based on SQL timestamps as well
-    def unix2timestamp (self,unix):
-       s = time.gmtime(unix)
-       return "TIMESTAMP'%04d-%02d-%02d %02d:%02d:%02d'" % (s.tm_year,s.tm_mon,s.tm_mday,
-                                                            s.tm_hour,s.tm_min,s.tm_sec)
-
     def sql(self, api, join_with = "AND"):
         """
         Returns a SQL conditional that represents this filter.
@@ -135,13 +121,18 @@ class Filter(Parameter, dict):
                     raise PLCInvalidArgument, "Invalid filter field '%s'" % field
 
                 if isinstance(value, (list, tuple, set)):
-                    # Turn empty list into (NULL) instead of invalid ()
+                    # handling filters like '~slice_id':[]
+                    # this should return true, as it's the opposite of 'slice_id':[] which is false
+                    # prior to this fix, 'slice_id':[] would have returned ``slice_id IN (NULL) '' which is unknown 
+                    # so it worked by coincidence, but the negation '~slice_ids':[] would return false too
                     if not value:
-                        value = [None]
-
-                    operator = "IN"
-                    value = map(str, map(api.db.quote, value))
-                    value = "(%s)" % ", ".join(value)
+                        field=""
+                        operator=""
+                        value = "FALSE"
+                    else:
+                        operator = "IN"
+                        value = map(str, map(api.db.quote, value))
+                        value = "(%s)" % ", ".join(value)
                 else:
                     if value is None:
                         operator = "IS"
@@ -149,7 +140,12 @@ class Filter(Parameter, dict):
                     elif isinstance(value, StringTypes) and \
                             (value.find("*") > -1 or value.find("%") > -1):
                         operator = "LIKE"
-                        value = str(api.db.quote(value.replace("*", "%")))
+                        # insert *** in pattern instead of either * or %
+                        # we dont use % as requests are likely to %-expansion later on
+                        # actual replacement to % done in PostgreSQL.py
+                        value = value.replace ('*','***')
+                        value = value.replace ('%','***')
+                        value = str(api.db.quote(value))
                     else:
                         operator = "="
                         if modifiers['<']: