1   /*
2    * Copyright (c) 2004-2005, University Health Network.  All rights reserved. Distributed under the BSD 
3    * license (see http://opensource.org/licenses/bsd-license.php).
4    *  
5    * HibernateQueryResultStoreTest.java
6    *
7    * Created on 16-Dec-2004 at 2:52:55 PM
8    */
9   package ca.uhn.cache.internal.impl;
10  
11  import java.text.MessageFormat;
12  import java.util.Date;
13  
14  import junit.framework.Test;
15  import junit.framework.TestSuite;
16  import junitx.util.PrivateAccessor;
17  
18  import org.jmock.Mock;
19  import org.jmock.MockObjectTestCase;
20  import org.springframework.context.support.ClassPathXmlApplicationContext;
21  
22  import ca.uhn.cache.IDimension;
23  import ca.uhn.cache.IParamSpace;
24  import ca.uhn.cache.IQuery;
25  import ca.uhn.cache.IQueryResult;
26  import ca.uhn.cache.VolatilityEnum;
27  import ca.uhn.cache.impl.DataItem;
28  import ca.uhn.cache.impl.DateParam;
29  import ca.uhn.cache.impl.DateRangeParam;
30  import ca.uhn.cache.impl.Dimension;
31  import ca.uhn.cache.impl.Query;
32  import ca.uhn.cache.impl.QueryResult;
33  import ca.uhn.cache.impl.StringParam;
34  import ca.uhn.cache.impl.StringSetParam;
35  import ca.uhn.cache.internal.exception.QueryResultStoreException;
36   import ca.uhn.cache.internal.hibernate.impl.DateParamField;
37  import ca.uhn.cache.internal.hibernate.impl.Field;
38  import ca.uhn.cache.internal.hibernate.impl.StringParamField;
39  import ca.uhn.cache.internal.util.UTC;
40  import ca.uhn.cache.util.SpringTestCaseUtils;
41  
42  
43  /***
44   * TODO complete javadoc for 
45   * 
46   * @author <a href="mailto:alexei.guevara@uhn.on.ca">Alexei Guevara</a>
47   * @version $Revision: 1.1 $ updated on $Date: 2005/01/24 22:52:21 $ by $Author: bryan_tripp $
48   */
49  public class HibernateQueryResultStoreIntegrationTest extends MockObjectTestCase {
50      
51      private static final String QUERY_RESULT_STORE_BEAN = "myQueryResultStore";
52      
53      private IDimension myStringParamDim1;
54      private IDimension myStringParamDim2;
55      private IDimension myDateParamDim;
56      
57      private HibernateQueryResultStore myHibernateQueryResultStore;
58      
59      private Mock myParamSpaceMock;
60      private IParamSpace myParamSpace;
61      
62      /***
63       * @return The Test Suite.
64       */
65      public static final Test suite() {
66          TestSuite retVal = new TestSuite( HibernateQueryResultStoreIntegrationTest.class );
67          
68  //        TestSuite retVal = new TestSuite();
69  //        retVal.addTest( new HibernateQueryResultStoreIntegrationTest( "testInsert5" ) );
70          
71          return retVal;
72      }
73      
74      /***
75       * @param theName ...
76       */
77      public HibernateQueryResultStoreIntegrationTest( String theName ) {
78          super( theName );
79      }
80      
81      /*
82       * @see TestCase#setUp()
83       */
84      protected void setUp() throws Exception {
85          super.setUp();
86          
87          myStringParamDim1 = 
88              new Dimension( "stringDimension1", new Class[] { StringParam.class, StringSetParam.class } );
89          
90          myStringParamDim2 = 
91              new Dimension( "stringDimension2", new Class[] { StringParam.class, StringSetParam.class } );
92          
93          myDateParamDim = 
94              new Dimension( "dateDimension", new Class[] { DateParam.class, DateRangeParam.class } );
95  
96          myParamSpaceMock = mock( IParamSpace.class, "myParamSpaceMock" );
97          myParamSpace = (IParamSpace) myParamSpaceMock.proxy();
98          
99          myParamSpaceMock.expects( once() )
100             .method("getDimensions")
101             .withNoArguments()
102             .will( returnValue( new IDimension[] { myStringParamDim1, myStringParamDim2, myDateParamDim } ) );
103 
104         ClassPathXmlApplicationContext appContext = 
105             new ClassPathXmlApplicationContext( 
106                     SpringTestCaseUtils.packageToPath( HibernateChunkStoreTest.class.getPackage() ) +
107                     "/hibernate-chunk-store.xml");
108         
109         myHibernateQueryResultStore = (HibernateQueryResultStore) appContext.getBean( QUERY_RESULT_STORE_BEAN );
110         
111         myHibernateQueryResultStore.setParamSpace( myParamSpace );
112         
113     }
114 
115     /*
116      * @see TestCase#tearDown()
117      */
118     protected void tearDown() throws Exception {
119         super.tearDown();
120     }
121 
122     /***
123      * @throws Throwable ...
124      */
125     public void testGenerateHql1_1() throws Throwable {
126         Query query = new Query();
127         query.addParameter( new StringParam( myStringParamDim1, "a" ) );
128         
129         String expectedHql = 
130             MessageFormat.format( 
131                     "SELECT f.record " +
132                     "FROM {0} f, {1} f1 " +
133                     "WHERE ( f.record = f1.record " +
134                       "AND f1.dimensionName = :f1dimensionName " +
135                       "AND f1.value = :f1value )",
136                     new Object[] { Field.class.getName(), StringParamField.class.getName() } );
137         
138         String actualHql = (String) PrivateAccessor.invoke( 
139                 myHibernateQueryResultStore, 
140                 "generateSelectHql", 
141                 new Class[] { IQuery.class}, 
142                 new Object[] { query } );
143         
144         assertEquals( expectedHql, actualHql );
145     }
146     
147     /***
148      * @throws Throwable ...
149      */
150     public void testGenerateHql1_2() throws Throwable {
151         Query query = new Query();
152         query.addParameter( new StringSetParam( myStringParamDim1, new String[] { "a", "b", "c" }  ) );
153         
154         String expectedHql = 
155             MessageFormat.format( 
156                     "SELECT f.record " +
157                     "FROM {0} f, {1} f1 " +
158                     "WHERE ( f.record = f1.record " +
159                       "AND f1.dimensionName = :f1dimensionName " +
160                       "AND f1.value IN ( :f1value1, :f1value2, :f1value3 ) )",
161                     new Object[] { Field.class.getName(), StringParamField.class.getName() } );
162         
163         String actualHql = (String) PrivateAccessor.invoke( 
164                 myHibernateQueryResultStore, 
165                 "generateSelectHql", 
166                 new Class[] { IQuery.class}, 
167                 new Object[] { query } );
168         
169         assertEquals( expectedHql, actualHql );
170     }
171     
172     
173     /***
174      * @throws Throwable ...
175      */
176     public void testGenerateHql2_1() throws Throwable {
177         Query query = new Query();
178         query.addParameter( new DateRangeParam( myDateParamDim, new Date(), new Date() ) );
179         
180         String expectedHql = 
181             MessageFormat.format( 
182                     "SELECT f.record " +
183                     "FROM {0} f, {1} f1 " +
184                     "WHERE ( f.record = f1.record " +
185                       "AND f1.dimensionName = :f1dimensionName " +
186                       "AND f1.value >= :f1start " +
187                       "AND f1.value <= :f1end )",
188                     new Object[] { Field.class.getName(), DateParamField.class.getName() } );
189         
190         String actualHql = (String) PrivateAccessor.invoke( 
191                 myHibernateQueryResultStore, 
192                 "generateSelectHql", 
193                 new Class[] { IQuery.class}, 
194                 new Object[] { query } );
195         
196         assertEquals( expectedHql, actualHql );
197 
198     }
199     
200     /***
201      * @throws Throwable ...
202      */
203     public void testGenerateHql2_2() throws Throwable {
204         Query query = new Query();
205         query.addParameter( new DateParam( myDateParamDim, new Date() ) );
206         
207         String expectedHql = 
208             MessageFormat.format( 
209                     "SELECT f.record " +
210                     "FROM {0} f, {1} f1 " +
211                     "WHERE ( f.record = f1.record " +
212                       "AND f1.dimensionName = :f1dimensionName " +
213                       "AND f1.value = :f1value )",
214                     new Object[] { Field.class.getName(), DateParamField.class.getName() } );
215         
216         String actualHql = (String) PrivateAccessor.invoke( 
217                 myHibernateQueryResultStore, 
218                 "generateSelectHql", 
219                 new Class[] { IQuery.class}, 
220                 new Object[] { query } );
221         
222         assertEquals( expectedHql, actualHql );
223 
224     }
225     
226     
227     /***
228      * @throws Throwable ...
229      */
230     public void testGenerateHql3() throws Throwable {
231         Query query = new Query();
232         query.addParameter( new DateParam( myDateParamDim, new Date() ) );
233         query.addParameter( new StringParam( myStringParamDim1, "a" ) );        
234         
235         String expectedHql = 
236             MessageFormat.format( 
237                     "SELECT f.record " +
238                     "FROM {0} f, {1} f1, {2} f2 " +
239                     "WHERE ( f.record = f1.record " +
240                       "AND f1.dimensionName = :f1dimensionName " +
241                       "AND f1.value = :f1value ) " +
242                       "AND " + 
243                       "( f.record = f2.record " +
244                       "AND f2.dimensionName = :f2dimensionName " +
245                       "AND f2.value = :f2value )",
246                     new Object[] { 
247                             Field.class.getName(), 
248                             DateParamField.class.getName(),
249                             StringParamField.class.getName() } );
250         
251         String actualHql = (String) PrivateAccessor.invoke( 
252                 myHibernateQueryResultStore, 
253                 "generateSelectHql", 
254                 new Class[] { IQuery.class}, 
255                 new Object[] { query } );
256         
257         assertEquals( expectedHql, actualHql );
258     }
259     
260     /***
261      * - one record that maps to a query with one StringParam.
262      * @throws QueryResultStoreException ...
263      */
264     public void testInsert1() throws QueryResultStoreException {
265         Query diProj = new Query();
266         Date date = UTC.currentTime();
267         
268         diProj.addParameter( new StringParam( myStringParamDim1, "a" ) );
269         
270         DataItem dataItem = new DataItem( "id", "foo", diProj, VolatilityEnum.STABLE, date );
271         
272         IQueryResult expectedQueryResult = new QueryResult();
273         expectedQueryResult.add( dataItem );
274         
275         myHibernateQueryResultStore.insert( expectedQueryResult );
276         
277         IQueryResult actualQueryResult = myHibernateQueryResultStore.select(diProj);
278         
279         assertEquals( expectedQueryResult, actualQueryResult );
280     }
281     
282     /***
283      * - one record that maps to a query with one DateParam.
284      * @throws QueryResultStoreException ...
285      */
286     public void testInsert2() throws QueryResultStoreException {
287         Query diProj = new Query();
288         Date date = UTC.currentTime();
289         diProj.addParameter( new DateParam( myDateParamDim, UTC.currentTime() ) );
290         
291         DataItem dataItem = new DataItem( "id", "foo", diProj, VolatilityEnum.STABLE, date );
292         
293         IQueryResult expectedQueryResult = new QueryResult();
294         expectedQueryResult.add( dataItem );
295         
296         myHibernateQueryResultStore.insert( expectedQueryResult );
297         
298         IQueryResult actualQueryResult = myHibernateQueryResultStore.select(diProj);
299         
300         assertEquals( expectedQueryResult, actualQueryResult );
301     }
302     
303     /***
304      * - one record that maps to a query with one StringParam and one DateParam.
305      * @throws QueryResultStoreException ...
306      */
307     public void testInsert3() throws QueryResultStoreException {
308         Query diProj = new Query();
309         diProj.addParameter( new StringParam( myStringParamDim1, "a" ) );
310         diProj.addParameter( new DateParam( myDateParamDim, UTC.currentTime() ) );
311         Date date = UTC.currentTime();
312         DataItem dataItem = new DataItem( "id", "foo", diProj, VolatilityEnum.STABLE, date );
313         
314         IQueryResult expectedQueryResult = new QueryResult();
315         expectedQueryResult.add( dataItem );
316         
317         myHibernateQueryResultStore.insert( expectedQueryResult );
318         
319         IQueryResult actualQueryResult = myHibernateQueryResultStore.select(diProj);
320         
321         assertEquals( expectedQueryResult, actualQueryResult );
322     }
323     
324     /***
325      * - one record that maps to a query with one StringParam.
326      * - use a StringSetParam for query
327      * 
328      * @throws QueryResultStoreException ...
329      */
330     public void testInsert4() throws QueryResultStoreException {
331         Query diProj = new Query();
332         diProj.addParameter( new StringParam( myStringParamDim1, "b" ) );
333         
334         Date date = UTC.currentTime();
335         DataItem dataItem = new DataItem( "id", "foo", diProj, VolatilityEnum.STABLE, date );
336         
337         IQueryResult expectedQueryResult = new QueryResult();
338         expectedQueryResult.add( dataItem );
339         
340         myHibernateQueryResultStore.insert( expectedQueryResult );
341         
342         IQuery query = new Query();
343         query.addParameter( new StringSetParam( myStringParamDim1, new String[] { "a", "b", "c" } ) );
344         
345         IQueryResult actualQueryResult = myHibernateQueryResultStore.select( query );
346         
347         assertEquals( expectedQueryResult, actualQueryResult );
348     }
349     
350     /***
351      * - insert two data items that have the same id, make sure that the data item that is inserted
352      *   first is updated with the information of the second one.
353      *   
354      * @throws QueryResultStoreException ...
355      */
356     public void testInsert5() throws QueryResultStoreException {
357         Date date = UTC.currentTime();
358 
359         Query diProj1 = new Query();
360         diProj1.addParameter( new StringParam( myStringParamDim1, "one" ) );
361         diProj1.addParameter( new StringParam( myStringParamDim2, "same" ) );
362         
363         DataItem dataItem1 = new DataItem( "id", "foo", diProj1, VolatilityEnum.VOLATILE, date );
364         
365         IQueryResult queryResult1 = new QueryResult();
366         queryResult1.add( dataItem1 );
367         
368         Query diProj2 = new Query();
369         diProj2.addParameter( new StringParam( myStringParamDim1, "two" ) );
370         diProj2.addParameter( new StringParam( myStringParamDim2, "same" ) );
371         
372         DataItem dataItem2 = new DataItem( "id", "foo", diProj2, VolatilityEnum.STABLE, date );
373         
374         IQueryResult queryResult2 = new QueryResult();
375         queryResult2.add( dataItem2 );
376         
377         IQueryResult expectedQueryResult = queryResult2;
378         
379         myHibernateQueryResultStore.insert( queryResult1 );
380         myHibernateQueryResultStore.insert( queryResult2 );
381 
382         Query query = new Query();
383         query.addParameter( new StringParam( myStringParamDim2, "same" ) );
384         
385         IQueryResult actualQueryResult = myHibernateQueryResultStore.select(query);
386         
387         assertEquals( expectedQueryResult, actualQueryResult );
388     }
389     
390     /***
391      * - one record that maps to a query with one StringParam.
392      * @throws QueryResultStoreException ...
393      */
394     public void testDelete1() throws QueryResultStoreException {
395         Date date = UTC.currentTime();
396         Query diProj = new Query();
397         diProj.addParameter( new StringParam( myStringParamDim1, "a" ) );
398         
399         DataItem dataItem = new DataItem( "id", "foo", diProj, VolatilityEnum.STABLE, date );
400         
401         IQueryResult expectedQueryResult = new QueryResult();
402         expectedQueryResult.add( dataItem );
403         
404         myHibernateQueryResultStore.insert( expectedQueryResult );
405         
406         int count = myHibernateQueryResultStore.delete(diProj);
407         
408         assertEquals( 1, count );
409     }
410     
411 }