提交 2ca2ee4f authored 作者: Thomas Mueller's avatar Thomas Mueller

JaQu improvements

上级 d2ab2e8e
......@@ -28,6 +28,10 @@ public class Customer {
this.region = region;
}
public String toString() {
return customerId;
}
//## Java 1.5 begin ##
public static List<Customer> getCustomerList() {
Customer[] list = new Customer[] {
......
......@@ -49,13 +49,19 @@ public class SamplesTest extends TestBase {
db.insertAll(Product.getProductList());
db.insertAll(Customer.getCustomerList());
db.insertAll(Order.getOrderList());
// TODO MIN, MAX, LIKE, LIKE ESCAPE...
// TODO +, -, *, /, ||, nested operations
// TODO nested AND/OR
// TODO nested AND/OR, >, <,...
// TODO NOT
// TODO DELETE: FROM ... DELETE?
// TODO +, -, *, /, ||, nested operations
// TODO LIKE ESCAPE...
// TODO UPDATE: FROM ... UPDATE?
// TODO SELECT UNION
// TODO DatabaseAdapter
// TODO user prepared statements
testOrAndNot();
testDelete();
testIsNull();
testLike();
testMinMax();
testSum();
testLength();
testCount();
......@@ -84,11 +90,7 @@ public class SamplesTest extends TestBase {
where(p.unitsInStock).is(0).
orderBy(p.productId).select();
String result = "";
for (Product x : soldOutProducts) {
result += x.productName + ";";
}
assertEquals("Chef Anton's Gumbo Mix;", result);
assertEquals("[Chef Anton's Gumbo Mix: 0]", soldOutProducts.toString());
}
private void testWhereSimple3() throws Exception {
......@@ -103,19 +105,11 @@ public class SamplesTest extends TestBase {
List<Product> expensiveInStockProducts =
db.from(p).
where(p.unitsInStock).bigger(0).
and(p.unitPrice).bigger(3.0).
and(p.unitPrice).bigger(30.0).
orderBy(p.productId).select();
String result = "";
for (Product x : expensiveInStockProducts) {
result += x.productName + ";";
}
assertEquals(
"Chai;Chang;Aniseed Syrup;Chef Anton's Cajun Seasoning;"
+ "Grandma's Boysenberry Spread;"
+ "Uncle Bob's Organic Dried Pears;"
+ "Northwoods Cranberry Sauce;Mishi Kobe Niku;Ikura;",
result);
assertEquals("[Northwoods Cranberry Sauce: 6, Mishi Kobe Niku: 29, Ikura: 31]",
expensiveInStockProducts.toString());
}
......@@ -132,9 +126,7 @@ public class SamplesTest extends TestBase {
where(c.region).is("WA").
select();
for (Customer cu : waCustomers) {
assertEquals("WA", cu.region);
}
assertEquals("[ALFKI, ANATR]", waCustomers.toString());
}
private void testSelectSimple2() throws Exception {
......@@ -203,6 +195,9 @@ public class SamplesTest extends TestBase {
public String customerId;
public Integer orderId;
public BigDecimal total;
public String toString() {
return customerId + ":" + orderId + ":" + total;
}
}
//## Java 1.5 begin ##
......@@ -223,7 +218,7 @@ public class SamplesTest extends TestBase {
List<CustOrder> orders =
db.from(c).
innerJoin(o).on(c.customerId).is(o.customerId).
where(o.total).smaller(new BigDecimal("500.00")).
where(o.total).smaller(new BigDecimal("100.00")).
orderBy(1).
select(new CustOrder() { {
customerId = c.customerId;
......@@ -231,18 +226,32 @@ public class SamplesTest extends TestBase {
total = o.total;
}});
StringBuilder buff = new StringBuilder();
for (CustOrder co : orders) {
buff.append("c:");
buff.append(co.customerId);
buff.append("/o:");
buff.append(co.orderId);
buff.append(';');
assertEquals("[ANATR:10308:88.80]", orders.toString());
}
private void testIsNull() throws Exception {
Product p = new Product();
String sql = db.from(p).whereTrue(isNull(p.productName)).getSQL();
assertEquals("SELECT * FROM Product WHERE (productName IS NULL)", sql);
}
private void testDelete() throws Exception {
Product p = new Product();
int deleted = db.from(p).where(p.productName).like("A%").delete();
assertEquals(1, deleted);
deleted = db.from(p).delete();
assertEquals(9, deleted);
db.insertAll(Product.getProductList());
}
String s = buff.toString();
assertEquals("c:ALFKI/o:10702;c:ALFKI/o:10952;c:ANATR/o:10308;" +
"c:ANATR/o:10625;c:ANATR/o:10759;c:ANTON/o:10355;" +
"c:ANTON/o:10365;c:ANTON/o:10682;", s);
private void testOrAndNot() throws Exception {
Product p = new Product();
String sql = db.from(p).whereTrue(not(isNull(p.productName))).getSQL();
assertEquals("SELECT * FROM Product WHERE (NOT productName IS NULL)", sql);
sql = db.from(p).whereTrue(not(isNull(p.productName))).getSQL();
assertEquals("SELECT * FROM Product WHERE (NOT productName IS NULL)", sql);
sql = db.from(p).whereTrue(db.test(p.productId).is(1)).getSQL();
assertEquals("SELECT * FROM Product WHERE ((productId = 1))", sql);
}
private void testLength() throws Exception {
......@@ -251,24 +260,40 @@ public class SamplesTest extends TestBase {
where(length(p.productName)).smaller(10).
orderBy(1).
selectDistinct(length(p.productName));
String s = lengths.toString();
assertEquals("[4, 5]", s);
assertEquals("[4, 5]", lengths.toString());
}
private void testSum() throws Exception {
Product p = new Product();
Integer sum = db.from(p).
selectFirst(sum(p.unitsInStock));
Integer sum = db.from(p).selectFirst(sum(p.unitsInStock));
assertEquals(323, sum.intValue());
Double sumPrice = db.from(p).
selectFirst(sum(p.unitPrice));
Double sumPrice = db.from(p).selectFirst(sum(p.unitPrice));
assertEquals(313.35, sumPrice.doubleValue());
}
private void testMinMax() throws Exception {
Product p = new Product();
Integer min = db.from(p).selectFirst(min(p.unitsInStock));
assertEquals(0, min.intValue());
String minName = db.from(p).selectFirst(min(p.productName));
assertEquals("Aniseed Syrup", minName);
Double max = db.from(p).selectFirst(max(p.unitPrice));
assertEquals(97.0, max.doubleValue());
}
private void testLike() throws Exception {
Product p = new Product();
List<Product> aList = db.from(p).
where(p.productName).like("Cha%").
orderBy(p.productName).select();
assertEquals("[Chai: 39, Chang: 17]", aList.toString());
}
private void testCount() throws Exception {
long count = db.from(new Product()).selectCount();
assertEquals(10, count);
}
//## Java 1.5 end ##
/**
......@@ -277,6 +302,9 @@ public class SamplesTest extends TestBase {
public static class ProductGroup {
public String category;
public Long productCount;
public String toString() {
return category + ":" + productCount;
}
}
//## Java 1.5 begin ##
......@@ -300,16 +328,8 @@ public class SamplesTest extends TestBase {
productCount = count();
}});
StringBuilder buff = new StringBuilder();
for (ProductGroup og: list) {
buff.append(og.category);
buff.append("=");
buff.append(og.productCount);
buff.append(';');
}
String s = buff.toString();
assertEquals("Beverages=2;Condiments=5;Meat/Poultry=1;" +
"Produce=1;Seafood=1;", s);
assertEquals("[Beverages:2, Condiments:5, Meat/Poultry:1, Produce:1, Seafood:1]",
list.toString());
}
//## Java 1.5 end ##
......
......@@ -26,9 +26,9 @@ class Condition<A> implements Token {
public String getString(Query query) {
if (compareType.hasRightExpression()) {
return query.getString(x) + compareType.getString() + query.getString(y);
return query.getString(x) + " " + compareType.getString() + " " + query.getString(y);
}
return query.getString(x) + compareType.getString();
return query.getString(x) + " " + compareType.getString();
}
}
//## Java 1.5 end ##
......@@ -106,14 +106,6 @@ public class Db {
return def;
}
// private <T> T alias(Class<T> clazz) {
// TableDefinition def = define(clazz);
// T alias = instance(clazz);
// SelectTable table = new SelectTable(this, null, alias, false);
// def.initSelectObject(table, alias, aliasMap);
// return alias;
// }
public void close() {
try {
conn.close();
......@@ -122,6 +114,10 @@ public class Db {
}
}
public <A> TestCondition<A> test(A x) {
return new TestCondition<A>(x);
}
public <T> void insertAll(List<T> list) {
for (T t : list) {
insert(t);
......@@ -156,6 +152,14 @@ public class Db {
}
}
int executeUpdate(String sql) {
try {
return conn.createStatement().executeUpdate(sql);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
// <X> FieldDefinition<X> getFieldDefinition(X x) {
// return aliasMap.get(x).getFieldDefinition();
// }
......
......@@ -18,16 +18,25 @@ public class Function implements Token {
private static final Long COUNT_STAR = new Long(0);
protected Object[] x;
private String name;
private Object x;
private Function(String name, Object x) {
protected Function(String name, Object... x) {
this.name = name;
this.x = x;
}
public String getString(Query query) {
return name + "(" + query.getString(x) + ")";
StringBuilder buff = new StringBuilder();
buff.append(name).append('(');
for (int i = 0; i < x.length; i++) {
if (i > 0) {
buff.append(',');
}
buff.append(query.getString(x[i]));
}
buff.append(')');
return buff.toString();
}
public static Long count() {
......@@ -49,6 +58,63 @@ public class Function implements Token {
Utils.newObject(Long.class), new Function("COUNT", x));
}
public static Boolean isNull(Object x) {
return Db.registerToken(
Utils.newObject(Boolean.class), new Function("", x) {
public String getString(Query query) {
return query.getString(x[0]) + " IS NULL";
}
});
}
public static Boolean isNotNull(Object x) {
return Db.registerToken(
Utils.newObject(Boolean.class), new Function("", x) {
public String getString(Query query) {
return query.getString(x[0]) + " IS NOT NULL";
}
});
}
public static Boolean not(Boolean x) {
return Db.registerToken(
Utils.newObject(Boolean.class), new Function("", x) {
public String getString(Query query) {
return "NOT " + query.getString(x[0]);
}
});
}
public static Boolean or(Boolean... x) {
return Db.registerToken(Utils.newObject(Boolean.class), new Function("", (Object[]) x) {
public String getString(Query query) {
StringBuilder buff = new StringBuilder();
for (int i = 0; i < x.length; i++) {
if (i > 0) {
buff.append(" OR ");
}
buff.append(query.getString(x[i]));
}
return buff.toString();
}
});
}
public static Boolean and(Boolean... x) {
return Db.registerToken(Utils.newObject(Boolean.class), new Function("", (Object[]) x) {
public String getString(Query query) {
StringBuilder buff = new StringBuilder();
for (int i = 0; i < x.length; i++) {
if (i > 0) {
buff.append(" AND ");
}
buff.append(query.getString(x[i]));
}
return buff.toString();
}
});
}
public static <X> X min(X x) {
Class<X> clazz = (Class<X>) x.getClass();
X o = Utils.newObject(clazz);
......@@ -61,5 +127,14 @@ public class Function implements Token {
return Db.registerToken(o, new Function("MAX", x));
}
public static Boolean like(String x, String pattern) {
Boolean o = Utils.newObject(Boolean.class);
return Db.registerToken(o, new Function("LIKE", x, pattern) {
public String getString(Query query) {
return "(" + query.getString(x[0]) + " LIKE " + query.getString(x[1]) + ")";
}
});
}
//## Java 1.5 end ##
}
......@@ -68,6 +68,10 @@ public class Query<T> {
return list.isEmpty() ? null : list.get(0);
}
public String getSQL() {
return getSQL("*", false).trim();
}
private List<T> select(boolean distinct) {
List<T> result = Utils.newArrayList();
ResultSet rs = db.executeQuery(getSQL("*", distinct));
......@@ -83,6 +87,15 @@ public class Query<T> {
return result;
}
public int delete() {
StringBuilder buff = new StringBuilder();
buff.append("DELETE FROM ");
buff.append(from.getString());
buff.append(getSQLWhere());
String sql = buff.toString();
return db.executeUpdate(sql);
}
public <X, Z> List<X> selectDistinct(Z x) {
return select(x, true);
}
......@@ -139,6 +152,12 @@ public class Query<T> {
public <A> QueryCondition<T, A> where(A x) {
return new QueryCondition<T, A>(this, x);
}
public QueryWhere<T> whereTrue(Boolean condition) {
Token token = new Function("", condition);
addConditionToken(token);
return new QueryWhere<T>(this);
}
//## Java 1.5 end ##
/**
......@@ -188,6 +207,18 @@ public class Query<T> {
conditions.add(condition);
}
String getSQLWhere() {
StringBuilder buff = new StringBuilder("");
if (!conditions.isEmpty()) {
buff.append(" WHERE ");
for (Token token : conditions) {
buff.append(token.getString(this));
buff.append(' ');
}
}
return buff.toString();
}
String getSQL(String selectList, boolean distinct) {
StringBuilder buff = new StringBuilder("SELECT ");
if (distinct) {
......@@ -199,13 +230,7 @@ public class Query<T> {
for (SelectTable join : joins) {
buff.append(join.getStringAsJoin(this));
}
if (!conditions.isEmpty()) {
buff.append(" WHERE ");
for (Token token : conditions) {
buff.append(token.getString(this));
buff.append(' ');
}
}
buff.append(getSQLWhere());
if (groupByExpressions != null) {
buff.append(" GROUP BY ");
for (int i = 0; i < groupByExpressions.length; i++) {
......
......@@ -33,10 +33,25 @@ public class QueryCondition<T, A> {
return new QueryWhere<T>(query);
}
public QueryWhere<T> biggerEqual(A y) {
query.addConditionToken(new Condition<A>(query, x, y, CompareType.BIGGER_EQUAL));
return new QueryWhere<T>(query);
}
public QueryWhere<T> smaller(A y) {
query.addConditionToken(new Condition<A>(query, x, y, CompareType.SMALLER));
return new QueryWhere<T>(query);
}
public QueryWhere<T> smallerEqual(A y) {
query.addConditionToken(new Condition<A>(query, x, y, CompareType.SMALLER_EQUAL));
return new QueryWhere<T>(query);
}
public QueryWhere<T> like(A pattern) {
query.addConditionToken(new Condition<A>(query, x, pattern, CompareType.LIKE));
return new QueryWhere<T>(query);
}
}
//## Java 1.5 end ##
......@@ -38,6 +38,10 @@ public class QueryWhere<T> {
return (List<X>) query.select(x);
}
public String getSQL() {
return query.getSQL("*", false).trim();
}
public <X, Z> List<X> selectDistinct(Z x) {
return (List<X>) query.selectDistinct(x);
}
......@@ -108,5 +112,9 @@ public class QueryWhere<T> {
return this;
}
public int delete() {
return query.delete();
}
}
//## Java 1.5 end ##
......@@ -68,7 +68,7 @@ public class Utils {
} else if (clazz == Double.class) {
return (T) new Double(counter++);
} else if (clazz == Boolean.class) {
return (T) Boolean.FALSE;
return (T) new Boolean(false);
} else if (clazz == BigDecimal.class) {
return (T) new BigDecimal(counter++);
} else if (clazz == BigInteger.class) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论