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 2009/12/11 16:37:35 UTC
svn commit: r889664 - in /labs/magma/trunk/foundation-database: pom.xml
src/main/java/org/apache/magma/database/QueryByExampleBuilder.java
src/test/java/org/apache/magma/database/TestQbe.java
Author: simoneg
Date: Fri Dec 11 15:37:34 2009
New Revision: 889664
URL: http://svn.apache.org/viewvc?rev=889664&view=rev
Log:
LABS-501 : Query by example system
Added:
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
Modified:
labs/magma/trunk/foundation-database/pom.xml
Modified: labs/magma/trunk/foundation-database/pom.xml
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-database/pom.xml?rev=889664&r1=889663&r2=889664&view=diff
==============================================================================
--- labs/magma/trunk/foundation-database/pom.xml (original)
+++ labs/magma/trunk/foundation-database/pom.xml Fri Dec 11 15:37:34 2009
@@ -43,9 +43,9 @@
<version>1.0</version>
</dependency>
<dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.4</version>
+ <groupId>org.apache.magma.tools</groupId>
+ <artifactId>magma-test-utilities</artifactId>
+ <version>0.0.3-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
Added: 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=889664&view=auto
==============================================================================
--- labs/magma/trunk/foundation-database/src/main/java/org/apache/magma/database/QueryByExampleBuilder.java (added)
+++ labs/magma/trunk/foundation-database/src/main/java/org/apache/magma/database/QueryByExampleBuilder.java Fri Dec 11 15:37:34 2009
@@ -0,0 +1,200 @@
+package org.apache.magma.database;
+
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.Transient;
+
+import org.apache.commons.beanutils.MethodUtils;
+import org.apache.magma.basics.MagmaException;
+
+public class QueryByExampleBuilder<T> {
+
+ private FieldSettings defaults = new FieldSettings();
+ private Map<String, FieldSettings> settings;
+ private List<String> ignoreds = new ArrayList<String>();
+ private boolean useOr = false;
+
+ public QueryByExampleBuilder() {
+ addIgnore("class");
+ defaults.caseSensitive = false;
+ defaults.considerZero = false;
+ defaults.containsLike = true;
+ defaults.keywordsLike = false;
+ defaults.startsLike = false;
+ }
+
+ public FieldSettings getSettings() {
+ return this.defaults;
+ }
+
+ public void addSettings(String field, FieldSettings settings) {
+ if (this.settings == null) this.settings = new HashMap<String, FieldSettings>();
+ settings.setParent(defaults);
+ this.settings.put(field, settings);
+ }
+
+ public void addIgnore(String field) {
+ this.ignoreds.add(field);
+ }
+
+ public Query generateQuery(T qbe) {
+ StringBuilder sb = new StringBuilder();
+ boolean wheresent = false;
+ List<Object> params = new ArrayList<Object>();
+ try {
+ BeanInfo infos = Introspector.getBeanInfo(qbe.getClass());
+ PropertyDescriptor[] descs = infos.getPropertyDescriptors();
+ for (PropertyDescriptor desc : descs) {
+ String name = desc.getName();
+ if (ignoreds.contains(name)) continue;
+ Class<?> type = desc.getPropertyType();
+ type = MethodUtils.toNonPrimitiveClass(type);
+ if (type == null) continue;
+ Method rm = desc.getReadMethod();
+ if (rm == null || desc.getWriteMethod() == null) continue;
+ if (rm.isAnnotationPresent(Transient.class)) continue;
+ FieldSettings settings = null;
+ if (this.settings != null) {
+ settings = this.settings.get(name);
+ }
+ 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 ";
+ } 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 {
+ 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);
+ }
+ }
+ } catch (Exception e) {
+ throw new MagmaException(e, "Error creating query from QBE {0}", qbe.getClass());
+ }
+
+ Query ret = new Query();
+ ret.query = sb.toString();
+ ret.params = params.toArray();
+ return ret;
+ }
+
+ public class Query {
+ public String query;
+ public Object[] params;
+ }
+
+ public class FieldSettings {
+ private Boolean considerZero = null;
+ private Boolean caseSensitive = null;
+ private Boolean containsLike = null;
+ private Boolean startsLike = null;
+ private Boolean keywordsLike = null;
+ private FieldSettings parent;
+
+ public Boolean getConsiderZero() {
+ if (considerZero != null) return considerZero;
+ if (parent != null) return parent.getConsiderZero();
+ return null;
+ }
+ public void setConsiderZero(Boolean considerZero) {
+ this.considerZero = considerZero;
+ }
+ public Boolean getCaseSensitive() {
+ if (caseSensitive != null) return caseSensitive;
+ if (parent != null) return parent.getCaseSensitive();
+ return null;
+ }
+ public void setCaseSensitive(Boolean caseSensitive) {
+ this.caseSensitive = caseSensitive;
+ }
+ public Boolean getContainsLike() {
+ if (containsLike != null) return containsLike;
+ if (parent != null) return parent.getContainsLike();
+ return null;
+ }
+ public void setContainsLike(Boolean containsLike) {
+ this.containsLike = containsLike;
+ }
+ public Boolean getStartsLike() {
+ if (startsLike != null) return startsLike;
+ if (parent != null) return parent.getStartsLike();
+ return null;
+ }
+ public void setStartsLike(Boolean startsLike) {
+ this.startsLike = startsLike;
+ }
+ public Boolean getKeywordsLike() {
+ if (keywordsLike != null) return keywordsLike;
+ if (parent != null) return parent.getKeywordsLike();
+ return null;
+ }
+ public void setKeywordsLike(Boolean keywordsLike) {
+ this.keywordsLike = keywordsLike;
+ }
+ FieldSettings getParent() {
+ return parent;
+ }
+ void setParent(FieldSettings parent) {
+ this.parent = parent;
+ }
+ }
+
+ public boolean isUseOr() {
+ return useOr;
+ }
+
+ public void setUseOr(boolean useOr) {
+ this.useOr = useOr;
+ }
+
+}
Added: 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=889664&view=auto
==============================================================================
--- labs/magma/trunk/foundation-database/src/test/java/org/apache/magma/database/TestQbe.java (added)
+++ labs/magma/trunk/foundation-database/src/test/java/org/apache/magma/database/TestQbe.java Fri Dec 11 15:37:34 2009
@@ -0,0 +1,89 @@
+package org.apache.magma.database;
+
+import static org.junit.Assert.*;
+import static org.junit.matchers.JUnitMatchers.*;
+import static org.hamcrest.CoreMatchers.*;
+
+import java.util.Date;
+
+import org.apache.magma.database.QueryByExampleBuilder.Query;
+import static org.apache.magma.testing.AssertStringStructure.assertStructure;
+import org.junit.Test;
+
+
+public class TestQbe {
+
+ @Test
+ public void simpleQuery() throws Exception {
+
+ class SimpleBean {
+ private String name;
+ private int height;
+ private Date birthday;
+
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public int getHeight() {
+ return height;
+ }
+ public void setHeight(int height) {
+ this.height = height;
+ }
+ public Date getBirthday() {
+ return birthday;
+ }
+ public void setBirthday(Date birthday) {
+ this.birthday = birthday;
+ }
+ }
+
+ SimpleBean sb = new SimpleBean();
+ QueryByExampleBuilder<SimpleBean> qbe = new QueryByExampleBuilder<SimpleBean>();
+ Query query = qbe.generateQuery(sb);
+ System.out.println(query.query);
+ assertThat(query.params.length, equalTo(0));
+ assertStructure(query.query, "!!WHERE");
+
+ sb.height = 178;
+ query = qbe.generateQuery(sb);
+ System.out.println(query.query);
+ assertThat(query.params.length, equalTo(1));
+ assertStructure(query.query, "WHERE", "height", "=", "?1", "$$");
+
+ sb.height = 0;
+ sb.name="Simone";
+ query = qbe.generateQuery(sb);
+ System.out.println(query.query);
+ assertThat(query.params.length, equalTo(1));
+ assertStructure(query.query, "WHERE", "LOWER(x.name)", "LIKE", "?1", "$$");
+
+ qbe.getSettings().setContainsLike(false);
+ query = qbe.generateQuery(sb);
+ System.out.println(query.query);
+ assertThat(query.params.length, equalTo(1));
+ assertStructure(query.query, "WHERE", "LOWER(x.name)", "=", "?1", "$$");
+
+ qbe.getSettings().setCaseSensitive(true);
+ query = qbe.generateQuery(sb);
+ System.out.println(query.query);
+ assertThat(query.params.length, equalTo(1));
+ assertStructure(query.query, "WHERE", "name", "=", "?1", "$$");
+
+ sb.height = 178;
+ query = qbe.generateQuery(sb);
+ System.out.println(query.query);
+ assertThat(query.params.length, equalTo(2));
+ assertStructure(query.query, "WHERE", "?1", "AND", "?2", "$$");
+
+ qbe.setUseOr(true);
+ query = qbe.generateQuery(sb);
+ System.out.println(query.query);
+ assertThat(query.params.length, equalTo(2));
+ assertStructure(query.query, "WHERE", "?1", "OR", "?2", "$$");
+ }
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org