View Javadoc

1   /***
2    *  Copyright 2003-2010 Terracotta, Inc.
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  
17  package net.sf.ehcache.search;
18  
19  import static org.junit.Assert.assertEquals;
20  import static org.junit.Assert.assertFalse;
21  import static org.junit.Assert.assertTrue;
22  import static org.junit.Assert.fail;
23  
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.HashSet;
27  import java.util.List;
28  import java.util.Set;
29  
30  import org.junit.Test;
31  
32  import net.sf.ehcache.Cache;
33  import net.sf.ehcache.CacheException;
34  import net.sf.ehcache.CacheManager;
35  import net.sf.ehcache.Ehcache;
36  import net.sf.ehcache.Element;
37  import net.sf.ehcache.config.CacheConfiguration;
38  import net.sf.ehcache.config.Configuration;
39  import net.sf.ehcache.config.SearchAttribute;
40  import net.sf.ehcache.config.Searchable;
41  import net.sf.ehcache.search.Person.Gender;
42  import net.sf.ehcache.search.aggregator.Aggregator;
43  import net.sf.ehcache.search.aggregator.AggregatorException;
44  import net.sf.ehcache.search.aggregator.AggregatorInstance;
45  import net.sf.ehcache.search.expression.Or;
46  
47  public class BasicSearchTest {
48  
49      @Test
50      public void testInvalidConfiguration() {
51          try {
52              new CacheManager(getClass().getResource("/ehcache-search-invalid-key.xml"));
53              fail();
54          } catch (CacheException ce) {
55              // expected
56          }
57  
58          try {
59              new CacheManager(getClass().getResource("/ehcache-search-invalid-value.xml"));
60              fail();
61          } catch (CacheException ce) {
62              // expected
63          }
64      }
65  
66      @Test
67      public void testKeysValuesDisabled() {
68          CacheManager cacheManager = new CacheManager(getClass().getResource("/ehcache-search.xml"));
69  
70          Cache cache = cacheManager.getCache("searchable-no-keys-values");
71  
72          CacheConfiguration config = cache.getCacheConfiguration();
73  
74          Searchable searchable = config.getSearchable();
75  
76          assertFalse(searchable.keys());
77          assertFalse(searchable.values());
78  
79          try {
80              cache.getSearchAttribute(Query.KEY.getAttributeName());
81              fail();
82          } catch (CacheException se) {
83              // expected
84              System.err.println(se.getMessage());
85          }
86  
87          try {
88              cache.getSearchAttribute(Query.VALUE.getAttributeName());
89              fail();
90          } catch (CacheException se) {
91              // expected
92              System.err.println(se.getMessage());
93          }
94      }
95  
96      @Test
97      public void testNonSearchableCache() {
98          CacheManager cacheManager = new CacheManager(getClass().getResource("/ehcache-search.xml"));
99          Ehcache cache = cacheManager.getEhcache("not-searchable");
100         assertFalse(cache.isSearchable());
101 
102         try {
103             cache.createQuery();
104             fail();
105         } catch (CacheException e) {
106             // expected
107         }
108     }
109 
110     @Test
111     public void testDefaultSearchableCache() {
112         CacheManager cacheManager = new CacheManager(getClass().getResource("/ehcache-search.xml"));
113         Ehcache cache = cacheManager.getEhcache("default-searchable");
114         assertTrue(cache.isSearchable());
115 
116         cache.put(new Element("key", new Object()));
117         cache.put(new Element(new Object(), "value"));
118         cache.put(new Element(new Object(), new Object()));
119         cache.put(new Element(null, null));
120 
121         Query query;
122         Results results;
123 
124         query = cache.createQuery();
125         query.includeKeys();
126         query.addCriteria(Query.KEY.eq("key")).end();
127         results = query.execute();
128         assertEquals(1, results.size());
129         assertEquals("key", results.all().iterator().next().getKey());
130 
131         query = cache.createQuery();
132         query.includeKeys();
133         query.addCriteria(Query.VALUE.eq("value")).end();
134         results = query.execute();
135         assertEquals(1, results.size());
136         Object key = results.all().iterator().next().getKey();
137         assertEquals("value", cache.get(key).getObjectValue());
138     }
139 
140     @Test
141     public void testQueryBuilder() {
142         CacheManager cacheManager = new CacheManager(getClass().getResource("/ehcache-search.xml"));
143         Ehcache cache = cacheManager.getEhcache("cache1");
144 
145         Query query1 = cache.createQuery();
146         Query query2 = cache.createQuery();
147 
148         // query instances should be unique
149         assertFalse(query1 == query2);
150 
151         // null checks
152         try {
153             query1.addCriteria(null);
154             fail();
155         } catch (NullPointerException npe) {
156             // expected
157         }
158         try {
159             query1.addOrderBy(null, Direction.ASCENDING);
160             fail();
161         } catch (NullPointerException npe) {
162             // expected
163         }
164         try {
165             query1.addOrderBy(new Attribute("foo"), null);
166             fail();
167         } catch (NullPointerException npe) {
168             // expected
169         }
170         try {
171             query1.includeAggregator((Aggregator[]) null);
172             fail();
173         } catch (NullPointerException npe) {
174             // expected
175         }
176         try {
177             query1.includeAttribute((Attribute[]) null);
178             fail();
179         } catch (NullPointerException npe) {
180             // expected
181         }
182         try {
183             query1.includeAttribute(new Attribute[] { new Attribute("foo"), null });
184             fail();
185         } catch (NullPointerException npe) {
186             // expected
187         }
188 
189         // freeze query
190         query1.end();
191 
192         try {
193             query1.addCriteria(new Attribute("foo").le(35));
194             fail();
195         } catch (SearchException se) {
196             // expected
197         }
198         try {
199             query1.addOrderBy(new Attribute("foo"), Direction.ASCENDING);
200             fail();
201         } catch (SearchException se) {
202             // expected
203         }
204         try {
205             query1.includeAggregator(new Attribute("foo").max());
206             fail();
207         } catch (SearchException se) {
208             // expected
209         }
210         try {
211             query1.includeAttribute(new Attribute("foo"));
212             fail();
213         } catch (SearchException se) {
214             // expected
215         }
216         try {
217             query1.includeKeys();
218             fail();
219         } catch (SearchException se) {
220             // expected
221         }
222         try {
223             query1.maxResults(3);
224             fail();
225         } catch (SearchException se) {
226             // expected
227         }
228     }
229 
230     @Test
231     public void testRange() {
232         CacheManager cacheManager = new CacheManager(getClass().getResource("/ehcache-search.xml"));
233         Ehcache cache = cacheManager.getEhcache("cache1");
234         SearchTestUtil.populateData(cache);
235 
236         Query query = cache.createQuery();
237         query.includeKeys();
238         query.end();
239 
240         Results results = query.execute();
241         assertEquals(4, results.all().size());
242 
243         List<Integer> keys = new ArrayList<Integer>();
244         for (int i = 0; i < 4; i++) {
245             List<Result> range = results.range(i, 1);
246             assertEquals(1, range.size());
247             keys.add((Integer) range.get(0).getKey());
248         }
249         assertEquals(4, keys.size());
250 
251         for (int i = 0; i < 4; i++) {
252             assertEquals(0, results.range(i, 0).size());
253         }
254 
255         assertEquals(0, results.range(0, 0).size());
256         assertEquals(1, results.range(0, 1).size());
257         assertEquals(2, results.range(0, 2).size());
258         assertEquals(3, results.range(0, 3).size());
259         assertEquals(4, results.range(0, 4).size());
260         assertEquals(4, results.range(0, 5).size());
261         assertEquals(4, results.range(0, Integer.MAX_VALUE).size());
262 
263         try {
264             results.range(-1, 1);
265             fail();
266         } catch (IllegalArgumentException iae) {
267             // expected
268         }
269 
270         try {
271             results.range(0, -1);
272             fail();
273         } catch (IllegalArgumentException iae) {
274             // expected
275         }
276     }
277 
278     @Test
279     public void testBasic() {
280         CacheManager cacheManager = new CacheManager(getClass().getResource("/ehcache-search.xml"));
281 
282         // uses expression attribute extractors
283         basicQueries(cacheManager.getEhcache("cache1"));
284 
285         // uses a "custom" attribute extractor too
286         basicQueries(cacheManager.getEhcache("cache2"));
287 
288         // uses bean attributes
289         basicQueries(cacheManager.getEhcache("bean-attributes"));
290     }
291 
292     @Test
293     public void testCustomAggregator() {
294         CacheManager cacheManager = new CacheManager(getClass().getResource("/ehcache-search.xml"));
295         Ehcache cache = cacheManager.getEhcache("cache1");
296         SearchTestUtil.populateData(cache);
297 
298         Attribute<Integer> age = cache.getSearchAttribute("age");
299 
300         Query query = cache.createQuery();
301         query.includeAggregator(new Aggregator() {
302             public AggregatorInstance<Integer> createInstance() {
303                 return new AggregatorInstance<Integer>() {
304 
305                     private int doubledSum;
306 
307                     public void accept(Object input) throws AggregatorException {
308                         if (doubledSum == 0) {
309                             doubledSum = (2 * (Integer) input);
310                         } else {
311                             doubledSum += (2 * (Integer) input);
312                         }
313                     }
314 
315                     public Integer aggregateResult() {
316                         return doubledSum;
317                     }
318 
319                     public Attribute<?> getAttribute() {
320                         return new Attribute("age");
321                     }
322                 };
323             }
324         });
325         query.end();
326 
327         Results results = query.execute();
328         assertEquals(1, results.size());
329         for (Result result : results.all()) {
330             assertEquals(246, result.getAggregatorResults().get(0));
331         }
332     }
333 
334     @Test
335     public void testBuiltinFunctions() {
336         CacheManager cacheManager = new CacheManager(getClass().getResource("/ehcache-search.xml"));
337         Ehcache cache = cacheManager.getEhcache("cache1");
338         SearchTestUtil.populateData(cache);
339 
340         Attribute<Integer> age = cache.getSearchAttribute("age");
341 
342         {
343             Query query = cache.createQuery();
344             query.includeAggregator(age.count());
345             query.end();
346 
347             Results results = query.execute();
348             assertTrue(results.hasAggregators());
349             assertEquals(1, results.size());
350             for (Result result : results.all()) {
351                 System.err.println(result); // exercise toString()
352                 assertEquals(4, result.getAggregatorResults().get(0));
353             }
354         }
355 
356         {
357             Query query = cache.createQuery();
358             query.includeAggregator(age.max());
359             query.end();
360 
361             Results results = query.execute();
362             assertTrue(results.hasAggregators());
363             assertEquals(1, results.size());
364             for (Result result : results.all()) {
365                 assertEquals(35, result.getAggregatorResults().get(0));
366             }
367         }
368 
369         {
370             Query query = cache.createQuery();
371             query.includeAggregator(age.min());
372             query.end();
373 
374             Results results = query.execute();
375             assertTrue(results.hasAggregators());
376             assertEquals(1, results.size());
377             for (Result result : results.all()) {
378                 assertEquals(23, result.getAggregatorResults().get(0));
379             }
380         }
381 
382         {
383             Query query = cache.createQuery();
384             query.includeAggregator(age.sum());
385             query.end();
386 
387             Results results = query.execute();
388             assertTrue(results.hasAggregators());
389             assertEquals(1, results.size());
390             for (Result result : results.all()) {
391                 assertEquals(123L, result.getAggregatorResults().get(0));
392             }
393         }
394 
395         {
396             Query query = cache.createQuery();
397             query.includeAggregator(age.average());
398             query.end();
399 
400             Results results = query.execute();
401             assertTrue(results.hasAggregators());
402             assertEquals(1, results.size());
403             for (Result result : results.all()) {
404                 assertEquals(30.75F, result.getAggregatorResults().get(0));
405             }
406         }
407 
408         {
409             // multiple aggregators
410             Query query = cache.createQuery();
411             query.includeAggregator(age.min());
412             query.includeAggregator(age.max());
413             query.end();
414 
415             Results results = query.execute();
416             assertTrue(results.hasAggregators());
417             assertEquals(1, results.size());
418             for (Result result : results.all()) {
419                 assertEquals(23, result.getAggregatorResults().get(0));
420                 assertEquals(35, result.getAggregatorResults().get(1));
421             }
422         }
423 
424         {
425             // use criteria with an aggregator
426             Query query = cache.createQuery();
427             query.includeAggregator(age.average());
428             query.addCriteria(age.between(0, 32));
429             query.end();
430 
431             Results results = query.execute();
432             assertTrue(results.hasAggregators());
433             assertEquals(1, results.size());
434             for (Result result : results.all()) {
435                 assertEquals(26.5F, result.getAggregatorResults().get(0));
436             }
437         }
438 
439         {
440             // includeKeys in addition to an aggregator
441             Query query = cache.createQuery();
442             query.includeKeys();
443             query.includeAggregator(age.average());
444             query.addCriteria(age.between(0, 32));
445             query.end();
446 
447             Results results = query.execute();
448             assertTrue(results.hasAggregators());
449             assertTrue(results.hasKeys());
450             assertEquals(2, results.size());
451             for (Result result : results.all()) {
452                 assertEquals(26.5F, result.getAggregatorResults().get(0));
453             }
454 
455             verify(cache, query, 2, 4);
456         }
457 
458         {
459             // execute query twice
460             Query query = cache.createQuery();
461             query.includeAggregator(age.count());
462             query.end();
463 
464             Results results = query.execute();
465             assertTrue(results.hasAggregators());
466             assertFalse(results.hasKeys());
467             for (Result result : results.all()) {
468                 assertEquals(4, result.getAggregatorResults().get(0));
469             }
470 
471             results = query.execute();
472             assertTrue(results.hasAggregators());
473             assertFalse(results.hasKeys());
474             for (Result result : results.all()) {
475                 assertEquals(4, result.getAggregatorResults().get(0));
476             }
477         }
478     }
479 
480     @Test
481     public void testMaxResults() {
482         CacheManager cacheManager = new CacheManager(getClass().getResource("/ehcache-search.xml"));
483         Ehcache cache = cacheManager.getEhcache("cache1");
484         SearchTestUtil.populateData(cache);
485 
486         Attribute<Integer> age = cache.getSearchAttribute("age");
487         Attribute<Person.Gender> gender = cache.getSearchAttribute("gender");
488 
489         Query query = cache.createQuery();
490         query.includeKeys();
491         query.addCriteria(age.ne(35));
492         query.maxResults(1);
493         query.end();
494 
495         Results results = query.execute();
496         assertEquals(1, results.size());
497         for (Result result : results.all()) {
498             switch ((Integer) result.getKey()) {
499                 case 2:
500                 case 4: {
501                     break;
502                 }
503                 default: {
504                     throw new AssertionError(result.getKey());
505                 }
506             }
507         }
508 
509         query = cache.createQuery();
510         query.includeKeys();
511         query.addCriteria(age.ne(35));
512         query.maxResults(0);
513         query.end();
514 
515         results = query.execute();
516         assertEquals(0, results.size());
517 
518         query = cache.createQuery();
519         query.includeKeys();
520         query.addCriteria(age.ne(35));
521         query.maxResults(2);
522         query.end();
523 
524         results = query.execute();
525         assertEquals(2, results.size());
526 
527         query = cache.createQuery();
528         query.includeKeys();
529         query.addCriteria(age.ne(35));
530         query.maxResults(2);
531         query.end();
532 
533         results = query.execute();
534         assertEquals(2, results.size());
535 
536         query = cache.createQuery();
537         query.includeKeys();
538         query.addCriteria(age.ne(35));
539         query.maxResults(-1);
540         query.end();
541 
542         results = query.execute();
543         assertEquals(2, results.size());
544     }
545 
546     @Test
547     public void testAttributeQuery() {
548         CacheManager cacheManager = new CacheManager(getClass().getResource("/ehcache-search.xml"));
549         Ehcache cache = cacheManager.getEhcache("cache1");
550         SearchTestUtil.populateData(cache);
551 
552         Attribute<Integer> age = cache.getSearchAttribute("age");
553         Attribute<Person.Gender> gender = cache.getSearchAttribute("gender");
554 
555         Query query = cache.createQuery();
556         // not including keys
557         query.addCriteria(age.ne(35));
558         query.includeAttribute(age, gender);
559         query.end();
560 
561         Results results = query.execute();
562         assertFalse(results.hasKeys());
563         assertFalse(results.hasAggregators());
564         assertTrue(results.hasAttributes());
565 
566         for (Result result : results.all()) {
567             System.err.println(result.toString()); // exercise toString()
568 
569             try {
570                 result.getKey();
571                 fail();
572             } catch (SearchException se) {
573                 // expected
574             }
575 
576             try {
577                 result.getKey();
578                 fail();
579             } catch (SearchException se) {
580                 // expected
581             }
582 
583             int ageAttr = result.getAttribute(age);
584             if (ageAttr == 23) {
585                 assertEquals(Gender.FEMALE, result.getAttribute(gender));
586             } else if (ageAttr == 30) {
587                 assertEquals(Gender.MALE, result.getAttribute(gender));
588             } else {
589                 throw new AssertionError("unexpected age: " + ageAttr);
590             }
591 
592             try {
593                 result.getAttribute(new Attribute("does-not-exist"));
594                 fail();
595             } catch (SearchException se) {
596                 // expected
597             }
598         }
599 
600     }
601 
602     private void basicQueries(Ehcache cache) {
603         SearchTestUtil.populateData(cache);
604 
605         Query query;
606         Attribute<Integer> age = cache.getSearchAttribute("age");
607 
608         query = cache.createQuery();
609         query.includeKeys();
610         query.addCriteria(age.ne(35));
611         query.end();
612         verify(cache, query, 2, 4);
613 
614         query = cache.createQuery();
615         query.includeKeys();
616         query.addCriteria(cache.getSearchAttribute("age").lt(30));
617         query.end();
618         query.execute();
619         verify(cache, query, 2);
620 
621         query = cache.createQuery();
622         query.includeKeys();
623         query.addCriteria(cache.getSearchAttribute("age").le(30));
624         query.end();
625         query.execute();
626         verify(cache, query, 2, 4);
627 
628         query = cache.createQuery();
629         query.includeKeys();
630         query.addCriteria(cache.getSearchAttribute("age").in(new HashSet(Arrays.asList(23, 35))));
631         query.end();
632         query.execute();
633         verify(cache, query, 1, 2, 3);
634 
635         query = cache.createQuery();
636         query.includeKeys();
637         query.addCriteria(cache.getSearchAttribute("age").gt(30));
638         query.end();
639         query.execute();
640         verify(cache, query, 1, 3);
641 
642         query = cache.createQuery();
643         query.includeKeys();
644         query.addCriteria(cache.getSearchAttribute("age").between(23, 35, true, false));
645         query.end();
646         query.execute();
647         verify(cache, query, 2, 4);
648 
649         query = cache.createQuery();
650         query.includeKeys();
651         query.addCriteria(cache.getSearchAttribute("age").ge(30));
652         query.end();
653         query.execute();
654         verify(cache, query, 1, 3, 4);
655 
656         query = cache.createQuery();
657         query.includeKeys();
658         query.addCriteria(cache.getSearchAttribute("age").eq(35).or(cache.getSearchAttribute("gender").eq(Gender.FEMALE)));
659         query.end();
660         verify(cache, query, 1, 2, 3);
661 
662         query = cache.createQuery();
663         query.includeKeys();
664         query.addCriteria(cache.getSearchAttribute("age").eq(35).and(cache.getSearchAttribute("gender").eq(Gender.MALE)));
665         query.end();
666         verify(cache, query, 1, 3);
667 
668         query = cache.createQuery();
669         query.includeKeys();
670         query.addCriteria(cache.getSearchAttribute("age").eq(35).and(cache.getSearchAttribute("gender").eq(Gender.FEMALE)));
671         query.end();
672         verify(cache, query);
673 
674         query = cache.createQuery();
675         query.includeKeys();
676         query.addCriteria(cache.getSearchAttribute("age").eq(35));
677         query.addCriteria(cache.getSearchAttribute("gender").eq(Gender.FEMALE));
678         query.end();
679         verify(cache, query);
680 
681         query = cache.createQuery();
682         query.includeKeys();
683         query.addCriteria(cache.getSearchAttribute("gender").eq(Gender.MALE).not());
684         query.end();
685         verify(cache, query, 2);
686 
687         query = cache.createQuery();
688         query.includeKeys();
689         query.addCriteria(cache.getSearchAttribute("name").eq("Tim Eck"));
690         query.addCriteria(cache.getSearchAttribute("gender").eq(Gender.MALE));
691         query.addCriteria(cache.getSearchAttribute("age").eq(35));
692         query.end();
693         verify(cache, query, 1);
694 
695         query = cache.createQuery();
696         query.includeKeys();
697         Attribute name = cache.getSearchAttribute("name");
698         query.addCriteria(name.eq("Tim Eck").or(name.eq("Ari Zilka")).or(name.eq("Nabib El-Rahman")));
699         query.end();
700         verify(cache, query, 1, 3, 4);
701 
702         try {
703             cache.getSearchAttribute("DOES_NOT_EXIST_PLEASE_DO_NOT_CREATE_ME");
704             fail();
705         } catch (CacheException ce) {
706             // expected
707         }
708     }
709 
710     @Test
711     public void testOrdering() {
712         CacheManager cacheManager = new CacheManager(getClass().getResource("/ehcache-search.xml"));
713         Ehcache cache = cacheManager.getEhcache("cache1");
714         SearchTestUtil.populateData(cache);
715 
716         Attribute<Integer> age = cache.getSearchAttribute("age");
717         Attribute<String> name = cache.getSearchAttribute("name");
718 
719         Query query;
720 
721         query = cache.createQuery();
722         query.includeKeys();
723         // no critera -- select all elements
724         query.addOrderBy(age, Direction.DESCENDING);
725         query.addOrderBy(name, Direction.ASCENDING);
726         query.end();
727 
728         verifyOrdered(cache, query, 3, 1, 4, 2);
729 
730         query = cache.createQuery();
731         query.includeKeys();
732         // no critera -- select all elements
733         query.addOrderBy(age, Direction.DESCENDING);
734         query.addOrderBy(name, Direction.ASCENDING);
735         query.maxResults(2);
736         query.end();
737 
738         verifyOrdered(cache, query, 3, 1);
739     }
740 
741     @Test
742     public void testILike() {
743         CacheManager cacheManager = new CacheManager(getClass().getResource("/ehcache-search.xml"));
744         Ehcache cache = cacheManager.getEhcache("cache1");
745         SearchTestUtil.populateData(cache);
746 
747         Attribute<String> name = cache.getSearchAttribute("name");
748 
749         Query query;
750 
751         query = cache.createQuery();
752         query.includeKeys();
753         query.addCriteria(new Or(name.ilike("tim*"), name.ilike("ari*")));
754         query.end();
755 
756         verify(cache, query, 3, 1);
757 
758         cache.removeAll();
759         cache.put(new Element(1, new Person("Test // Bob * ?", 35, Gender.MALE)));
760         cache.put(new Element(2, new Person("(..Test", 35, Gender.MALE)));
761         cache.put(new Element(3, new Person("lowercase", 35, Gender.MALE)));
762         cache.put(new Element(4, new Person("UPPERCASE", 35, Gender.MALE)));
763         cache.put(new Element(5, new Person("MiXeD", 35, Gender.MALE)));
764         cache.put(new Element(6, new Person("Hello there\nI am on a newline\nMe too\n", 999, Gender.MALE)));
765 
766         query = cache.createQuery();
767         query.includeKeys();
768         query.addCriteria(name.ilike("Test //// Bob //* //?"));
769         query.end();
770 
771         verify(cache, query, 1);
772 
773         query = cache.createQuery();
774         query.includeKeys();
775         query.addCriteria(name.ilike("*Test*"));
776         query.end();
777 
778         verify(cache, query, 1, 2);
779 
780         query = cache.createQuery();
781         query.includeKeys();
782         query.addCriteria(name.ilike("Test*//?"));
783         query.end();
784 
785         verify(cache, query, 1);
786 
787         query = cache.createQuery();
788         query.includeKeys();
789         query.addCriteria(name.ilike("(..*"));
790         query.end();
791 
792         verify(cache, query, 2);
793 
794         query = cache.createQuery();
795         query.includeKeys();
796         query.addCriteria(name.ilike("Lowercase"));
797         query.end();
798 
799         verify(cache, query, 3);
800 
801         query = cache.createQuery();
802         query.includeKeys();
803         query.addCriteria(name.ilike("LOWER*"));
804         query.end();
805 
806         verify(cache, query, 3);
807 
808         query = cache.createQuery();
809         query.includeKeys();
810         query.addCriteria(name.ilike("uppercase"));
811         query.end();
812 
813         verify(cache, query, 4);
814 
815         query = cache.createQuery();
816         query.includeKeys();
817         query.addCriteria(name.ilike("mixed"));
818         query.end();
819 
820         verify(cache, query, 5);
821 
822         query = cache.createQuery();
823         query.includeKeys();
824         query.addCriteria(name.ilike("*am on a*"));
825         query.end();
826 
827         verify(cache, query, 6);
828 
829     }
830 
831     @Test
832     public void testTypeChecking() {
833         CacheManager cm = new CacheManager(new Configuration().defaultCache(new CacheConfiguration()));
834 
835         CacheConfiguration config = new CacheConfiguration("test", 0);
836         config.setOverflowToDisk(false);
837         config.diskPersistent(false);
838         config.setEternal(true);
839         Searchable searchable = new Searchable().searchAttribute(new SearchAttribute().name("attr").expression("value.getAttr()"));
840         config.addSearchable(searchable);
841 
842         cm.addCache(new Cache(config));
843 
844         class Value {
845             private final Object attr;
846 
847             Value(Object attr) {
848                 this.attr = attr;
849             }
850 
851             Object getAttr() {
852                 return attr;
853             }
854         }
855 
856         Ehcache cache = cm.getEhcache("test");
857         cache.put(new Element(1, new Value("foo")));
858 
859         Query query = cache.createQuery();
860         query.includeKeys();
861         query.addCriteria(cache.getSearchAttribute("attr").le(4));
862         query.end();
863 
864         try {
865             query.execute();
866             fail();
867         } catch (SearchException se) {
868             // expected since the criteria wants INT, but actual attribute value is STRING
869         }
870 
871         // with proper type search will execute
872         cache.put(new Element(1, new Value(4)));
873         assertEquals(1, query.execute().all().iterator().next().getKey());
874     }
875 
876     @Test
877     public void testEmptyQueries() {
878         CacheManager cacheManager = new CacheManager(getClass().getResource("/ehcache-search.xml"));
879         Ehcache cache = cacheManager.getEhcache("cache1");
880         SearchTestUtil.populateData(cache);
881 
882         {
883             Query query = cache.createQuery();
884             query.end();
885             try {
886                 query.execute();
887                 fail();
888             } catch (SearchException e) {
889                 System.err.println("Expected " + e);
890             }
891         }
892 
893         {
894             Attribute<Integer> age = cache.getSearchAttribute("age");
895             Query query = cache.createQuery();
896             query.addCriteria(age.ne(35));
897             query.end();
898             try {
899                 query.execute();
900                 fail();
901             } catch (SearchException e) {
902                 System.err.println("Expected " + e);
903             }
904         }
905     }
906 
907     @Test
908     public void testIncludeValues() {
909         CacheManager cacheManager = new CacheManager(getClass().getResource("/ehcache-search.xml"));
910         Ehcache cache = cacheManager.getEhcache("cache1");
911         SearchTestUtil.populateData(cache);
912 
913         {
914             Query query = cache.createQuery();
915             query.includeValues();
916             query.end();
917             Results results = query.execute();
918             assertTrue(results.hasValues());
919             assertEquals(4, results.size());
920             int ageSum = 0;
921             for (Result result : results.all()) {
922                 System.err.println(result.toString()); // exercise toString()
923 
924                 Person p = (Person) result.getValue();
925                 ageSum += p.getAge();
926                 try {
927                     result.getKey();
928                     fail();
929                 } catch (SearchException se) {
930                     // expected since keys not included
931                 }
932             }
933 
934             assertEquals(123, ageSum);
935         }
936 
937         {
938             Query query = cache.createQuery();
939             query.includeKeys();
940             query.end();
941             Results results = query.execute();
942             assertFalse(results.hasValues());
943             assertEquals(4, results.size());
944             for (Result result : results.all()) {
945                 try {
946                     result.getValue();
947                     fail();
948                 } catch (SearchException se) {
949                     // expected since keys not included
950                 }
951             }
952         }
953     }
954 
955     private void verify(Ehcache cache, Query query, Integer... expectedKeys) {
956         Results results = query.execute();
957         assertEquals(expectedKeys.length, results.size());
958         assertTrue(results.hasKeys());
959         assertFalse(results.hasAttributes());
960 
961         Set<Integer> keys = new HashSet<Integer>(Arrays.asList(expectedKeys));
962 
963         System.err.println(results.toString()); // call toString() just to make sure it doesn't blow up
964 
965         for (Result result : results.all()) {
966             System.err.println(result.toString()); // call toString() just to make sure it doesn't blow up
967 
968             int key = (Integer) result.getKey();
969             if (!keys.remove(key)) {
970                 throw new AssertionError("unexpected key: " + key);
971             }
972         }
973     }
974 
975     private void verifyOrdered(Ehcache cache, Query query, Integer... expectedKeys) {
976         Results results = query.execute();
977         assertEquals(results.size(), expectedKeys.length);
978 
979         int pos = 0;
980         for (Result result : results.all()) {
981             Object expectedKey = expectedKeys[pos++];
982             assertEquals(expectedKey, result.getKey());
983         }
984     }
985 
986 }