View Javadoc

1   package net.sf.ehcache.search;
2   
3   import static net.sf.ehcache.search.Query.KEY;
4   import static org.junit.Assert.assertEquals;
5   
6   import java.util.Arrays;
7   import java.util.List;
8   import java.util.Map;
9   
10  import net.sf.ehcache.CacheManager;
11  import net.sf.ehcache.Ehcache;
12  import net.sf.ehcache.Element;
13  import net.sf.ehcache.config.SearchAttribute;
14  
15  import org.junit.After;
16  import org.junit.Assert;
17  import org.junit.Before;
18  import org.junit.Test;
19  import org.slf4j.Logger;
20  import org.slf4j.LoggerFactory;
21  
22  import bsh.EvalError;
23  import bsh.Interpreter;
24  
25  /***
26   * This class was used to develop the API and now that the code has been written it has been made an
27   * executable test.
28   *
29   * @author teck
30   * @author Greg Luck
31   */
32  public class QueryExamplesTest {
33  
34      private static final Logger LOG = LoggerFactory.getLogger(QueryExamplesTest.class);
35  
36      private CacheManager cacheManager;
37      private Ehcache cache;
38  
39      @Before
40      public void before() {
41          cacheManager = new CacheManager(getClass().getResource("/ehcache-search.xml"));
42          cache = cacheManager.getCache("cache1");
43          SearchTestUtil.populateData(cache);
44      }
45  
46      @After
47      public void after() {
48          cacheManager.shutdown();
49      }
50  
51      @Test
52      public void testExamples() {
53          examples();
54      }
55  
56      void examples() throws SearchException {
57  
58          Attribute<Integer> age = cache.getSearchAttribute("age");
59          Attribute<String> gender = cache.getSearchAttribute("gender");
60          Attribute<String> name = cache.getSearchAttribute("name");
61  
62          Query query;
63          Results results;
64  
65          // include all keys in the cache
66          query = cache.createQuery().includeKeys().end();
67          results = query.execute();
68          for (Result result : results.all()) {
69              LOG.info("" + result.getKey());
70          }
71          results.discard(); // not required but will speed resource freeing
72  
73          // access results in a "paged" manner
74          query = cache.createQuery().includeKeys().end();
75          results = query.execute();
76  
77          int pageSize = 100;
78          int index = 0;
79          List<Result> page;
80          do {
81              page = results.range(index, pageSize);
82  
83              for (Result result : page) {
84                  LOG.info("" + result.getKey());
85              }
86  
87              index += page.size();
88          } while (page.size() == pageSize);
89  
90          // select age from the cache
91          query = cache.createQuery().includeAttribute(age).end();
92          results = query.execute();
93          for (Result result : results.all()) {
94              LOG.info("" + result.getAttribute(age));
95          }
96  
97          // select age, gender from the cache
98          query = cache.createQuery().includeAttribute(age, gender).end();
99          results = query.execute();
100         for (Result result : results.all()) {
101             LOG.info("" + result.getAttribute(age));
102             // slf4j weirdness
103             Object object = result.getAttribute(gender);
104             LOG.info("" + object);
105         }
106 
107         // select max(age) -- named indexed attribute "age"
108         Query sumQuery = cache.createQuery().includeAggregator(age.sum()).end();
109         results = sumQuery.execute();
110         for (Result result : results.all()) {
111             Long sumResult = (Long) result.getAggregatorResults().get(0);
112             LOG.info("Sum is: " + sumResult);
113         }
114 
115         // select keys with criteria age == 12 AND gender = "timmy"
116         query = cache.createQuery().includeKeys().addCriteria(age.eq(12).and(gender.eq("timmy"))).end();
117 
118         // same as above (but without AND, uses two add() -- multiple
119         // criteria implies AND)
120         query = cache.createQuery().includeKeys().addCriteria(age.eq(12)).addCriteria(gender.eq("timmy")).end();
121 
122         // slightly more complicated expression and multiple ordering
123         // age = 13 OR (age == 12 AND gender = "timmy") order by age asc, gender desc limit 10
124         query = cache.createQuery().includeKeys().addCriteria(age.eq(13).or(age.eq(12).and(gender.eq("timmy"))))
125                 .addOrderBy(age, Direction.ASCENDING).addOrderBy(gender, Direction.DESCENDING).maxResults(10).end();
126     }
127 
128     @Test
129     public void testNoIncludeSpecified() {
130         Attribute<Integer> age = cache.getSearchAttribute("age");
131         Query query = cache.createQuery().addCriteria(age.eq(35));
132         try {
133             query.execute();
134             Assert.fail();
135         } catch (SearchException e) {
136             System.err.println("Expected " + e.toString());
137         }
138     }
139 
140     @Test
141     public void testUseShorthandKeyAttribute() {
142         Results results = cache.createQuery().addCriteria(KEY.eq(1)).includeKeys().execute();
143         assertEquals(1, results.size());
144         assertEquals(1, results.all().iterator().next().getKey());
145     }
146 
147     @Test
148     public void testUseShorthandValueAttribute() {
149         Object tmpKey = new Object();
150         Double value = Math.PI * System.nanoTime();
151         cache.put(new Element(tmpKey, value));
152 
153         try {
154             Results results = cache.createQuery().addCriteria(Query.VALUE.eq(value)).includeKeys().execute();
155             assertEquals(1, results.size());
156             assertEquals(tmpKey, results.all().iterator().next().getKey());
157         } finally {
158             cache.remove(tmpKey);
159         }
160     }
161 
162     @Test
163     public void testIncludeKeysSpecified() {
164         Attribute<Integer> age = cache.getSearchAttribute("age");
165         Results results = cache.createQuery().addCriteria(age.eq(35)).includeKeys().execute();
166         assertEquals(2, results.size());
167         for (Result result : results.all()) {
168             LOG.info("" + cache.get(result.getKey()));
169         }
170     }
171 
172     @Test
173     public void testSearchKeys() {
174         Results results = cache.createQuery().addCriteria(Query.KEY.in(Arrays.asList(1, 3))).includeKeys().execute();
175         assertEquals(2, results.size());
176         for (Result result : results.all()) {
177             LOG.info("" + cache.get(result.getKey()));
178         }
179     }
180 
181     /***
182      * Show how to execute a query in beanshell
183      */
184     @Test
185     public void testBasicBeanShellQuery() throws EvalError {
186 
187         Interpreter i = new Interpreter();
188         Query query = cache.createQuery().includeKeys();
189 
190         Attribute<Integer> age = cache.getSearchAttribute("age");
191 
192         i.set("query", query);
193         Results results = null;
194         i.set("results", results);
195         i.set("age", age);
196 
197         i.eval("results = query.addCriteria(age.eq(35)).execute()");
198         results = (Results) i.get("results");
199         assertEquals(2, results.size());
200         for (Result result : results.all()) {
201             LOG.info("" + result.getKey());
202         }
203     }
204 
205     /***
206      * Show how to execute a query in beanshell
207      */
208     @Test
209     public void testInjectedStringBeanShellQuery() throws EvalError {
210 
211         Interpreter i = new Interpreter();
212         Query query = cache.createQuery().includeKeys();
213 
214         Attribute<Integer> age = cache.getSearchAttribute("age");
215 
216         i.set("query", query);
217         Results results = null;
218         i.set("results", results);
219         i.set("age", age);
220 
221         String userDefinedQuery = "age.eq(35)";
222         String fullQueryString = "results = query.addCriteria(" + userDefinedQuery + ").execute()";
223 
224         i.eval(fullQueryString);
225         results = (Results) i.get("results");
226         assertEquals(2, results.size());
227         for (Result result : results.all()) {
228             LOG.info("" + result.getKey());
229         }
230     }
231 
232     /***
233      * Show how to execute a query in beanshell using autodiscovered attributes
234      */
235     @Test
236     public void testAutoDiscoveredAttributesBeanShellQuery() throws EvalError {
237 
238         Interpreter i = new Interpreter();
239 
240         // Auto discover the search attributes and add them to the interpreter's context
241         Map<String, SearchAttribute> attributes = cache.getCacheConfiguration().getSearchAttributes();
242         for (Map.Entry<String, SearchAttribute> entry : attributes.entrySet()) {
243             i.set(entry.getKey(), cache.getSearchAttribute(entry.getKey()));
244             LOG.info("Setting attribute " + entry.getKey());
245         }
246 
247         // Define the query and results. Add things which would be set in the GUI i.e. includeKeys and add to context
248         Query query = cache.createQuery().includeKeys();
249         Results results = null;
250         i.set("query", query);
251         i.set("results", results);
252 
253         // This comes from the freeform text field
254         String userDefinedQuery = "age.eq(35)";
255 
256         // Add the stuff on that we need
257         String fullQueryString = "results = query.addCriteria(" + userDefinedQuery + ").execute()";
258 
259         i.eval(fullQueryString);
260         results = (Results) i.get("results");
261         assertEquals(2, results.size());
262         for (Result result : results.all()) {
263             LOG.info("" + result.getKey());
264         }
265 
266     }
267 
268 }