3 using System
.Collections
;
4 using System
.Threading
;
11 public class QueryFu
{
13 static public Query
NewTokenQuery (string token
)
19 part
= new QueryPart_Text ();
26 static public Query
NewTokenQuery (int id
)
28 return NewTokenQuery (Token
.IdToString (id
));
31 static Random random
= new Random ();
33 static public Query
NewRandomQuery (int length
,
34 bool allow_inexpensive
)
36 return NewRandomQuery (length
, allow_inexpensive
, false);
39 static private Query
NewRandomQuery (int length
,
40 bool allow_inexpensive
,
46 // One in four queries will contain some OR terms.
47 if (! inside_an_or
&& random
.Next (4) == 0) {
48 int N
= random
.Next (3) + 1;
49 for (int i
= 0; i
< N
; ++i
) {
51 part
= new QueryPart_Or ();
54 sub_length
= random
.Next (length
) + 1;
58 // We generate a new query at random, and stuff its QueryParts
59 // into our Or QueryPart.
61 or_query
= NewRandomQuery (sub_length
, allow_inexpensive
, true);
62 foreach (QueryPart sub_part
in or_query
.Parts
)
69 if (allow_inexpensive
&& ! inside_an_or
) {
71 mime_type
= random
.Next (3);
73 query
.AddMimeType ("inode/directory");
74 else if (mime_type
== 1)
75 query
.AddMimeType ("text/plain");
78 // Every query must contain at least
80 bool contains_required
;
81 contains_required
= false;
83 for (int i
= 0; i
< length
; ++i
) {
85 part
= new QueryPart_Text ();
86 part
.Text
= Token
.GetRandom ();
88 // Prohibited parts are not allowed inside an or
89 if (contains_required
&& ! inside_an_or
) {
90 if (random
.Next (2) == 0)
91 part
.Logic
= QueryPartLogic
.Prohibited
;
93 // This part will be required.
94 contains_required
= true;
97 if (random
.Next (2) == 0)
98 part
.SearchTextProperties
= false;
99 else if (allow_inexpensive
&& random
.Next (2) == 0)
100 part
.SearchFullText
= false;
102 query
.AddPart (part
);
105 // Note the ! inside_an_or; date range queries don't
106 // work right inside OR queries when being searched
107 // within the resolution of one day. See the FIXME
108 // about hit filters in LuceneCommon.cs
109 if (allow_inexpensive
&& ! inside_an_or
&& random
.Next (3) == 0) {
111 FileSystemObject
.PickTimestampRange (out a
, out b
);
113 QueryPart_DateRange part
;
114 part
= new QueryPart_DateRange ();
117 query
.AddPart (part
);
123 static public Query
NewRandomQuery ()
125 return NewRandomQuery (2 + random
.Next (4), true);
128 /////////////////////////////////////////////////////////////
130 static public string QueryPartToString (QueryPart abstract_part
)
135 if (abstract_part
is QueryPart_Text
) {
137 part
= (QueryPart_Text
) abstract_part
;
140 if (! (part
.SearchFullText
&& part
.SearchTextProperties
)) {
141 if (part
.SearchFullText
)
142 msg
+= " IN FULLTEXT";
143 else if (part
.SearchTextProperties
)
144 msg
+= " IN TEXT PROPERTIES";
146 msg
+= " IN ANY TEXT";
148 } else if (abstract_part
is QueryPart_Property
) {
149 QueryPart_Property part
;
150 part
= (QueryPart_Property
) abstract_part
;
151 msg
= String
.Format ("PROPERTY {0} = {1}", part
.Key
, part
.Value
);
152 } else if (abstract_part
is QueryPart_DateRange
) {
153 QueryPart_DateRange part
;
154 part
= (QueryPart_DateRange
) abstract_part
;
155 msg
= String
.Format ("DATE RANGE {0} to {1}", part
.StartDate
, part
.EndDate
);
158 if (abstract_part
.Logic
== QueryPartLogic
.Prohibited
)
165 static public void SpewQuery (Query query
)
169 foreach (QueryPart abstract_part
in query
.Parts
) {
173 if (abstract_part
is QueryPart_Or
) {
174 QueryPart_Or part
= abstract_part
as QueryPart_Or
;
176 Log
.Spew ("{0}: OR", i
);
177 foreach (QueryPart sub_part
in part
.SubParts
) {
179 Log
.Spew (" {0}.{1}: {2}", i
, j
, QueryPartToString (sub_part
));
183 Log
.Spew ("{0}: {1}", i
, QueryPartToString (abstract_part
));
188 /////////////////////////////////////////////////////////////
190 private class QueryClosure
{
192 public Hashtable Hits
;
195 public QueryClosure (Query query
)
197 this.Hits
= UriFu
.NewHashtable ();
201 public void OnHitsAdded (HitsAddedResponse response
)
203 foreach (Hit hit
in response
.Hits
)
204 Hits
[hit
.Uri
] = hit
;
207 public void OnFinished (FinishedResponse response
)
214 static public Hashtable
GetHits (Query q
)
217 qc
= new QueryClosure (q
);
218 q
.HitsAddedEvent
+= qc
.OnHitsAdded
;
219 q
.FinishedEvent
+= qc
.OnFinished
;
221 q
.SendAsyncBlocking ();
226 static public ICollection
GetUris (Query q
)
228 return GetHits (q
).Keys
;