Author: simoneg
Date: Mon Jan  4 12:27:35 2010
New Revision: 895613

URL: http://svn.apache.org/viewvc?rev=895613&view=rev
Log:
QBE now supports query customization via an interface

Added:
    
labs/magma/trunk/foundation-database/src/main/java/org/apache/magma/database/QueryByExampleBean.java
Modified:
    
labs/magma/trunk/foundation-database/src/main/java/org/apache/magma/database/QueryByExampleBuilder.java
    
labs/magma/trunk/foundation-database/src/test/java/org/apache/magma/database/TestQbe.java

Added: 
labs/magma/trunk/foundation-database/src/main/java/org/apache/magma/database/QueryByExampleBean.java
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/foundation-database/src/main/java/org/apache/magma/database/QueryByExampleBean.java?rev=895613&view=auto
==============================================================================
--- 
labs/magma/trunk/foundation-database/src/main/java/org/apache/magma/database/QueryByExampleBean.java
 (added)
+++ 
labs/magma/trunk/foundation-database/src/main/java/org/apache/magma/database/QueryByExampleBean.java
 Mon Jan  4 12:27:35 2010
@@ -0,0 +1,18 @@
+package org.apache.magma.database;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.magma.database.QueryByExampleBuilder.FieldSettings;
+
+public interface QueryByExampleBean {
+
+       public class QueryPart {
+               public String join;
+               public String clause;
+               public List<Object> params = new ArrayList<Object>();
+       }
+       
+       public QueryPart modifyQueryFor(String field, FieldSettings settings);
+       
+}

Modified: 
labs/magma/trunk/foundation-database/src/main/java/org/apache/magma/database/QueryByExampleBuilder.java
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/foundation-database/src/main/java/org/apache/magma/database/QueryByExampleBuilder.java?rev=895613&r1=895612&r2=895613&view=diff
==============================================================================
--- 
labs/magma/trunk/foundation-database/src/main/java/org/apache/magma/database/QueryByExampleBuilder.java
 (original)
+++ 
labs/magma/trunk/foundation-database/src/main/java/org/apache/magma/database/QueryByExampleBuilder.java
 Mon Jan  4 12:27:35 2010
@@ -15,6 +15,7 @@
 
 import org.apache.commons.beanutils.MethodUtils;
 import org.apache.magma.basics.MagmaException;
+import org.apache.magma.database.QueryByExampleBean.QueryPart;
 
 public class QueryByExampleBuilder<T> {
 
@@ -45,8 +46,15 @@
        public void addIgnore(String field) {
                this.ignoreds.add(field);
        }
-       
        public Query generateQuery(T qbe) {
+               return generateQuery(qbe, qbe.getClass());
+       }
+
+       
+       public Query generateQuery(T qbe, Class targetClass) {
+               QueryByExampleBean qbeb = null;
+               if (qbe instanceof QueryByExampleBean) qbeb = 
(QueryByExampleBean) qbe;
+               StringBuilder fromb = new StringBuilder();
                StringBuilder sb = new StringBuilder();
                boolean wheresent = false;
                List<Object> params = new ArrayList<Object>();
@@ -68,80 +76,105 @@
                                }
                                if (settings == null) settings = this.defaults;
                                String clause = "";
-                               if (type.equals(String.class)) {
-                                       String val = (String) rm.invoke(qbe);
-                                       if (val == null || val.length() == 0) 
continue;
-                                       boolean like = false;
-                                       if (settings.getStartsLike()) {
-                                               val = val + "%";
-                                               like = true;
-                                       } else if (settings.getContainsLike() 
|| settings.getKeywordsLike()) {
-                                               val = "%" + val + "%";
-                                               like = true;
-                                       }
-                                       if (settings.getKeywordsLike()) {
-                                               val = val.replace(' ', '%');
-                                               like = true;
-                                       }
-                                       clause = "x." + name;
-                                       if (!settings.getCaseSensitive()) {
-                                               clause = "LOWER(" + clause + 
")";
-                                               val = val.toLowerCase();
-                                       }
-                                       if (like) {
-                                               clause += " LIKE ";
+                               QueryPart part = null;
+                               if (qbeb != null) part = 
qbeb.modifyQueryFor(name, settings);
+                               if (qbeb == null || part == null) {
+                                       if (type.equals(String.class)) {
+                                               String val = (String) 
rm.invoke(qbe);
+                                               if (val == null || val.length() 
== 0) continue;
+                                               boolean like = false;
+                                               if (settings.getStartsLike()) {
+                                                       val = val + "%";
+                                                       like = true;
+                                               } else if 
(settings.getContainsLike() || settings.getKeywordsLike()) {
+                                                       val = "%" + val + "%";
+                                                       like = true;
+                                               }
+                                               if (settings.getKeywordsLike()) 
{
+                                                       val = val.replace(' ', 
'%');
+                                                       like = true;
+                                               }
+                                               clause = "x." + name;
+                                               if 
(!settings.getCaseSensitive()) {
+                                                       clause = "LOWER(" + 
clause + ")";
+                                                       val = val.toLowerCase();
+                                               }
+                                               if (like) {
+                                                       clause += " LIKE ";
+                                               } else {
+                                                       clause += " = ";
+                                               }
+                                               clause += "?" + (params.size() 
+ 1);
+                                               params.add(val);                
                                
+                                       } else if 
(Number.class.isAssignableFrom(type)) {
+                                               Number val = 
(Number)rm.invoke(qbe);
+                                               if (val == null) continue;
+                                               if (!settings.getConsiderZero() 
&& val.intValue() == 0) continue;
+                                               clause = "x." + name;
+                                               clause += "=?" + (params.size() 
+ 1);
+                                               params.add(val);
+                                       } else if 
(Date.class.isAssignableFrom(type)) {
+                                               // Try to create a range around 
meaningful part of a date.
+                                               Date val = (Date) 
rm.invoke(qbe);
+                                               if (val == null) continue;
+                                               GregorianCalendar calendar = 
new GregorianCalendar();
+                                               calendar.setTime(val);
+                                               for (int calele : new int[] {
+                                                               
GregorianCalendar.MILLISECOND,
+                                                               
GregorianCalendar.SECOND,
+                                                               
GregorianCalendar.MINUTE,
+                                                               
GregorianCalendar.HOUR_OF_DAY,
+                                                               
GregorianCalendar.DAY_OF_MONTH,
+                                                               
GregorianCalendar.MONTH
+                                                       }) {
+                                                       if 
(calendar.get(calele) == calendar.getActualMinimum(calele)) {
+                                                               
calendar.set(calele, calendar.getActualMaximum(calele));
+                                                       }
+                                               }
+                                               clause = "(x." + name + ">=";
+                                               clause += "?" + (params.size() 
+ 1);
+                                               params.add(val);        
+                                               clause += " AND x." + name + 
"<=";
+                                               clause += "?" + (params.size() 
+ 1) + ")";
+                                               params.add(calendar.getTime()); 
                                        } else {
-                                               clause += " = ";
-                                       }
-                                       clause += "?" + (params.size() + 1);
-                                       params.add(val);
-                               } else if (Number.class.isAssignableFrom(type)) 
{
-                                       Number val = (Number)rm.invoke(qbe);
-                                       if (val == null) continue;
-                                       if (!settings.getConsiderZero() && 
val.intValue() == 0) continue;
-                                       clause = "x." + name;
-                                       clause += "=?" + (params.size() + 1);
-                                       params.add(val);        
-                               } else if (Date.class.isAssignableFrom(type)) {
-                                       // Try to create a range around 
meaningful part of a date.
-                                       Date val = (Date) rm.invoke(qbe);
-                                       if (val == null) continue;
-                                       GregorianCalendar calendar = new 
GregorianCalendar();
-                                       calendar.setTime(val);
-                                       for (int calele : new int[] {
-                                                       
GregorianCalendar.MILLISECOND,
-                                                       
GregorianCalendar.SECOND,
-                                                       
GregorianCalendar.MINUTE,
-                                                       
GregorianCalendar.HOUR_OF_DAY,
-                                                       
GregorianCalendar.DAY_OF_MONTH,
-                                                       GregorianCalendar.MONTH
-                                               }) {
-                                               if (calendar.get(calele) == 
calendar.getActualMinimum(calele)) {
-                                                       calendar.set(calele, 
calendar.getActualMaximum(calele));
+                                               Object val = rm.invoke(qbe);
+                                               if (val == null) continue;
+                                               clause = "x." + name;
+                                               clause += "=?" + (params.size() 
+ 1);
+                                               params.add(val);
+                                       }
+                                       if (clause != null) {
+                                               if (wheresent) {
+                                                       sb.append(this.useOr ? 
" OR " : " AND ");
+                                               } else {
+                                                       sb.append(" WHERE ");
+                                                       wheresent = true;
                                                }
+                                               sb.append(clause);
                                        }
-                                       clause = "(x." + name + ">=";
-                                       clause += "?" + (params.size() + 1);
-                                       params.add(val);        
-                                       clause += " AND x." + name + "<=";
-                                       clause += "?" + (params.size() + 1) + 
")";
-                                       params.add(calendar.getTime()); 
-                                       
                                } else {
-                                       Object val = rm.invoke(qbe);
-                                       if (val == null) continue;
-                                       clause = "x." + name;
-                                       clause += "=?" + (params.size() + 1);
-                                       params.add(val);                        
                                        
-                               }
-                               if (clause != null) {
+                                       if (part.join != null && 
part.join.length() > 0) {
+                                               if (fromb.length() == 0) {
+                                                       fromb.append("FROM ");
+                                                       
fromb.append(targetClass.getName());
+                                                       fromb.append(" x ");
+                                               }
+                                               fromb.append(",");
+                                               fromb.append(part.join);
+                                       }
+                                       String pcl = part.clause;
+                                       for (int i = 0; i < part.params.size(); 
i++) {
+                                               params.add(part.params.get(i));
+                                               pcl = pcl.replaceAll("\\?" + (i 
+ 1), "?" + (params.size()));
+                                       }
                                        if (wheresent) {
                                                sb.append(this.useOr ? " OR " : 
" AND ");
                                        } else {
                                                sb.append(" WHERE ");
                                                wheresent = true;
                                        }
-                                       sb.append(clause);
+                                       sb.append(pcl);
                                }
                        }
                } catch (Exception e) {
@@ -149,12 +182,15 @@
                }
                
                Query ret = new Query();
+               if (fromb.length() > 0)
+                       ret.from = fromb.toString(); 
                ret.query = sb.toString();
                ret.params = params.toArray();
                return ret;
        }
        
        public class Query {
+               public String from;
                public String query;
                public Object[] params;
        }

Modified: 
labs/magma/trunk/foundation-database/src/test/java/org/apache/magma/database/TestQbe.java
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/foundation-database/src/test/java/org/apache/magma/database/TestQbe.java?rev=895613&r1=895612&r2=895613&view=diff
==============================================================================
--- 
labs/magma/trunk/foundation-database/src/test/java/org/apache/magma/database/TestQbe.java
 (original)
+++ 
labs/magma/trunk/foundation-database/src/test/java/org/apache/magma/database/TestQbe.java
 Mon Jan  4 12:27:35 2010
@@ -7,6 +7,7 @@
 import java.util.Date;
 import java.util.GregorianCalendar;
 
+import org.apache.magma.database.QueryByExampleBuilder.FieldSettings;
 import org.apache.magma.database.QueryByExampleBuilder.Query;
 import static org.apache.magma.testing.AssertStringStructure.assertStructure;
 import org.junit.Test;
@@ -103,11 +104,87 @@
                assertThat(query.params.length, equalTo(2));
                assertStructure(query.query, "WHERE", "x.birthday", ">=", "?1", 
"AND", "x.birthday", "<=", "?2", ")", "$$");
                assertThat((Date)query.params[0], equalTo(cal.getTime()));
+               cal.setTime((Date) query.params[0]);
+               assertThat(cal.get(GregorianCalendar.YEAR), equalTo(1979));
+               assertThat(cal.get(GregorianCalendar.MONTH), 
equalTo(GregorianCalendar.MARCH));
+               assertThat(cal.get(GregorianCalendar.DAY_OF_MONTH), equalTo(5));
+               assertThat(cal.get(GregorianCalendar.HOUR_OF_DAY), equalTo(0));
+               assertThat(cal.get(GregorianCalendar.MINUTE), equalTo(0));
+               assertThat(cal.get(GregorianCalendar.SECOND), equalTo(0));
+               assertThat(cal.get(GregorianCalendar.MILLISECOND), equalTo(0));
                cal.setTime((Date) query.params[1]);
+               assertThat(cal.get(GregorianCalendar.YEAR), equalTo(1979));
+               assertThat(cal.get(GregorianCalendar.MONTH), 
equalTo(GregorianCalendar.MARCH));
+               assertThat(cal.get(GregorianCalendar.DAY_OF_MONTH), equalTo(5));
                assertThat(cal.get(GregorianCalendar.HOUR_OF_DAY), equalTo(23));
                assertThat(cal.get(GregorianCalendar.MINUTE), equalTo(59));
                assertThat(cal.get(GregorianCalendar.SECOND), equalTo(59));
                assertThat(cal.get(GregorianCalendar.MILLISECOND), 
equalTo(999));
        }
        
+       @Test
+       public void qbeBean() throws Exception {
+               
+               class SpecificBean implements QueryByExampleBean {
+                       private String name;
+                       private String state;
+                       
+                       public String getName() {
+                               return name;
+                       }
+                       public void setName(String name) {
+                               this.name = name;
+                       }
+                       public String getState() {
+                               return state;
+                       }
+                       public void setState(String state) {
+                               this.state = state;
+                       }
+                       
+                       public QueryPart modifyQueryFor(String field, 
FieldSettings settings) {
+                               if (field.equals("state") && this.getState() != 
null) {
+                                       QueryPart ret = new QueryPart();
+                                       ret.join = "LEFT JOIN x.locations 
location";
+                                       ret.clause = "location.state=?1";
+                                       ret.params.add(this.getState());
+                                       return ret;
+                               }
+                               return null;
+                       }
+               }
+               
+               SpecificBean sb = new SpecificBean();
+               QueryByExampleBuilder<SpecificBean> qbe = new 
QueryByExampleBuilder<SpecificBean>();
+               Query query = qbe.generateQuery(sb);
+               System.out.println(query.query);
+               assertThat(query.params.length, equalTo(0));
+               assertStructure(query.query, "!!WHERE");
+               
+               sb.name = "foo";
+               query = qbe.generateQuery(sb);
+               System.out.println(query.query);
+               assertThat(query.params.length, equalTo(1));
+               assertStructure(query.query, "WHERE", "LOWER(x.name)", "LIKE", 
"?1", "$$");
+               
+               sb.name=null;
+               sb.state = "Alabama";
+               query = qbe.generateQuery(sb);
+               System.out.println(query.from);
+               System.out.println(query.query);
+               assertThat(query.params.length, equalTo(1));
+               assertStructure(query.from, "FROM", 
SpecificBean.class.getName(), "x", "LEFT JOIN", "x.locations", "location", 
"$$");
+               assertStructure(query.query, "WHERE", "location.state", "=", 
"?1", "$$");
+
+               sb.name="foo";
+               sb.state = "Alabama";
+               query = qbe.generateQuery(sb);
+               System.out.println(query.from);
+               System.out.println(query.query);
+               assertThat(query.params.length, equalTo(2));
+               assertStructure(query.from, "FROM", 
SpecificBean.class.getName(), "x", "LEFT JOIN", "x.locations", "location", 
"$$");
+               assertStructure(query.query, "WHERE", "x.name", "?1", 
"location.state", "=", "?2", "$$");
+
+       }
+       
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to