You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by si...@apache.org on 2010/01/04 13:27:35 UTC
svn commit: r895613 - in /labs/magma/trunk/foundation-database/src:
main/java/org/apache/magma/database/QueryByExampleBean.java
main/java/org/apache/magma/database/QueryByExampleBuilder.java
test/java/org/apache/magma/database/TestQbe.java
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: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org