Commits

Matt Chaput committed 34ae562

Added ability to say *:* in the parser to get query.Every().

Comments (0)

Files changed (3)

src/whoosh/qparser/default.py

                 plugins.GroupPlugin(),
                 plugins.OperatorsPlugin(),
                 plugins.BoostPlugin(),
+                plugins.EveryPlugin(),
                 ]
 
     def add_plugins(self, pins):

src/whoosh/qparser/plugins.py

     
     def create(self, parser, match):
         kwargs = match.groupdict()
-        
-        if not PY3:
-            def convert_unicode_keys(d):
-                if isinstance(d, dict):
-                	return dict([(k.encode("utf-8"), convert_unicode_keys(v))\
-                	        for k, v in iteritems(d)])
-                return d
-            kwargs = convert_unicode_keys(kwargs)
-        
         return self.nodetype(**kwargs)
 
 
         return top
 
 
+class EveryPlugin(TaggingPlugin):
+    expr = "[*]:[*]"
+    priority = -1
+    
+    def create(self, parser, match):
+        return self.EveryNode()
+        
+    class EveryNode(syntax.SyntaxNode):
+        def r(self):
+            return "*:*"
+        
+        def query(self, parser):
+            return query.Every()
+
+
 class FieldsPlugin(TaggingPlugin):
     """Adds the ability to specify the field of a clause.
     """
         def create(self, parser, match):
             return syntax.FieldnameNode(match.group("text"), match.group(0))
     
-    def __init__(self, expr=r"(?P<text>\w+):", remove_unknown=True):
+    def __init__(self, expr=r"(?P<text>\w+|[*]):", remove_unknown=True):
         """
         :param expr: the regular expression to use for tagging fields.
         :param remove_unknown: if True, converts field specifications for
             prev_field_node = None
             
             for node in group:
-                if isinstance(node, fnclass) and node.fieldname not in schema:
+                if (isinstance(node, fnclass) and node.fieldname not in schema):
                     prev_field_node = node
                     continue
                 elif prev_field_node:

tests/test_parsing.py

     qp = default.QueryParser("text", schema)
     q = qp.parse(u("*"))
     assert_equal(q.__class__, query.Every)
-
+    assert_equal(q.fieldname, "text")
+    
     q = qp.parse(u("*h?ll*"))
     assert_equal(q.__class__, query.Wildcard)
     assert_equal(q.text, "*h?ll*")
     assert_equal(q.__class__, query.Wildcard)
     assert_equal(q.text, "*q")
 
+def test_star_field():
+    schema = fields.Schema(text=fields.TEXT)
+    qp = default.QueryParser("text", schema)
+    
+    q = qp.parse(u("*:*"))
+    assert_equal(q.__class__, query.Every)
+    assert_equal(q.fieldname, None)
+    
+    # This gets parsed to a term with text="*:test" which is then analyzed down
+    # to just "test"
+    q = qp.parse(u("*:test"))
+    assert_equal(q.__class__, query.Term)
+    assert_equal(q.fieldname, "text")
+    assert_equal(q.text, "test")
+    
 def test_range_query():
     schema = fields.Schema(name=fields.ID(stored=True), text = fields.TEXT(stored=True))
     qp = default.QueryParser("text", schema)