Browse Source

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
tags/rel_1_1_19
James Ahlborn 15 years ago
parent
commit
cd23b43568

+ 55
- 3
src/java/com/healthmarketscience/jackcess/query/Query.java View File

@@ -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();

BIN
test/data/queryTest.mdb View File


+ 8
- 6
test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java View File

@@ -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);

+ 48
- 0
test/src/java/com/healthmarketscience/jackcess/query/QueryTest.java View File

@@ -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));

Loading…
Cancel
Save