diff options
author | James Ahlborn <jtahlborn@yahoo.com> | 2009-05-28 02:57:33 +0000 |
---|---|---|
committer | James Ahlborn <jtahlborn@yahoo.com> | 2009-05-28 02:57:33 +0000 |
commit | cd23b435686872ea0abd59568be5bd2bd1994858 (patch) | |
tree | 70923292c775828b5da4348f19edca4168607a62 | |
parent | 9ee53ade6d1056a259a7472fa3ba8116f708a7cb (diff) | |
download | jackcess-cd23b435686872ea0abd59568be5bd2bd1994858.tar.gz jackcess-cd23b435686872ea0abd59568be5bd2bd1994858.zip |
add initial test for reading queries; add support for multicolumn joins
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@393 f203690c-595d-4dc9-a70b-905162fa7fd2
-rw-r--r-- | src/java/com/healthmarketscience/jackcess/query/Query.java | 58 | ||||
-rwxr-xr-x | test/data/queryTest.mdb | bin | 0 -> 163840 bytes | |||
-rw-r--r-- | test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java | 14 | ||||
-rw-r--r-- | test/src/java/com/healthmarketscience/jackcess/query/QueryTest.java | 48 |
4 files changed, 111 insertions, 9 deletions
diff --git a/src/java/com/healthmarketscience/jackcess/query/Query.java b/src/java/com/healthmarketscience/jackcess/query/Query.java index 7853859..08f6f48 100644 --- a/src/java/com/healthmarketscience/jackcess/query/Query.java +++ b/src/java/com/healthmarketscience/jackcess/query/Query.java @@ -28,10 +28,12 @@ King of Prussia, PA 19406 package com.healthmarketscience.jackcess.query; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -224,7 +226,31 @@ public abstract class Query List<Row> joins = getJoinRows(); if(!joins.isEmpty()) { - for(Row join : joins) { + // combine any multi-column joins + Collection<List<Row>> comboJoins = combineJoins(joins); + + for(List<Row> comboJoin : comboJoins) { + + Row join = comboJoin.get(0); + String joinExpr = join.expression; + + if(comboJoin.size() > 1) { + + // combine all the join expressions with "AND" + AppendableList<String> comboExprs = new AppendableList<String>() { + private static final long serialVersionUID = 0L; + @Override + protected String getSeparator() { + return ") AND ("; + } + }; + for(Row tmpJoin : comboJoin) { + comboExprs.add(tmpJoin.expression); + } + + joinExpr = new StringBuilder().append("(") + .append(comboExprs).append(")").toString(); + } String fromTable = join.name1; String toTable = join.name2; @@ -238,7 +264,7 @@ public abstract class Query String expr = new StringBuilder().append(fromExpr) .append(joinType).append(toExpr).append(" ON ") - .append(join.expression).toString(); + .append(joinExpr).toString(); fromExpr.join(toExpr, expr); joinExprs.add(fromExpr); @@ -265,6 +291,28 @@ public abstract class Query throw new IllegalStateException("Cannot find join table " + table); } + private Collection<List<Row>> combineJoins(List<Row> joins) + { + // combine joins with the same to/from tables + Map<List<String>,List<Row>> comboJoinMap = + new LinkedHashMap<List<String>,List<Row>>(); + for(Row join : joins) { + List<String> key = Arrays.asList(join.name1, join.name2); + List<Row> comboJoins = comboJoinMap.get(key); + if(comboJoins == null) { + comboJoins = new ArrayList<Row>(); + comboJoinMap.put(key, comboJoins); + } else { + if(comboJoins.get(0).flag != join.flag) { + throw new IllegalStateException( + "Mismatched join flags for combo joins"); + } + } + comboJoins.add(join); + } + return comboJoinMap.values(); + } + protected String getFromRemoteDbPath() { return getRemoteDatabaseRow().name1; @@ -610,13 +658,17 @@ public abstract class Query super(c); } + protected String getSeparator() { + return ", "; + } + @Override public String toString() { StringBuilder builder = new StringBuilder(); for(Iterator<E> iter = iterator(); iter.hasNext(); ) { builder.append(iter.next().toString()); if(iter.hasNext()) { - builder.append(", "); + builder.append(getSeparator()); } } return builder.toString(); diff --git a/test/data/queryTest.mdb b/test/data/queryTest.mdb Binary files differnew file mode 100755 index 0000000..5bb6b28 --- /dev/null +++ b/test/data/queryTest.mdb diff --git a/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java b/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java index aedf3e7..5b5d343 100644 --- a/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java +++ b/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java @@ -66,27 +66,29 @@ public class DatabaseTest extends TestCase { super(name); } - static Database open() throws Exception { + public static Database open() throws Exception { return open(new File("test/data/test.mdb")); } - static Database open(File file) throws Exception { + public static Database open(File file) throws Exception { return Database.open(file, true, _autoSync); } - static Database create() throws Exception { + public static Database create() throws Exception { return create(false); } - static Database create(boolean keep) throws Exception { + public static Database create(boolean keep) throws Exception { return Database.create(createTempFile(keep), _autoSync); } - static Database openCopy(File srcFile) throws Exception { + public static Database openCopy(File srcFile) throws Exception { return openCopy(srcFile, false); } - static Database openCopy(File srcFile, boolean keep) throws Exception { + public static Database openCopy(File srcFile, boolean keep) + throws Exception + { File tmp = createTempFile(keep); copyFile(srcFile, tmp); return Database.open(tmp, false, _autoSync); diff --git a/test/src/java/com/healthmarketscience/jackcess/query/QueryTest.java b/test/src/java/com/healthmarketscience/jackcess/query/QueryTest.java index 10d976c..5d24307 100644 --- a/test/src/java/com/healthmarketscience/jackcess/query/QueryTest.java +++ b/test/src/java/com/healthmarketscience/jackcess/query/QueryTest.java @@ -27,12 +27,17 @@ King of Prussia, PA 19406 package com.healthmarketscience.jackcess.query; +import java.io.File; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import com.healthmarketscience.jackcess.DataType; +import com.healthmarketscience.jackcess.Database; +import com.healthmarketscience.jackcess.DatabaseTest; import com.healthmarketscience.jackcess.query.Query.Row; import junit.framework.TestCase; import org.apache.commons.lang.StringUtils; @@ -192,6 +197,49 @@ public class QueryTest extends TestCase } + public void testReadQueries() throws Exception + { + Map<String,String> expectedQueries = new HashMap<String,String>(); + expectedQueries.put( + "SelectQuery", multiline( + "SELECT Table1.*, Table2.col1, Table2.col2, Table3.col3", + "FROM (Table1 LEFT OUTER JOIN Table3 ON Table1.col1 = Table3.col1) INNER JOIN Table2 ON (Table3.col1 = Table2.col1) AND (Table3.col1 = Table2.col2)", + "WHERE (((Table2.col2)=\"foo\" Or (Table2.col2) In (\"buzz\",\"bazz\")))", + "ORDER BY Table2.col1;")); + expectedQueries.put( + "DeleteQuery", multiline( + "DELETE Table1.col1, Table1.col2, Table1.col3", + "FROM Table1", + "WHERE (((Table1.col1)>\"blah\"));")); + expectedQueries.put( + "AppendQuery",multiline( + "INSERT INTO Table3", + "SELECT [Table1].[col2], [Table2].[col2], [Table2].[col3]", + "FROM Table3, Table1 INNER JOIN Table2 ON [Table1].[col1]=[Table2].[col1];")); + expectedQueries.put( + "UpdateQuery",multiline( + "UPDATE Table1", + "SET Table1.col1 = \"foo\", Table1.col2 = [Table2].[col3]", + "WHERE (([Table2].[col1] Is Not Null));")); + expectedQueries.put( + "MakeTableQuery",multiline( + "SELECT Max(Table2.col1) AS MaxOfcol1, Table2.col2, Table3.col2 INTO Table4", + "FROM (Table2 INNER JOIN Table1 ON Table2.col1 = Table1.col2) RIGHT OUTER JOIN Table3 ON Table1.col2 = Table3.col3", + "GROUP BY Table2.col2, Table3.col2", + "HAVING (((Max(Table2.col1))=\"buzz\") AND ((Table2.col2)<>\"blah\"));")); + + Database db = DatabaseTest.open(new File("test/data/queryTest.mdb")); + + Map<String,String> foundQueries = new HashMap<String,String>(); + for(Query q : db.getQueries()) { + assertNull(foundQueries.put(q.getName(), q.toSQLString())); + } + + assertEquals(expectedQueries, foundQueries); + + db.close(); + } + private void doTestColumns(SelectQuery query) throws Exception { addRows(query, newRow(COLUMN_ATTRIBUTE, "Table1.id", null, null)); |