提交 7fda2b32 authored 作者: Thomas Mueller's avatar Thomas Mueller

JaQu is now using prepared statements and supports Date, Time, Timestamp.

上级 fe741914
...@@ -23,30 +23,32 @@ import org.h2.jaqu.Table; ...@@ -23,30 +23,32 @@ import org.h2.jaqu.Table;
*/ */
//## Java 1.5 begin ## //## Java 1.5 begin ##
public class ComplexObject implements Table { public class ComplexObject implements Table {
Integer id; public Integer id;
Long amount; public Long amount;
String name; public String name;
BigDecimal value; public BigDecimal value;
Date birthday; public Date birthday;
Time time; public Time time;
Timestamp created; public Timestamp created;
static ComplexObject build(Integer id, boolean isNull) {
ComplexObject obj = new ComplexObject();
obj.id = id;
obj.amount = isNull ? null : new Long(1);
obj.name = isNull ? null : "hello";
obj.value = isNull ? null : new BigDecimal("1");
obj.birthday = isNull ? null : java.sql.Date.valueOf("2001-01-01");
obj.time = isNull ? null : Time.valueOf("10:20:30");
obj.created = isNull ? null : Timestamp.valueOf("2002-02-02 02:02:02");
return obj;
}
public void define() { public void define() {
primaryKey(id); primaryKey(id);
} }
public static List<ComplexObject> getList() { public static List<ComplexObject> getList() {
ComplexObject[] list = new ComplexObject[] { return Arrays.asList(new ComplexObject[] { build(0, true), build(1, false) });
// new Order("ALFKI", 10702, "330.00", "2007-01-02"),
// new Order("ALFKI", 10952, "471.20", "2007-02-03"),
// new Order("ANATR", 10308, "88.80", "2007-01-03"),
// new Order("ANATR", 10625, "479.75", "2007-03-03"),
// new Order("ANATR", 10759, "320.00", "2007-04-01"),
// new Order("ANTON", 10365, "403.20", "2007-02-13"),
// new Order("ANTON", 10682, "375.50", "2007-03-13"),
// new Order("ANTON", 10355, "480.00", "2007-04-11")
};
return Arrays.asList(list);
} }
} }
......
...@@ -33,7 +33,7 @@ public class Customer { ...@@ -33,7 +33,7 @@ public class Customer {
} }
//## Java 1.5 begin ## //## Java 1.5 begin ##
public static List<Customer> getCustomerList() { public static List<Customer> getList() {
Customer[] list = new Customer[] { Customer[] list = new Customer[] {
new Customer("ALFKI", "WA"), new Customer("ALFKI", "WA"),
new Customer("ANATR", "WA"), new Customer("ANATR", "WA"),
......
...@@ -45,7 +45,7 @@ public class Order implements Table { ...@@ -45,7 +45,7 @@ public class Order implements Table {
primaryKey(customerId, orderId); primaryKey(customerId, orderId);
} }
public static List<Order> getOrderList() { public static List<Order> getList() {
Order[] list = new Order[] { Order[] list = new Order[] {
new Order("ALFKI", 10702, "330.00", "2007-01-02"), new Order("ALFKI", 10702, "330.00", "2007-01-02"),
new Order("ALFKI", 10952, "471.20", "2007-02-03"), new Order("ALFKI", 10952, "471.20", "2007-02-03"),
......
...@@ -52,7 +52,7 @@ public class Product implements Table { ...@@ -52,7 +52,7 @@ public class Product implements Table {
unitPrice, unitsInStock); unitPrice, unitsInStock);
} }
public static List<Product> getProductList() { public static List<Product> getList() {
Product[] list = new Product[] { Product[] list = new Product[] {
create(1, "Chai", "Beverages", 18, 39), create(1, "Chai", "Beverages", 18, 39),
create(2, "Chang", "Beverages", 19.0, 17), create(2, "Chang", "Beverages", 19.0, 17),
......
...@@ -46,12 +46,12 @@ public class SamplesTest extends TestBase { ...@@ -46,12 +46,12 @@ public class SamplesTest extends TestBase {
public void test() throws Exception { public void test() throws Exception {
//## Java 1.5 begin ## //## Java 1.5 begin ##
db = Db.open("jdbc:h2:mem:", "sa", "sa"); db = Db.open("jdbc:h2:mem:", "sa", "sa");
db.insertAll(Product.getProductList()); db.insertAll(Product.getList());
db.insertAll(Customer.getCustomerList()); db.insertAll(Customer.getList());
db.insertAll(Order.getOrderList()); db.insertAll(Order.getList());
db.insertAll(ComplexObject.getList()); db.insertAll(ComplexObject.getList());
// TODO use prepared statements // TODO support JavaBeans specification
// TODO test all relevant data types (Date,...) // TODO support all relevant data types (byte[],...)
// TODO nested AND/OR, >, <,... // TODO nested AND/OR, >, <,...
// TODO NOT // TODO NOT
// TODO +, -, *, /, ||, nested operations // TODO +, -, *, /, ||, nested operations
...@@ -59,6 +59,7 @@ public class SamplesTest extends TestBase { ...@@ -59,6 +59,7 @@ public class SamplesTest extends TestBase {
// TODO UPDATE: FROM ... UPDATE? // TODO UPDATE: FROM ... UPDATE?
// TODO SELECT UNION // TODO SELECT UNION
// TODO DatabaseAdapter // TODO DatabaseAdapter
testComplexObject();
testOrAndNot(); testOrAndNot();
testDelete(); testDelete();
testIsNull(); testIsNull();
...@@ -142,7 +143,7 @@ public class SamplesTest extends TestBase { ...@@ -142,7 +143,7 @@ public class SamplesTest extends TestBase {
db.from(p). db.from(p).
orderBy(p.productId).select(p.productName); orderBy(p.productId).select(p.productName);
List<Product> products = Product.getProductList(); List<Product> products = Product.getList();
for (int i = 0; i < products.size(); i++) { for (int i = 0; i < products.size(); i++) {
assertEquals(products.get(i).productName, productNames.get(i)); assertEquals(products.get(i).productName, productNames.get(i));
} }
...@@ -178,7 +179,7 @@ public class SamplesTest extends TestBase { ...@@ -178,7 +179,7 @@ public class SamplesTest extends TestBase {
price = p.unitPrice; price = p.unitPrice;
}}); }});
List<Product> products = Product.getProductList(); List<Product> products = Product.getList();
assertEquals(products.size(), productInfos.size()); assertEquals(products.size(), productInfos.size());
for (int i = 0; i < products.size(); i++) { for (int i = 0; i < products.size(); i++) {
ProductPrice pr = productInfos.get(i); ProductPrice pr = productInfos.get(i);
...@@ -243,7 +244,7 @@ public class SamplesTest extends TestBase { ...@@ -243,7 +244,7 @@ public class SamplesTest extends TestBase {
assertEquals(1, deleted); assertEquals(1, deleted);
deleted = db.from(p).delete(); deleted = db.from(p).delete();
assertEquals(9, deleted); assertEquals(9, deleted);
db.insertAll(Product.getProductList()); db.insertAll(Product.getList());
} }
private void testOrAndNot() throws Exception { private void testOrAndNot() throws Exception {
...@@ -253,7 +254,7 @@ public class SamplesTest extends TestBase { ...@@ -253,7 +254,7 @@ public class SamplesTest extends TestBase {
sql = db.from(p).whereTrue(not(isNull(p.productName))).getSQL(); sql = db.from(p).whereTrue(not(isNull(p.productName))).getSQL();
assertEquals("SELECT * FROM Product WHERE (NOT productName IS NULL)", sql); assertEquals("SELECT * FROM Product WHERE (NOT productName IS NULL)", sql);
sql = db.from(p).whereTrue(db.test(p.productId).is(1)).getSQL(); sql = db.from(p).whereTrue(db.test(p.productId).is(1)).getSQL();
assertEquals("SELECT * FROM Product WHERE ((productId = 1))", sql); assertEquals("SELECT * FROM Product WHERE ((productId = ?))", sql);
} }
private void testLength() throws Exception { private void testLength() throws Exception {
...@@ -296,6 +297,20 @@ public class SamplesTest extends TestBase { ...@@ -296,6 +297,20 @@ public class SamplesTest extends TestBase {
assertEquals(10, count); assertEquals(10, count);
} }
private void testComplexObject() throws Exception {
ComplexObject co = new ComplexObject();
long count = db.from(co).
where(co.id).is(1).
and(co.amount).is(1L).
and(co.birthday).smaller(new java.util.Date()).
and(co.created).smaller(java.sql.Timestamp.valueOf("2005-05-05 05:05:05")).
and(co.name).is("hello").
and(co.time).smaller(java.sql.Time.valueOf("23:23:23")).
and(co.value).is(new BigDecimal("1")).
selectCount();
assertEquals(1, count);
}
//## Java 1.5 end ## //## Java 1.5 end ##
/** /**
......
...@@ -24,12 +24,13 @@ class Condition<A> implements Token { ...@@ -24,12 +24,13 @@ class Condition<A> implements Token {
this.y = y; this.y = y;
} }
public String getString(Query query) { public void appendSQL(SqlStatement stat, Query query) {
query.appendSQL(stat, x);
stat.appendSQL(" ");
stat.appendSQL(compareType.getString());
if (compareType.hasRightExpression()) { if (compareType.hasRightExpression()) {
return query.getString(x) + " " + query.appendSQL(stat, y);
compareType.getString() + " " + query.getString(y);
} }
return query.getString(x) + " " + compareType.getString();
} }
} }
//## Java 1.5 end ## //## Java 1.5 end ##
...@@ -20,8 +20,8 @@ enum ConditionAndOr implements Token { ...@@ -20,8 +20,8 @@ enum ConditionAndOr implements Token {
this.text = text; this.text = text;
} }
public String getString(Query query) { public void appendSQL(SqlStatement stat, Query query) {
return text; stat.appendSQL(text);
} }
} }
......
...@@ -124,14 +124,6 @@ public class Db { ...@@ -124,14 +124,6 @@ public class Db {
} }
} }
void execute(String sql) {
try {
conn.createStatement().execute(sql);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
PreparedStatement prepare(String sql) { PreparedStatement prepare(String sql) {
try { try {
return conn.prepareStatement(sql); return conn.prepareStatement(sql);
......
...@@ -26,17 +26,16 @@ public class Function implements Token { ...@@ -26,17 +26,16 @@ public class Function implements Token {
this.x = x; this.x = x;
} }
public String getString(Query query) { public void appendSQL(SqlStatement stat, Query query) {
StringBuilder buff = new StringBuilder(); stat.appendSQL(name);
buff.append(name).append('('); stat.appendSQL("(");
for (int i = 0; i < x.length; i++) { for (int i = 0; i < x.length; i++) {
if (i > 0) { if (i > 0) {
buff.append(','); stat.appendSQL(",");
} }
buff.append(query.getString(x[i])); query.appendSQL(stat, x[i]);
} }
buff.append(')'); stat.appendSQL(")");
return buff.toString();
} }
public static Long count() { public static Long count() {
...@@ -61,8 +60,9 @@ public class Function implements Token { ...@@ -61,8 +60,9 @@ public class Function implements Token {
public static Boolean isNull(Object x) { public static Boolean isNull(Object x) {
return Db.registerToken( return Db.registerToken(
Utils.newObject(Boolean.class), new Function("", x) { Utils.newObject(Boolean.class), new Function("", x) {
public String getString(Query query) { public void appendSQL(SqlStatement stat, Query query) {
return query.getString(x[0]) + " IS NULL"; query.appendSQL(stat, x[0]);
stat.appendSQL(" IS NULL");
} }
}); });
} }
...@@ -70,8 +70,9 @@ public class Function implements Token { ...@@ -70,8 +70,9 @@ public class Function implements Token {
public static Boolean isNotNull(Object x) { public static Boolean isNotNull(Object x) {
return Db.registerToken( return Db.registerToken(
Utils.newObject(Boolean.class), new Function("", x) { Utils.newObject(Boolean.class), new Function("", x) {
public String getString(Query query) { public void appendSQL(SqlStatement stat, Query query) {
return query.getString(x[0]) + " IS NOT NULL"; query.appendSQL(stat, x[0]);
stat.appendSQL(" IS NOT NULL");
} }
}); });
} }
...@@ -79,8 +80,9 @@ public class Function implements Token { ...@@ -79,8 +80,9 @@ public class Function implements Token {
public static Boolean not(Boolean x) { public static Boolean not(Boolean x) {
return Db.registerToken( return Db.registerToken(
Utils.newObject(Boolean.class), new Function("", x) { Utils.newObject(Boolean.class), new Function("", x) {
public String getString(Query query) { public void appendSQL(SqlStatement stat, Query query) {
return "NOT " + query.getString(x[0]); stat.appendSQL("NOT ");
query.appendSQL(stat, x[0]);
} }
}); });
} }
...@@ -89,15 +91,13 @@ public class Function implements Token { ...@@ -89,15 +91,13 @@ public class Function implements Token {
return Db.registerToken( return Db.registerToken(
Utils.newObject(Boolean.class), Utils.newObject(Boolean.class),
new Function("", (Object[]) x) { new Function("", (Object[]) x) {
public String getString(Query query) { public void appendSQL(SqlStatement stat, Query query) {
StringBuilder buff = new StringBuilder();
for (int i = 0; i < x.length; i++) { for (int i = 0; i < x.length; i++) {
if (i > 0) { if (i > 0) {
buff.append(" OR "); stat.appendSQL(" OR ");
} }
buff.append(query.getString(x[i])); query.appendSQL(stat, x[i]);
} }
return buff.toString();
} }
}); });
} }
...@@ -106,15 +106,13 @@ public class Function implements Token { ...@@ -106,15 +106,13 @@ public class Function implements Token {
return Db.registerToken( return Db.registerToken(
Utils.newObject(Boolean.class), Utils.newObject(Boolean.class),
new Function("", (Object[]) x) { new Function("", (Object[]) x) {
public String getString(Query query) { public void appendSQL(SqlStatement stat, Query query) {
StringBuilder buff = new StringBuilder();
for (int i = 0; i < x.length; i++) { for (int i = 0; i < x.length; i++) {
if (i > 0) { if (i > 0) {
buff.append(" AND "); stat.appendSQL(" AND ");
} }
buff.append(query.getString(x[i])); query.appendSQL(stat, x[i]);
} }
return buff.toString();
} }
}); });
} }
...@@ -134,8 +132,12 @@ public class Function implements Token { ...@@ -134,8 +132,12 @@ public class Function implements Token {
public static Boolean like(String x, String pattern) { public static Boolean like(String x, String pattern) {
Boolean o = Utils.newObject(Boolean.class); Boolean o = Utils.newObject(Boolean.class);
return Db.registerToken(o, new Function("LIKE", x, pattern) { return Db.registerToken(o, new Function("LIKE", x, pattern) {
public String getString(Query query) { public void appendSQL(SqlStatement stat, Query query) {
return "(" + query.getString(x[0]) + " LIKE " + query.getString(x[1]) + ")"; stat.appendSQL("(");
query.appendSQL(stat, x[0]);
stat.appendSQL(" LIKE ");
query.appendSQL(stat, x[1]);
stat.appendSQL(")");
} }
}); });
} }
......
...@@ -28,19 +28,17 @@ class OrderExpression<T> { ...@@ -28,19 +28,17 @@ class OrderExpression<T> {
this.nullsLast = nullsLast; this.nullsLast = nullsLast;
} }
String getString() { void appendSQL(SqlStatement stat) {
StringBuilder buff = new StringBuilder(); query.appendSQL(stat, expression);
buff.append(query.getString(expression));
if (desc) { if (desc) {
buff.append(" DESC"); stat.appendSQL(" DESC");
} }
if (nullsLast) { if (nullsLast) {
buff.append(" NULLS LAST"); stat.appendSQL(" NULLS LAST");
} }
if (nullsFirst) { if (nullsFirst) {
buff.append(" NULLS FIRST"); stat.appendSQL(" NULLS FIRST");
} }
return buff.toString();
} }
} }
......
...@@ -45,7 +45,9 @@ public class Query<T> { ...@@ -45,7 +45,9 @@ public class Query<T> {
} }
public long selectCount() { public long selectCount() {
ResultSet rs = db.executeQuery(getSQL("COUNT(*)", false)); SqlStatement selectList = new SqlStatement(db);
selectList.setSQL("COUNT(*)");
ResultSet rs = prepare(selectList, false).executeQuery();
try { try {
rs.next(); rs.next();
long value = rs.getLong(1); long value = rs.getLong(1);
...@@ -69,12 +71,16 @@ public class Query<T> { ...@@ -69,12 +71,16 @@ public class Query<T> {
} }
public String getSQL() { public String getSQL() {
return getSQL("*", false).trim(); SqlStatement selectList = new SqlStatement(db);
selectList.setSQL("*");
return prepare(selectList, false).getSQL().trim();
} }
private List<T> select(boolean distinct) { private List<T> select(boolean distinct) {
List<T> result = Utils.newArrayList(); List<T> result = Utils.newArrayList();
ResultSet rs = db.executeQuery(getSQL("*", distinct)); SqlStatement selectList = new SqlStatement(db);
selectList.setSQL("*");
ResultSet rs = prepare(selectList, distinct).executeQuery();
try { try {
while (rs.next()) { while (rs.next()) {
T item = from.newObject(); T item = from.newObject();
...@@ -88,12 +94,11 @@ public class Query<T> { ...@@ -88,12 +94,11 @@ public class Query<T> {
} }
public int delete() { public int delete() {
StringBuilder buff = new StringBuilder(); SqlStatement stat = new SqlStatement(db);
buff.append("DELETE FROM "); stat.appendSQL("DELETE FROM ");
buff.append(from.getString()); from.appendSQL(stat);
buff.append(getSQLWhere()); appendWhere(stat);
String sql = buff.toString(); return stat.executeUpdate();
return db.executeUpdate(sql);
} }
public <X, Z> List<X> selectDistinct(Z x) { public <X, Z> List<X> selectDistinct(Z x) {
...@@ -115,8 +120,8 @@ public class Query<T> { ...@@ -115,8 +120,8 @@ public class Query<T> {
private <X> List<X> select(Class<X> clazz, X x, boolean distinct) { private <X> List<X> select(Class<X> clazz, X x, boolean distinct) {
TableDefinition<X> def = db.define(clazz); TableDefinition<X> def = db.define(clazz);
String selectList = def.getSelectList(this, x); SqlStatement selectList = def.getSelectList(this, x);
ResultSet rs = db.executeQuery(getSQL(selectList, distinct)); ResultSet rs = prepare(selectList, distinct).executeQuery();
List<X> result = Utils.newArrayList(); List<X> result = Utils.newArrayList();
try { try {
while (rs.next()) { while (rs.next()) {
...@@ -131,8 +136,9 @@ public class Query<T> { ...@@ -131,8 +136,9 @@ public class Query<T> {
} }
private <X> List<X> getSimple(X x, boolean distinct) { private <X> List<X> getSimple(X x, boolean distinct) {
String selectList = getString(x); SqlStatement selectList = new SqlStatement(db);
ResultSet rs = db.executeQuery(getSQL(selectList, distinct)); appendSQL(selectList, x);
ResultSet rs = prepare(selectList, distinct).executeQuery();
List<X> result = Utils.newArrayList(); List<X> result = Utils.newArrayList();
try { try {
while (rs.next()) { while (rs.next()) {
...@@ -188,72 +194,77 @@ public class Query<T> { ...@@ -188,72 +194,77 @@ public class Query<T> {
return this; return this;
} }
String getString(Object x) { void appendSQL(SqlStatement stat, Object x) {
if (x == Function.count()) { if (x == Function.count()) {
return "COUNT(*)"; stat.appendSQL("COUNT(*)");
return;
} }
Token token = Db.getToken(x); Token token = Db.getToken(x);
if (token != null) { if (token != null) {
return token.getString(this); token.appendSQL(stat, this);
return;
} }
SelectColumn col = aliasMap.get(x); SelectColumn col = aliasMap.get(x);
if (col != null) { if (col != null) {
return col.getString(); col.appendSQL(stat);
return;
} }
return Utils.quoteSQL(x); stat.appendSQL("?");
stat.addParameter(x);
} }
void addConditionToken(Token condition) { void addConditionToken(Token condition) {
conditions.add(condition); conditions.add(condition);
} }
String getSQLWhere() { void appendWhere(SqlStatement stat) {
StringBuilder buff = new StringBuilder("");
if (!conditions.isEmpty()) { if (!conditions.isEmpty()) {
buff.append(" WHERE "); stat.appendSQL(" WHERE ");
for (Token token : conditions) { for (Token token : conditions) {
buff.append(token.getString(this)); token.appendSQL(stat, this);
buff.append(' '); stat.appendSQL(" ");
} }
} }
return buff.toString();
} }
String getSQL(String selectList, boolean distinct) { SqlStatement prepare(SqlStatement selectList, boolean distinct) {
StringBuilder buff = new StringBuilder("SELECT "); SqlStatement stat = selectList;
String selectSQL = stat.getSQL();
stat.setSQL("");
stat.appendSQL("SELECT ");
if (distinct) { if (distinct) {
buff.append("DISTINCT "); stat.appendSQL("DISTINCT ");
} }
buff.append(selectList); stat.appendSQL(selectSQL);
buff.append(" FROM "); stat.appendSQL(" FROM ");
buff.append(from.getString()); from.appendSQL(stat);
for (SelectTable join : joins) { for (SelectTable join : joins) {
buff.append(join.getStringAsJoin(this)); join.appendSQLAsJoin(stat, this);
} }
buff.append(getSQLWhere()); appendWhere(stat);
if (groupByExpressions != null) { if (groupByExpressions != null) {
buff.append(" GROUP BY "); stat.appendSQL(" GROUP BY ");
for (int i = 0; i < groupByExpressions.length; i++) { for (int i = 0; i < groupByExpressions.length; i++) {
if (i > 0) { if (i > 0) {
buff.append(", "); stat.appendSQL(", ");
} }
Object obj = groupByExpressions[i]; Object obj = groupByExpressions[i];
buff.append(getString(obj)); appendSQL(stat, obj);
buff.append(' '); stat.appendSQL(" ");
} }
} }
if (!orderByList.isEmpty()) { if (!orderByList.isEmpty()) {
buff.append(" ORDER BY "); stat.appendSQL(" ORDER BY ");
for (int i = 0; i < orderByList.size(); i++) { for (int i = 0; i < orderByList.size(); i++) {
if (i > 0) { if (i > 0) {
buff.append(", "); stat.appendSQL(", ");
} }
OrderExpression o = orderByList.get(i); OrderExpression o = orderByList.get(i);
buff.append(o.getString()); o.appendSQL(stat);
buff.append(' '); stat.appendSQL(" ");
} }
} }
return buff.toString(); return stat;
} }
//## Java 1.5 end ## //## Java 1.5 end ##
......
...@@ -39,7 +39,9 @@ public class QueryWhere<T> { ...@@ -39,7 +39,9 @@ public class QueryWhere<T> {
} }
public String getSQL() { public String getSQL() {
return query.getSQL("*", false).trim(); SqlStatement selectList = new SqlStatement(query.getDb());
selectList.appendSQL("*");
return query.prepare(selectList, false).getSQL().trim();
} }
public <X, Z> List<X> selectDistinct(Z x) { public <X, Z> List<X> selectDistinct(Z x) {
...@@ -116,5 +118,9 @@ public class QueryWhere<T> { ...@@ -116,5 +118,9 @@ public class QueryWhere<T> {
return query.delete(); return query.delete();
} }
public long selectCount() {
return query.selectCount();
}
} }
//## Java 1.5 end ## //## Java 1.5 end ##
...@@ -25,11 +25,12 @@ class SelectColumn<X> { ...@@ -25,11 +25,12 @@ class SelectColumn<X> {
this.fieldDef = fieldDef; this.fieldDef = fieldDef;
} }
String getString() { void appendSQL(SqlStatement stat) {
if (selectTable.getQuery().isJoin()) { if (selectTable.getQuery().isJoin()) {
return selectTable.getAs() + "." + fieldDef.columnName; stat.appendSQL(selectTable.getAs() + "." + fieldDef.columnName);
} else {
stat.appendSQL(fieldDef.columnName);
} }
return fieldDef.columnName;
} }
FieldDefinition<X> getFieldDefinition() { FieldDefinition<X> getFieldDefinition() {
......
...@@ -46,29 +46,28 @@ class SelectTable <T> { ...@@ -46,29 +46,28 @@ class SelectTable <T> {
return aliasDef; return aliasDef;
} }
String getString() { void appendSQL(SqlStatement stat) {
if (query.isJoin()) { if (query.isJoin()) {
return aliasDef.tableName + " AS " + as; stat.appendSQL(aliasDef.tableName + " AS " + as);
} else {
stat.appendSQL(aliasDef.tableName);
} }
return aliasDef.tableName;
} }
String getStringAsJoin(Query query) { void appendSQLAsJoin(SqlStatement stat, Query query) {
StringBuilder buff = new StringBuilder();
if (outerJoin) { if (outerJoin) {
buff.append(" LEFT OUTER JOIN "); stat.appendSQL(" LEFT OUTER JOIN ");
} else { } else {
buff.append(" INNER JOIN "); stat.appendSQL(" INNER JOIN ");
} }
buff.append(getString()); appendSQL(stat);
if (!joinConditions.isEmpty()) { if (!joinConditions.isEmpty()) {
buff.append(" ON "); stat.appendSQL(" ON ");
for (Token token : joinConditions) { for (Token token : joinConditions) {
buff.append(token.getString(query)); token.appendSQL(stat, query);
buff.append(' '); stat.appendSQL(" ");
} }
} }
return buff.toString();
} }
boolean getOuterJoin() { boolean getOuterJoin() {
......
/*
* Copyright 2004-2008 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.jaqu;
//## Java 1.5 begin ##
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
//## Java 1.5 end ##
/**
* This class represents a parameterized SQL statement.
*/
//## Java 1.5 begin ##
public class SqlStatement {
private Db db;
private String sql = "";
private ArrayList params = new ArrayList();
SqlStatement(Db db) {
this.db = db;
}
void setSQL(String sql) {
this.sql = sql;
}
void appendSQL(String s) {
sql += s;
}
String getSQL() {
return sql;
}
void addParameter(Object o) {
params.add(o);
}
ResultSet executeQuery() {
try {
return prepare().executeQuery();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
int executeUpdate() {
try {
return prepare().executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
private void setValue(PreparedStatement prep, int parameterIndex, Object x) {
try {
prep.setObject(parameterIndex, x);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
private PreparedStatement prepare() {
PreparedStatement prep = db.prepare(sql);
for (int i = 0; i < params.size(); i++) {
Object o = params.get(i);
setValue(prep, i + 1, o);
}
return prep;
}
}
//## Java 1.5 end ##
...@@ -8,7 +8,6 @@ package org.h2.jaqu; ...@@ -8,7 +8,6 @@ package org.h2.jaqu;
//## Java 1.5 begin ## //## Java 1.5 begin ##
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -16,7 +15,6 @@ import java.util.IdentityHashMap; ...@@ -16,7 +15,6 @@ import java.util.IdentityHashMap;
import java.util.Map; import java.util.Map;
import org.h2.jaqu.util.Utils; import org.h2.jaqu.util.Utils;
//## Java 1.5 end ##
/** /**
* A table definition contains the index definitions of a table, the field * A table definition contains the index definitions of a table, the field
...@@ -157,6 +155,7 @@ class TableDefinition<T> { ...@@ -157,6 +155,7 @@ class TableDefinition<T> {
} }
void insert(Db db, Object obj) { void insert(Db db, Object obj) {
SqlStatement stat = new SqlStatement(db);
StringBuilder buff = new StringBuilder("INSERT INTO "); StringBuilder buff = new StringBuilder("INSERT INTO ");
buff.append(tableName); buff.append(tableName);
buff.append(" VALUES("); buff.append(" VALUES(");
...@@ -165,31 +164,17 @@ class TableDefinition<T> { ...@@ -165,31 +164,17 @@ class TableDefinition<T> {
buff.append(", "); buff.append(", ");
} }
buff.append('?'); buff.append('?');
}
buff.append(')');
String sql = buff.toString();
PreparedStatement prep = db.prepare(sql);
for (int i = 0; i < fields.size(); i++) {
FieldDefinition field = fields.get(i); FieldDefinition field = fields.get(i);
Object value = field.getValue(obj); Object value = field.getValue(obj);
setValue(prep, i + 1, value); stat.addParameter(value);
} }
try { buff.append(')');
prep.execute(); stat.setSQL(buff.toString());
} catch (SQLException e) { stat.executeUpdate();
throw new RuntimeException(e);
}
}
private void setValue(PreparedStatement prep, int parameterIndex, Object x) {
try {
prep.setObject(parameterIndex, x);
} catch (SQLException e) {
throw new RuntimeException(e);
}
} }
TableDefinition createTableIfRequired(Db db) { TableDefinition createTableIfRequired(Db db) {
SqlStatement stat = new SqlStatement(db);
StringBuilder buff = new StringBuilder("CREATE TABLE IF NOT EXISTS "); StringBuilder buff = new StringBuilder("CREATE TABLE IF NOT EXISTS ");
buff.append(tableName); buff.append(tableName);
buff.append('('); buff.append('(');
...@@ -213,7 +198,8 @@ class TableDefinition<T> { ...@@ -213,7 +198,8 @@ class TableDefinition<T> {
buff.append(')'); buff.append(')');
} }
buff.append(')'); buff.append(')');
db.execute(buff.toString()); stat.setSQL(buff.toString());
stat.executeUpdate();
// TODO create indexes // TODO create indexes
return this; return this;
} }
...@@ -247,18 +233,17 @@ class TableDefinition<T> { ...@@ -247,18 +233,17 @@ class TableDefinition<T> {
} }
} }
<X> String getSelectList(Query query, X x) { <X> SqlStatement getSelectList(Query query, X x) {
StringBuilder buff = new StringBuilder(); SqlStatement selectList = new SqlStatement(query.getDb());
for (int i = 0; i < fields.size(); i++) { for (int i = 0; i < fields.size(); i++) {
if (i > 0) { if (i > 0) {
buff.append(", "); selectList.appendSQL(", ");
} }
FieldDefinition def = fields.get(i); FieldDefinition def = fields.get(i);
Object obj = def.getValue(x); Object obj = def.getValue(x);
String s = query.getString(obj); query.appendSQL(selectList, obj);
buff.append(s);
} }
return buff.toString(); return selectList;
} }
<U, X> void copyAttributeValues(Query query, X to, X map) { <U, X> void copyAttributeValues(Query query, X to, X map) {
......
...@@ -25,8 +25,12 @@ public class TestCondition<A> { ...@@ -25,8 +25,12 @@ public class TestCondition<A> {
public Boolean is(A y) { public Boolean is(A y) {
Boolean o = Utils.newObject(Boolean.class); Boolean o = Utils.newObject(Boolean.class);
return Db.registerToken(o, new Function("=", x, y) { return Db.registerToken(o, new Function("=", x, y) {
public String getString(Query query) { public void appendSQL(SqlStatement stat, Query query) {
return "(" + query.getString(x[0]) + " = " + query.getString(x[1]) + ")"; stat.appendSQL("(");
query.appendSQL(stat, x[0]);
stat.appendSQL(" = ");
query.appendSQL(stat, x[1]);
stat.appendSQL(")");
} }
}); });
} }
...@@ -34,8 +38,12 @@ public class TestCondition<A> { ...@@ -34,8 +38,12 @@ public class TestCondition<A> {
public Boolean bigger(A y) { public Boolean bigger(A y) {
Boolean o = Utils.newObject(Boolean.class); Boolean o = Utils.newObject(Boolean.class);
return Db.registerToken(o, new Function(">", x, y) { return Db.registerToken(o, new Function(">", x, y) {
public String getString(Query query) { public void appendSQL(SqlStatement stat, Query query) {
return "(" + query.getString(x[0]) + " > " + query.getString(x[1]) + ")"; stat.appendSQL("(");
query.appendSQL(stat, x[0]);
stat.appendSQL(" > ");
query.appendSQL(stat, x[1]);
stat.appendSQL(")");
} }
}); });
} }
...@@ -43,8 +51,12 @@ public class TestCondition<A> { ...@@ -43,8 +51,12 @@ public class TestCondition<A> {
public Boolean biggerEqual(A y) { public Boolean biggerEqual(A y) {
Boolean o = Utils.newObject(Boolean.class); Boolean o = Utils.newObject(Boolean.class);
return Db.registerToken(o, new Function(">=", x, y) { return Db.registerToken(o, new Function(">=", x, y) {
public String getString(Query query) { public void appendSQL(SqlStatement stat, Query query) {
return "(" + query.getString(x[0]) + " >= " + query.getString(x[1]) + ")"; stat.appendSQL("(");
query.appendSQL(stat, x[0]);
stat.appendSQL(" >= ");
query.appendSQL(stat, x[1]);
stat.appendSQL(")");
} }
}); });
} }
...@@ -52,8 +64,12 @@ public class TestCondition<A> { ...@@ -52,8 +64,12 @@ public class TestCondition<A> {
public Boolean smaller(A y) { public Boolean smaller(A y) {
Boolean o = Utils.newObject(Boolean.class); Boolean o = Utils.newObject(Boolean.class);
return Db.registerToken(o, new Function("<", x, y) { return Db.registerToken(o, new Function("<", x, y) {
public String getString(Query query) { public void appendSQL(SqlStatement stat, Query query) {
return "(" + query.getString(x[0]) + " < " + query.getString(x[1]) + ")"; stat.appendSQL("(");
query.appendSQL(stat, x[0]);
stat.appendSQL(" < ");
query.appendSQL(stat, x[1]);
stat.appendSQL(")");
} }
}); });
} }
...@@ -61,8 +77,12 @@ public class TestCondition<A> { ...@@ -61,8 +77,12 @@ public class TestCondition<A> {
public Boolean smallerEqual(A y) { public Boolean smallerEqual(A y) {
Boolean o = Utils.newObject(Boolean.class); Boolean o = Utils.newObject(Boolean.class);
return Db.registerToken(o, new Function("<=", x, y) { return Db.registerToken(o, new Function("<=", x, y) {
public String getString(Query query) { public void appendSQL(SqlStatement stat, Query query) {
return "(" + query.getString(x[0]) + " <= " + query.getString(x[1]) + ")"; stat.appendSQL("(");
query.appendSQL(stat, x[0]);
stat.appendSQL(" <= ");
query.appendSQL(stat, x[1]);
stat.appendSQL(")");
} }
}); });
} }
...@@ -70,8 +90,12 @@ public class TestCondition<A> { ...@@ -70,8 +90,12 @@ public class TestCondition<A> {
public Boolean like(A pattern) { public Boolean like(A pattern) {
Boolean o = Utils.newObject(Boolean.class); Boolean o = Utils.newObject(Boolean.class);
return Db.registerToken(o, new Function("LIKE", x, pattern) { return Db.registerToken(o, new Function("LIKE", x, pattern) {
public String getString(Query query) { public void appendSQL(SqlStatement stat, Query query) {
return "(" + query.getString(x[0]) + " LIKE " + query.getString(x[1]) + ")"; stat.appendSQL("(");
query.appendSQL(stat, x[0]);
stat.appendSQL(" LIKE ");
query.appendSQL(stat, x[1]);
stat.appendSQL(")");
} }
}); });
} }
......
...@@ -11,6 +11,6 @@ package org.h2.jaqu; ...@@ -11,6 +11,6 @@ package org.h2.jaqu;
*/ */
interface Token { interface Token {
//## Java 1.5 begin ## //## Java 1.5 begin ##
String getString(Query query); void appendSQL(SqlStatement stat, Query query);
//## Java 1.5 end ## //## Java 1.5 end ##
} }
...@@ -16,8 +16,6 @@ import java.util.HashMap; ...@@ -16,8 +16,6 @@ import java.util.HashMap;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.h2.util.StringUtils;
//## Java 1.5 end ## //## Java 1.5 end ##
/** /**
...@@ -73,6 +71,14 @@ public class Utils { ...@@ -73,6 +71,14 @@ public class Utils {
return (T) new BigDecimal(counter++); return (T) new BigDecimal(counter++);
} else if (clazz == BigInteger.class) { } else if (clazz == BigInteger.class) {
return (T) new BigInteger("" + counter++); return (T) new BigInteger("" + counter++);
} else if (clazz == java.sql.Date.class) {
return (T) new java.sql.Date(counter++);
} else if (clazz == java.sql.Time.class) {
return (T) new java.sql.Time(counter++);
} else if (clazz == java.sql.Timestamp.class) {
return (T) new java.sql.Timestamp(counter++);
} else if (clazz == java.util.Date.class) {
return (T) new java.util.Date(counter++);
} else if (clazz == List.class) { } else if (clazz == List.class) {
return (T) new ArrayList(); return (T) new ArrayList();
} }
...@@ -109,16 +115,6 @@ public class Utils { ...@@ -109,16 +115,6 @@ public class Utils {
} }
} }
public static String quoteSQL(Object x) {
if (x == null) {
return "NULL";
}
if (x instanceof String) {
return StringUtils.quoteStringSQL((String) x);
}
return x.toString();
}
public static <T> boolean isSimpleType(Class<T> clazz) { public static <T> boolean isSimpleType(Class<T> clazz) {
if (Number.class.isAssignableFrom(clazz)) { if (Number.class.isAssignableFrom(clazz)) {
return true; return true;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论