1   /**
2    * This file is part of the equanda project.
3    *
4    * The contents of this file are subject to the Mozilla Public License Version 1.1 (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 http://www.mozilla.org/MPL/
7    *
8    * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
9    * ANY KIND, either express or implied. See the License for the specific language governing rights and
10   * limitations under the License.
11   *
12   * Alternatively, the contents of this file may be used under the terms of
13   * either the GNU General Public License Version 2 or later (the "GPL"), or
14   * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
15   * in which case the provisions of the GPL or the LGPL are applicable instead
16   * of those above. If you wish to allow use of your version of this file only
17   * under the terms of either the GPL or the LGPL, and not to allow others to
18   * use your version of this file under the terms of the MPL, indicate your
19   * decision by deleting the provisions above and replace them with the notice
20   * and other provisions required by the GPL or the LGPL. If you do not delete
21   * the provisions above, a recipient may use your version of this file under
22   * the terms of any one of the MPL, the GPL or the LGPL.
23   */
24  
25  package org.equanda.test.xejb;
26  
27  import org.equanda.persistence.EquandaPersistenceException;
28  import org.equanda.persistence.query.EquandaQuery;
29  import org.equanda.persistence.query.EquandaQueryImpl;
30  import org.equanda.test.dm.client.*;
31  import org.equanda.test.dm.client.type.*;
32  import org.equanda.test.dm.client.constants.*;
33  
34  import java.sql.Timestamp;
35  import java.util.*;
36  
37  /**
38   * JUnit test for select and selections
39   *
40   * @author <a href="mailto:joachim@progs.be">Joachim Van der Auwera</a>
41   */
42  public class EquandaQueryTest
43      extends TestAdapter
44  {
45      private VehicleSelectorEJB selector;
46  
47      public void setUp()
48          throws Exception
49      {
50          super.setUp();
51          if ( selector == null ) selector = EquandaGlobal.getVehicleSelector();
52      }
53  
54      protected void tearDown()
55          throws Exception
56      {
57          super.tearDown();
58          selector.remove();
59      }
60  
61      /*
62       * test for records of specific type (or child thereof)
63       */
64      public void testCustomQuerySelection()
65          throws Exception
66      {
67          Vehicle val1 = new Vehicle(), val2 = new Vehicle(), val3 = new Vehicle();
68          try
69          {
70              val1.setName( "1Simple Vehicle" );
71              val1.setColourCode( 55 );
72              val1.setSpeed( 100 );
73              val1.setEquandaType( VehicleConstants.TYPE_Vehicle );
74              val1.equandaUpdate();
75  
76              val2.setName( "2Correct Vehicle" );
77              val2.setColourCode( 55 );
78              val2.setSpeed( 200 );
79              val2.setEquandaType( VehicleConstants.TYPE_VehicleWithWheels );
80              val2.equandaUpdate();
81  
82              val3.setName( "3Correct Airplane" );
83              val3.setColourCode( 55 );
84              val3.setSpeed( 300 );
85              val3.setEquandaType( VehicleConstants.TYPE_Airplane );
86              val3.equandaUpdate();
87  
88              // build selector
89              EquandaQuery query = new EquandaQueryImpl(
90                  "SELECT o FROM DMVehicleBean o WHERE  ( o.colourCode = :colourCode ) ORDER BY o.name" );
91              query.setParameter( "colourCode", 55 );
92              // check type filter
93              assertEquals( 3, selector.selectEquanda( query ).size() );
94              query.setTypeFilter( new VehicleType() );
95              assertEquals( 3, selector.selectEquanda( query ).size() );
96              query.setTypeFilter( new VehicleWithWheelsType() );
97              assertEquals( 2, selector.selectEquanda( query ).size() );
98  
99              // check limit
100             query.setTypeFilter( null );  // no filter
101             query.setMaxResults( 2 );
102             assertEquals( "", 2, selector.selectEquanda( query ).size() );
103 
104             // check set position
105             query.setMaxResults( -1 );  // no limit
106             query.setFirstResult( 2 );
107             Collection<Vehicle> coll = selector.selectEquanda( query );
108             assertEquals( 1, coll.size() );
109             assertEquals( "3Correct Airplane", coll.iterator().next().getName() );
110 
111             // check single selects
112             query.setMaxResults( -1 );  // no limit
113             query.setFirstResult( 2 );
114             assertEquals( "", "3Correct Airplane", selector.selectEquandaSingle( query ).getName() );
115             query.setParameter( "colourCode", 54 );
116             assertNull( "", selector.selectEquandaSingle( query ) );
117 
118             // check named queries
119             query = EquandaGlobal.getQuery( "Vehicle.Speed" );
120 
121             // test selectEquanda
122             query.setParameter( "speed", 100 );
123             query.setTypeFilter( new VehicleWithWheelsType() );
124             assertNull( selector.selectEquandaSingle( query ) );
125             query.setParameter( "speed", 200 );
126             assertEquals( 1, selector.selectEquanda( query ).size() );
127             query.setParameter( "speed", 300 );
128             assertEquals( 1, selector.selectEquanda( query ).size() );
129         }
130         finally
131         {
132             // clean up
133             if ( val1 != null && val1.getId() != null ) selector.removeEntityBean( val1.getId() );
134             if ( val2 != null && val2.getId() != null ) selector.removeEntityBean( val2.getId() );
135             if ( val3 != null && val3.getId() != null ) selector.removeEntityBean( val3.getId() );
136         }
137     }
138 
139     public void testLazyFetching()
140         throws Exception
141     {
142         Vehicle val1 = new Vehicle(), val2 = new Vehicle(), val3 = new Vehicle();
143         Vehicle val4 = new Vehicle(), val5 = new Vehicle(), val6 = new Vehicle();
144         try
145         {
146             val1.setName( "1Simple Vehicle" );
147             val1.setColourCode( 56 );
148             val1.setSpeed( 100 );
149             val1.setEquandaType( VehicleConstants.TYPE_Vehicle );
150             val1.equandaUpdate();
151             val2.setName( "2Correct Vehicle" );
152             val2.setColourCode( 56 );
153             val2.setSpeed( 200 );
154             val2.setEquandaType( VehicleConstants.TYPE_VehicleWithWheels );
155             val2.equandaUpdate();
156             val3.setName( "3Correct Airplane" );
157             val3.setColourCode( 56 );
158             val3.setSpeed( 300 );
159             val3.setEquandaType( VehicleConstants.TYPE_Airplane );
160             val3.equandaUpdate();
161             val4.setName( "4Airplane" );
162             val4.setColourCode( 56 );
163             val4.setSpeed( 300 );
164             val4.setEquandaType( VehicleConstants.TYPE_Airplane );
165             val4.equandaUpdate();
166             val5.setName( "5Airplane" );
167             val5.setColourCode( 56 );
168             val5.setSpeed( 300 );
169             val5.setEquandaType( VehicleConstants.TYPE_Airplane );
170             val5.equandaUpdate();
171             val6.setName( "6Airplane" );
172             val6.setColourCode( 56 );
173             val6.setSpeed( 300 );
174             val6.setEquandaType( VehicleConstants.TYPE_Airplane );
175             val6.equandaUpdate();
176 
177             // build selector
178             EquandaQueryImpl query = new EquandaQueryImpl(
179                 "SELECT o FROM DMVehicleBean o WHERE  ( o.colourCode = :colourCode ) ORDER BY o.name",
180                 "SELECT COUNT(o) FROM DMVehicleBean o WHERE  ( o.colourCode = :colourCode ) ORDER BY o.name" );
181             query.setParameter( "colourCode", 56 );
182 
183             // check collection size
184             List<Vehicle> coll = selector.selectEquanda( query );
185             assertEquals( 6, coll.size() );
186 
187             // test lazyCollection with filter
188             query.setTypeFilter( new AirplaneType() );
189             coll = selector.selectEquanda( query );
190             assertEquals( 4, coll.size() );
191             assertEquals( "3Correct Airplane", coll.get( 0 ).getName() );
192             assertEquals( "4Airplane", coll.get( 1 ).getName() );
193             assertEquals( "5Airplane", coll.get( 2 ).getName() );
194             assertEquals( "6Airplane", coll.get( 3 ).getName() );
195 
196             // test with results limit
197             query.setFirstResult( 2 );
198             query.setMaxResults( 2 );
199             coll = selector.selectEquanda( query );
200             assertEquals( 2, coll.size() );
201             assertEquals( "5Airplane", coll.get( 0 ).getName() );
202             assertEquals( "6Airplane", coll.get( 1 ).getName() );
203 
204             // test without count query
205             query = new EquandaQueryImpl(
206                 "SELECT o FROM DMVehicleBean o WHERE ( o.colourCode = :colourCode AND o.name = :name ) ORDER BY o.name" );
207             query.setParameter( "colourCode", 56 );
208             query.setParameter( "name", "3Correct Airplane" );
209             coll = selector.selectEquanda( query );
210             assertEquals( 1, coll.size() );
211             assertEquals( "3Correct Airplane", coll.get( 0 ).getName() );
212         }
213         finally
214         {
215             // clean up
216             if ( val1 != null && val1.getId() != null ) selector.removeEntityBean( val1.getId() );
217             if ( val2 != null && val2.getId() != null ) selector.removeEntityBean( val2.getId() );
218             if ( val3 != null && val3.getId() != null ) selector.removeEntityBean( val3.getId() );
219             if ( val4 != null && val4.getId() != null ) selector.removeEntityBean( val4.getId() );
220             if ( val5 != null && val5.getId() != null ) selector.removeEntityBean( val5.getId() );
221             if ( val6 != null && val6.getId() != null ) selector.removeEntityBean( val6.getId() );
222         }
223     }
224 
225     public void testLazyIterator()
226         throws Exception
227     {
228         System.out.println( "Supposed to work with lazylist-cache-capacity=5" );
229         Vehicle val1 = new Vehicle(), val2 = new Vehicle(), val3 = new Vehicle();
230         Vehicle val4 = new Vehicle(), val5 = new Vehicle(), val6 = new Vehicle();
231         try
232         {
233             val1.setName( "Vehicle1" );
234             val1.setColourCode( 1 );
235             val1.setSpeed( 100 );
236             val1.setEquandaType( VehicleConstants.TYPE_Vehicle );
237             val1.equandaUpdate();
238             val2.setName( "Vehicle2" );
239             val2.setColourCode( 1 );
240             val2.setSpeed( 100 );
241             val2.setEquandaType( VehicleConstants.TYPE_VehicleWithWheels );
242             val2.equandaUpdate();
243             val3.setName( "Vehicle3" );
244             val3.setColourCode( 1 );
245             val3.setSpeed( 100 );
246             val3.setEquandaType( VehicleConstants.TYPE_Airplane );
247             val3.equandaUpdate();
248             val4.setName( "Vehicle4" );
249             val4.setColourCode( 1 );
250             val4.setSpeed( 100 );
251             val4.setEquandaType( VehicleConstants.TYPE_Airplane );
252             val4.equandaUpdate();
253             val5.setName( "Vehicle5" );
254             val5.setColourCode( 1 );
255             val5.setSpeed( 100 );
256             val5.setEquandaType( VehicleConstants.TYPE_Airplane );
257             val5.equandaUpdate();
258             val6.setName( "Vehicle6" );
259             val6.setColourCode( 1 );
260             val6.setSpeed( 100 );
261             val6.setEquandaType( VehicleConstants.TYPE_Airplane );
262             val6.equandaUpdate();
263 
264             // check lazy collection iteration without modification of results
265             EquandaQueryImpl query = new EquandaQueryImpl( "SELECT o FROM DMVehicleBean o WHERE o.colourCode = 1" );
266             List<VehicleEJB> coll = selector.selectEquandaEJB( query );
267             assertEquals( 6, coll.size() );
268 
269             // check collection when results are altered
270             int count = 0;
271             try
272             {
273                 for ( VehicleEJB veh : selector.selectEquandaEJB( query ) )
274                 {
275                     veh.setColourCode( 5 );
276                     count++;
277                 }
278                 fail( "Lazy collection should be modified " + count );
279             }
280             catch ( ConcurrentModificationException cme )
281             {
282                 assertEquals( count, 5 );
283             }
284 
285             query = new EquandaQueryImpl( "SELECT o FROM DMVehicleBean o WHERE o.speed = 100" );
286             try
287             {
288                 coll = selector.selectEquandaEJB( query );
289                 for ( VehicleEJB aColl : coll ) aColl.setSpeed( 110 );
290                 fail( "Lazy collection should be modified" );
291             }
292             catch ( ConcurrentModificationException cme ) {}
293         }
294         finally
295         {
296             if ( val1 != null && val1.getId() != null ) selector.removeEntityBean( val1.getId() );
297             if ( val2 != null && val2.getId() != null ) selector.removeEntityBean( val2.getId() );
298             if ( val3 != null && val3.getId() != null ) selector.removeEntityBean( val3.getId() );
299             if ( val4 != null && val4.getId() != null ) selector.removeEntityBean( val4.getId() );
300             if ( val5 != null && val5.getId() != null ) selector.removeEntityBean( val5.getId() );
301             if ( val6 != null && val6.getId() != null ) selector.removeEntityBean( val6.getId() );
302         }
303     }
304 
305     public void testUpdateQueryBrand()
306         throws Exception
307     {
308         CarSelectorEJB csel = EquandaGlobal.getCarSelector();
309         for ( Car car : csel.selectEquandaAll() )
310         {
311             car.removeEntityBean();
312         }
313         csel.remove();
314         // Create two records with some time in between
315         Car car1 = Car.equandaCreate();
316         car1.setBrand( "UpdateQueryA" );
317         car1.equandaUpdate();
318         Car car2 = Car.equandaCreate();
319         car2.setBrand( "UpdateQueryB" );
320         car2.equandaUpdate();
321 
322         // delete old records (shoulld keep car2
323         EquandaQueryImpl query = new EquandaQueryImpl( "delete from DMCarBean o where o.brand <= :brand" );
324         Map<String, Object> parameters = new HashMap<String, Object>();
325         parameters.put( "brand", car1.getBrand() );
326         query.setParameters( parameters );
327         CarSelectorEJB sel = EquandaGlobal.getCarSelector();
328         sel.equandaRunUpdateQuery( query );
329 
330         // verify that car1 is deleted and car2 is still available
331         Car check;
332         check = sel.selectId( car2.getId() );
333         assertNotNull( check );
334         assertEquals( car2.getBrand(), check.getBrand() );
335 
336         // verify that car1 is deleted
337         try
338         {
339             sel.selectId( car1.getId() );
340             fail( "car1 should have been deleted" );
341         }
342         catch ( EquandaPersistenceException upe ) {}
343 
344         car2.removeEntityBean();
345 
346         sel.remove();
347     }
348 
349     public void testUpdateQueryTime()
350         throws Exception
351     {
352         // Create two records with some time in between
353         Car car1 = Car.equandaCreate();
354         car1.setBrand( "UpdateQueryX" );
355         car1.equandaUpdate();
356         try { Thread.sleep( 2000 ); } catch ( InterruptedException ie ) {}
357         Timestamp threshold = new Timestamp( System.currentTimeMillis() );
358         try { Thread.sleep( 2000 ); } catch ( InterruptedException ie ) {}
359         Car car2 = Car.equandaCreate();
360         car2.setBrand( "UpdateQueryY" );
361         car2.equandaUpdate();
362 
363         // delete old records (shoulld keep car2
364         EquandaQueryImpl query =
365             new EquandaQueryImpl( "delete from DMCarBean o where o.equandaModificationDate <= :time" );
366         Map<String, Object> parameters = new HashMap<String, Object>();
367         parameters.put( "time", threshold );
368         query.setParameters( parameters );
369         CarSelectorEJB sel = EquandaGlobal.getCarSelector();
370         sel.equandaRunUpdateQuery( query );
371 
372         // verify that car1 is deleted and car2 is still available
373         Car check;
374         check = sel.selectId( car2.getId() );
375         assertNotNull( check );
376         assertEquals( car2.getBrand(), check.getBrand() );
377 
378         // verify that car1 is deleted
379         try
380         {
381             sel.selectId( car1.getId() );
382             fail( "car1 should have been deleted" );
383         }
384         catch ( EquandaPersistenceException upe ) {}
385 
386         car2.removeEntityBean();
387 
388         sel.remove();
389     }
390 }