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