KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > db4o > test > nativequery > NQRegressionTestCase


1 /* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com
2
3 This file is part of the db4o open source object database.
4
5 db4o is free software; you can redistribute it and/or modify it under
6 the terms of version 2 of the GNU General Public License as published
7 by the Free Software Foundation and as clarified by db4objects' GPL
8 interpretation policy, available at
9 http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
10 Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
11 Suite 350, San Mateo, CA 94403, USA.
12
13 db4o is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */

21 package com.db4o.test.nativequery;
22
23 import java.lang.reflect.*;
24
25 import com.db4o.*;
26 import com.db4o.inside.query.*;
27 import com.db4o.nativequery.*;
28 import com.db4o.nativequery.expr.*;
29 import com.db4o.nativequery.main.*;
30 import com.db4o.query.*;
31 import com.db4o.test.*;
32 import com.db4o.test.nativequery.expr.*;
33
34 import db4ounit.*;
35 import db4ounit.TestSuite;
36 import db4ounit.extensions.*;
37 import db4ounit.extensions.fixtures.*;
38
39
40 public class NQRegressionTestCase extends AbstractDb4oTestCase {
41     private final static boolean RUN_LOADTIME=false;
42     
43     private static final String JavaDoc CSTR = "Cc";
44     private static final String JavaDoc BSTR = "Ba";
45     private static final String JavaDoc ASTR = "Aa";
46     public final static Integer JavaDoc INTWRAPPER=new Integer JavaDoc(1);
47     private final static Integer JavaDoc PRIVATE_INTWRAPPER=new Integer JavaDoc(1);
48     
49     private static abstract class Base {
50         int id;
51         Integer JavaDoc idWrap;
52         
53         public Base(int id) {
54             this.id=id;
55             idWrap=new Integer JavaDoc(id);
56         }
57
58         public int getId() {
59             return id;
60         }
61     }
62     
63     private static class Other extends Base {
64         public Other() {
65             super(1);
66         }
67     }
68     
69     private static class Data extends Base {
70         boolean bool;
71         float value;
72         String JavaDoc name;
73         Data prev;
74         int id2;
75         Boolean JavaDoc boolWrap;
76         
77         public Data(int id, boolean bool,float value, String JavaDoc name,Data prev, int id2) {
78             super(id);
79             this.bool=bool;
80             this.boolWrap=Boolean.valueOf(bool);
81             this.value=value;
82             this.name = name;
83             this.prev=prev;
84             this.id2=id2;
85         }
86
87         public float getValue() {
88             return value;
89         }
90
91         public String JavaDoc getName() {
92             return name;
93         }
94         
95         public boolean getBool() {
96             return bool;
97         }
98
99         public Data getPrev() {
100             return prev;
101         }
102     }
103
104     public static void main(String JavaDoc[] args) {
105         TestSuite suite=new Db4oTestSuiteBuilder(new Db4oSolo(),NQRegressionTestCase.class).build();
106         new TestRunner(suite).run();
107     }
108
109     public void store() {
110         Data a=new Data(1,false,1.1f,ASTR,null, 0);
111         Data b=new Data(2,false,1.1f,BSTR,a, Integer.MIN_VALUE);
112         Data c=new Data(3,true,2.2f,CSTR,b, Integer.MIN_VALUE);
113         Data cc=new Data(3,false,3.3f,CSTR,null, Integer.MIN_VALUE);
114         ObjectContainer db=db();
115         db.set(a);
116         db.set(b);
117         db.set(c);
118         db.set(cc);
119         db.set(new Other());
120     }
121     
122     private abstract static class ExpectingPredicate extends Predicate {
123         private String JavaDoc _name;
124         
125         public ExpectingPredicate(String JavaDoc name) {
126             _name=name;
127         }
128
129         public ExpectingPredicate(String JavaDoc name,Class JavaDoc extentType) {
130             super(extentType);
131             _name=name;
132         }
133
134         public abstract int expected();
135         
136         public String JavaDoc toString() {
137             return _name;
138         }
139     }
140     
141     private static ExpectingPredicate[] _PREDICATES={
142         // unconditional/untyped
143
new ExpectingPredicate("unconditional/untyped") {
144             public int expected() { return 5;}
145             public boolean match(Object JavaDoc candidate) {
146                 return true;
147             }
148         },
149         // unconditional
150
new ExpectingPredicate("unconditional: Base") {
151             public int expected() { return 5;}
152             public boolean match(Base candidate) {
153                 return true;
154             }
155         },
156         new ExpectingPredicate("unconditional: Data") {
157             public int expected() { return 4;}
158             public boolean match(Data candidate) {
159                 return true;
160             }
161         },
162 // new ExpectingPredicate() {
163
// public int expected() { return 0;}
164
// public boolean match(Data candidate) {
165
// return false;
166
// }
167
// },
168
// primitive equals
169
new ExpectingPredicate("bool") {
170             public int expected() { return 1;}
171             public boolean match(Data candidate) {
172                 return candidate.bool;
173             }
174         },
175         new ExpectingPredicate("!bool") {
176             public int expected() { return 3;}
177             public boolean match(Data candidate) {
178                 return !candidate.bool;
179             }
180         },
181         new ExpectingPredicate("id2==0") {
182             public int expected() { return 1;}
183             public boolean match(Data candidate) {
184                 return candidate.id2==0;
185             }
186         },
187         new ExpectingPredicate("id==1") {
188             public int expected() { return 1;}
189             public boolean match(Data candidate) {
190                 return candidate.id==1;
191             }
192         },
193         new ExpectingPredicate("id==3") {
194             public int expected() { return 2;}
195             public boolean match(Data candidate) {
196                 return candidate.id==3;
197             }
198         },
199         new ExpectingPredicate("value==1.1") {
200             public int expected() { return 2;}
201             public boolean match(Data candidate) {
202                 return candidate.value==1.1f;
203             }
204         },
205         new ExpectingPredicate("value==3.3") {
206             public int expected() { return 1;}
207             public boolean match(Data candidate) {
208                 return candidate.value==3.3f;
209             }
210         },
211         // string equals
212
new ExpectingPredicate("name.eq(ASTR)") {
213             public int expected() { return 1;}
214             public boolean match(Data candidate) {
215                 return candidate.name.equals(ASTR);
216             }
217         },
218         new ExpectingPredicate("name.eq(CSTR)") {
219             public int expected() { return 2;}
220             public boolean match(Data candidate) {
221                 return candidate.name.equals(CSTR);
222             }
223         },
224         // string specific comparisons
225
new ExpectingPredicate("name.contains('a')") {
226             public int expected() { return 2;}
227             public boolean match(Data candidate) {
228                 return candidate.name.contains("a");
229             }
230         },
231         new ExpectingPredicate("name.contains('A')") {
232             public int expected() { return 1;}
233             public boolean match(Data candidate) {
234                 return candidate.name.contains("A");
235             }
236         },
237         new ExpectingPredicate("name.contains('C')") {
238             public int expected() { return 2;}
239             public boolean match(Data candidate) {
240                 return candidate.name.contains("C");
241             }
242         },
243         new ExpectingPredicate("name.startsWith('C')") {
244             public int expected() { return 2;}
245             public boolean match(Data candidate) {
246                 return candidate.name.startsWith("C");
247             }
248         },
249         new ExpectingPredicate("name.startsWith('a')") {
250             public int expected() { return 0;}
251             public boolean match(Data candidate) {
252                 return candidate.name.startsWith("a");
253             }
254         },
255         new ExpectingPredicate("name.endsWith('A')") {
256             public int expected() { return 2;}
257             public boolean match(Data candidate) {
258                 return candidate.name.endsWith("a");
259             }
260         },
261         new ExpectingPredicate("name.endsWith('A')") {
262             public int expected() { return 0;}
263             public boolean match(Data candidate) {
264                 return candidate.name.endsWith("A");
265             }
266         },
267         new ExpectingPredicate("!(name.contains('A'))") {
268             public int expected() { return 3;}
269             public boolean match(Data candidate) {
270                 return !candidate.name.contains("A");
271             }
272         },
273         new ExpectingPredicate("!(name.startsWith('C'))") {
274             public int expected() { return 2;}
275             public boolean match(Data candidate) {
276                 return !candidate.name.startsWith("C");
277             }
278         },
279         // int field comparison
280
new ExpectingPredicate("id<2") {
281             public int expected() { return 1;}
282             public boolean match(Data candidate) {
283                 return candidate.id<2;
284             }
285         },
286         new ExpectingPredicate("id>2") {
287             public int expected() { return 2;}
288             public boolean match(Data candidate) {
289                 return candidate.id>2;
290             }
291         },
292         new ExpectingPredicate("id<=2") {
293             public int expected() { return 2;}
294             public boolean match(Data candidate) {
295                 return candidate.id<=2;
296             }
297         },
298         new ExpectingPredicate("id>=2") {
299             public int expected() { return 3;}
300             public boolean match(Data candidate) {
301                 return candidate.id>=2;
302             }
303         },
304         // float field comparison
305
new ExpectingPredicate("value>2.9") {
306             public int expected() { return 1;}
307             public boolean match(Data candidate) {
308                 return candidate.value>2.9f;
309             }
310         },
311         new ExpectingPredicate("1.5>=value") {
312             public int expected() { return 2;}
313             public boolean match(Data candidate) {
314                 return 1.5f >= candidate.value;
315             }
316         },
317         // mixed comparison (coercion)
318
new ExpectingPredicate("id==1.0") {
319             public int expected() { return 1;}
320             public boolean match(Data candidate) {
321                 return candidate.id==1.0f;
322             }
323         },
324         new ExpectingPredicate("id!=1.0") {
325             public int expected() { return 3;}
326             public boolean match(Data candidate) {
327                 return candidate.id!=1.0f;
328             }
329         },
330         new ExpectingPredicate("value!=1") {
331             public int expected() { return 4;}
332             public boolean match(Data candidate) {
333                 return candidate.value!=1;
334             }
335         },
336 // won't work: SODA coercion is broken for greater/smaller comparisons
337
// new ExpectingPredicate() {
338
// public int expected() { return 1;}
339
// public boolean match(Data candidate) {
340
// return candidate.value>2.9d;
341
// }
342
// },
343
// descend field
344
new ExpectingPredicate("getPrev().getId()>=1") {
345             public int expected() { return 2;}
346             public boolean match(Data candidate) {
347                 return candidate.getPrev()!=null&&candidate.getPrev().getId()>=1;
348             }
349         },
350         new ExpectingPredicate("BSTR.eq(getPrev().getName()") {
351             public int expected() { return 1;}
352             public boolean match(Data candidate) {
353                 return (candidate.getPrev()!=null)&&(BSTR.equals(candidate.getPrev().getName()));
354             }
355         },
356         new ExpectingPredicate("getPrev().getName().eq('')") {
357             public int expected() { return 0;}
358             public boolean match(Data candidate) {
359                 return candidate.getPrev()!=null&&candidate.getPrev().getName().equals("");
360             }
361         },
362         // getter comparisons
363
new ExpectingPredicate("getId()==2") {
364             public int expected() { return 1;}
365             public boolean match(Data candidate) {
366                 return candidate.getId()==2;
367             }
368         },
369         new ExpectingPredicate("getId()<2") {
370             public int expected() { return 1;}
371             public boolean match(Data candidate) {
372                 return candidate.getId()<2;
373             }
374         },
375         new ExpectingPredicate("getId()>2") {
376             public int expected() { return 2;}
377             public boolean match(Data candidate) {
378                 return candidate.getId()>2;
379             }
380         },
381         new ExpectingPredicate("getId()<=2") {
382             public int expected() { return 2;}
383             public boolean match(Data candidate) {
384                 return candidate.getId()<=2;
385             }
386         },
387         new ExpectingPredicate("getId()>=2") {
388             public int expected() { return 3;}
389             public boolean match(Data candidate) {
390                 return candidate.getId()>=2;
391             }
392         },
393         new ExpectingPredicate("getName().eq(CSTR)") {
394             public int expected() { return 2;}
395             public boolean match(Data candidate) {
396                 return candidate.getName().equals(CSTR);
397             }
398         },
399         // negation
400
new ExpectingPredicate("!(id==1)") {
401             public int expected() { return 3;}
402             public boolean match(Data candidate) {
403                 return !(candidate.id==1);
404             }
405         },
406         new ExpectingPredicate("!(getId()>2)") {
407             public int expected() { return 2;}
408             public boolean match(Data candidate) {
409                 return !(candidate.getId()>2);
410             }
411         },
412         new ExpectingPredicate("!getName().eq(CSTR)") {
413             public int expected() { return 2;}
414             public boolean match(Data candidate) {
415                 return !(candidate.getName().equals(CSTR));
416             }
417         },
418         // conjunction
419
new ExpectingPredicate("bool&&!getBool()") {
420             public int expected() { return 0;}
421             public boolean match(Data candidate) {
422                 return candidate.bool&&!candidate.getBool();
423             }
424         },
425         new ExpectingPredicate("id>1&&getName().eq(CSTR)") {
426             public int expected() { return 2;}
427             public boolean match(Data candidate) {
428                 return (candidate.id>1)&&candidate.getName().equals(CSTR);
429             }
430         },
431         new ExpectingPredicate("id>1&&getId()<=2") {
432             public int expected() { return 1;}
433             public boolean match(Data candidate) {
434                 return (candidate.id>1)&&(candidate.getId()<=2);
435             }
436         },
437         new ExpectingPredicate("id>1&&getId()<1") {
438             public int expected() { return 0;}
439             public boolean match(Data candidate) {
440                 return (candidate.id>1)&&(candidate.getId()<1);
441             }
442         },
443         // disjunction
444
new ExpectingPredicate("bool||getId()==1") {
445             public int expected() { return 2;}
446             public boolean match(Data candidate) {
447                 return candidate.bool||candidate.getId()==1;
448             }
449         },
450         new ExpectingPredicate("id==1||getName().eq(CSTR)") {
451             public int expected() { return 3;}
452             public boolean match(Data candidate) {
453                 return (candidate.id==1)||candidate.getName().equals(CSTR);
454             }
455         },
456         new ExpectingPredicate("id>1||getId()<=2") {
457             public int expected() { return 4;}
458             public boolean match(Data candidate) {
459                 return (candidate.id>1)||(candidate.getId()<=2);
460             }
461         },
462         new ExpectingPredicate("id<=1||getId()>=3") {
463             public int expected() { return 3;}
464             public boolean match(Data candidate) {
465                 return (candidate.id<=1)||(candidate.getId()>=3);
466             }
467         },
468         // nested boolean
469
new ExpectingPredicate("id>=1||getName().eq(CSTR)&&getId()<3") {
470             public int expected() { return 2;}
471             public boolean match(Data candidate) {
472                 return ((candidate.id>=1)||candidate.getName().equals(CSTR))&&candidate.getId()<3;
473             }
474         },
475         new ExpectingPredicate("(id==2||getId()<=1)&&!(getName().eq(BSTR))") {
476             public int expected() { return 1;}
477             public boolean match(Data candidate) {
478                 return ((candidate.id==2)||candidate.getId()<=1)&&!candidate.getName().equals(BSTR);
479             }
480         },
481         // predicate member comparison
482
new ExpectingPredicate("id>=P.id") {
483             private int id=2;
484             
485             public int expected() { return 3;}
486             public boolean match(Data candidate) {
487                 return candidate.id>=id;
488             }
489         },
490         new ExpectingPredicate("getName().eq(P.name)") {
491             private String JavaDoc name=BSTR;
492             
493             public int expected() { return 1;}
494             public boolean match(Data candidate) {
495                 return candidate.getName().equals(name);
496             }
497         },
498         // arithmetic
499
new ExpectingPredicate("id>=P.id+1") {
500             private int id=2;
501             
502             public int expected() { return 2;}
503             public boolean match(Data candidate) {
504                 return candidate.id>=id+1;
505             }
506         },
507         new ExpectingPredicate("id>=P.calc()") {
508             private int factor=2;
509             
510             private int calc() {
511                 return factor+1;
512             }
513             
514             public int expected() { return 2;}
515             public boolean match(Data candidate) {
516                 return candidate.id>=calc();
517             }
518         },
519         new ExpectingPredicate("getValue()==P.calc()") {
520             private float predFactor=2.0f;
521             
522             private float calc() {
523                 return predFactor*1.1f;
524             }
525             
526             public int expected() { return 1;}
527             public boolean match(Data candidate) {
528                 return candidate.getValue()==calc();
529             }
530         },
531         // force extent
532
new ExpectingPredicate("force extent",Data.class) {
533             public int expected() { return 1;}
534             public boolean match(Object JavaDoc candidate) {
535                 return ((Data)candidate).getId()==1;
536             }
537         },
538         // array access
539
new ExpectingPredicate("id==P.data[3]") {
540             private int[] data={0,1,2,3,4};
541             
542             public int expected() { return 2;}
543             public boolean match(Data candidate) {
544                 return candidate.id==data[3];
545             }
546         },
547         new ExpectingPredicate("prev==P.data[3]") {
548             private Data[] data={null,null,null,null};
549             
550             public int expected() { return 2;}
551             public boolean match(Data candidate) {
552                 return candidate.prev==data[3];
553             }
554         },
555         // non-candidate method calls
556
new ExpectingPredicate("id==Integer.parseInt('3')") {
557             public int expected() { return 2;}
558             public boolean match(Data candidate) {
559                 return candidate.id==Integer.parseInt("3");
560             }
561         },
562         new ExpectingPredicate("id==P.sum(3,0)") {
563             public int expected() { return 2;}
564             private int sum(int a,int b) {
565                 return a+b;
566             }
567             public boolean match(Data candidate) {
568                 return candidate.id==sum(3,0);
569             }
570         },
571         // primitive wrappers
572
new ExpectingPredicate("boolWrapper") {
573             public int expected() { return 1;}
574             public boolean match(Data candidate) {
575                 return candidate.boolWrap.booleanValue();
576             }
577         },
578         new ExpectingPredicate("INTWRAPPER.eq(idwrap)") {
579             public int expected() { return 1;}
580             public boolean match(Data candidate) {
581                 return NQRegressionTestCase.INTWRAPPER.equals(candidate.idWrap);
582             }
583         },
584         new ExpectingPredicate("idwrap.value==1") {
585             public int expected() { return 1;}
586             public boolean match(Data candidate) {
587                 return candidate.idWrap.intValue()==1;
588             }
589         },
590         new ExpectingPredicate("id==INTWRAPPER.intValue()") {
591             public int expected() { return 1;}
592             public boolean match(Data candidate) {
593                 return candidate.id==INTWRAPPER.intValue();
594             }
595         },
596         new ExpectingPredicate("idwrap.compareTo(INTWRAPPER)<2") {
597             public int expected() { return 3;}
598             public boolean match(Data candidate) {
599                 return candidate.idWrap.compareTo(INTWRAPPER)>0;
600             }
601         },
602         // Note: We never get to see a static field access here - non-static inner class
603
// stuff converts this to NQRegressionTests#access$0()
604
new ExpectingPredicate("PRIVATE_INTWRAPPER.eq(idWrap)") {
605             public int expected() { return 1;}
606             public boolean match(Data candidate) {
607                 return NQRegressionTestCase.PRIVATE_INTWRAPPER.equals(candidate.idWrap);
608             }
609         },
610     };
611     
612     private static ExpectingPredicate[] PREDICATES=_PREDICATES;
613     
614     public void testAll() {
615         for (int predIdx = 0; predIdx < PREDICATES.length; predIdx++) {
616             ExpectingPredicate predicate = PREDICATES[predIdx];
617             assertNQResult(predicate);
618         }
619     }
620     
621     private void assertNQResult(final ExpectingPredicate predicate) {
622         final String JavaDoc predicateId = "PREDICATE: "+predicate;
623         ObjectContainer db=db();
624         Db4oQueryExecutionListener listener = new Db4oQueryExecutionListener() {
625             private int run=0;
626             
627             public void notifyQueryExecuted(NQOptimizationInfo info) {
628                 if(run<2) {
629                     Assert.areEqual(info.predicate(),predicate,predicateId);
630                 }
631                 String JavaDoc expMsg=null;
632                 switch(run) {
633                     case 0:
634                         expMsg=NativeQueryHandler.UNOPTIMIZED;
635                         Assert.isNull(info.optimized(),predicateId);
636                         break;
637                     case 1:
638                         expMsg=NativeQueryHandler.DYNOPTIMIZED;
639                         Assert.isTrue(info.optimized() instanceof Expression,predicateId);
640                         break;
641                     case 2:
642                         expMsg=NativeQueryHandler.PREOPTIMIZED;
643                         Assert.isNull(info.optimized(),predicateId);
644                         break;
645                 }
646                 Assert.areEqual(expMsg,info.message(),predicateId);
647                 run++;
648             }
649         };
650         ((YapStream)db).getNativeQueryHandler().addListener(listener);
651         db.ext().configure().optimizeNativeQueries(false);
652         ObjectSet raw=db.query(predicate);
653         db.ext().configure().optimizeNativeQueries(true);
654         if(NQDebug.LOG) {
655             System.err.println("PREDICATE: "+predicate);
656         }
657         ObjectSet optimized=db.query(predicate);
658         if(!raw.equals(optimized)) {
659             System.out.println("RAW");
660             raw.reset();
661             while(raw.hasNext()) {
662                 System.out.println(raw.next());
663             }
664             System.out.println("OPT");
665             optimized.reset();
666             while(optimized.hasNext()) {
667                 System.out.println(optimized.next());
668             }
669         }
670         Assert.areEqual(raw,optimized,predicateId);
671         Assert.areEqual(predicate.expected(),raw.size(),predicateId);
672
673         if(RUN_LOADTIME) {
674             db.ext().configure().optimizeNativeQueries(false);
675             try {
676                 Db4oEnhancingClassloader loader=new Db4oEnhancingClassloader(getClass().getClassLoader());
677                 Class JavaDoc filterClass=loader.loadClass(predicate.getClass().getName());
678                 Constructor constr=null;
679                 Object JavaDoc[] args=null;
680                 try {
681                     constr=filterClass.getDeclaredConstructor(new Class JavaDoc[]{String JavaDoc.class});
682                     args=new Object JavaDoc[]{filterClass.getName()};
683                 }
684                 catch(NoSuchMethodException JavaDoc exc) {
685                     constr=filterClass.getDeclaredConstructor(new Class JavaDoc[]{String JavaDoc.class,Class JavaDoc.class});
686                     args=new Object JavaDoc[]{filterClass.getName(),Data.class};
687                 }
688                 constr.setAccessible(true);
689                 Predicate clPredicate=(Predicate)constr.newInstance(args);
690                 ObjectSet preoptimized=db.query(clPredicate);
691                 Assert.areEqual(predicate.expected(),preoptimized.size(),predicateId);
692                 Assert.areEqual(raw,preoptimized,predicateId);
693                 Assert.areEqual(optimized,preoptimized,predicateId);
694             }
695             catch (Throwable JavaDoc exc) {
696                 exc.printStackTrace();
697             }
698         }
699         ((YapStream)db).getNativeQueryHandler().clearListeners();
700         db.ext().configure().optimizeNativeQueries(true);
701     }
702 }
703
Popular Tags