提交 38ca69e9 authored 作者: Thomas Mueller's avatar Thomas Mueller

integrate jaqu (java query)

上级 803781b5
......@@ -3,8 +3,9 @@
This configuration file was written by the eclipse-cs plugin configuration editor
-->
<!--
Checkstyle-Configuration: MyCheckstyle
Description: none
Checkstyle-Configuration: Checkstyle
Description:
Checkstyle Configuration
-->
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.2//EN" "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
<module name="Checker">
......@@ -31,13 +32,13 @@
</module>
<module name="NoWhitespaceBefore"/>
<module name="OperatorWrap">
<property name="tokens" value="BAND,BOR,BSR,BXOR,COLON,DIV,EQUAL,GE,GT,LAND,LE,LITERAL_INSTANCEOF,LOR,LT,MINUS,MOD,NOT_EQUAL,QUESTION,SL,SR,STAR"/>
<property name="tokens" value="BAND,BOR,BSR,BXOR,COLON,DIV,EQUAL,GE,GT,LAND,LE,LITERAL_INSTANCEOF,LOR,LT,MINUS,MOD,NOT_EQUAL,SL,SR,STAR"/>
</module>
<module name="ParenPad"/>
<module name="TabCharacter"/>
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround">
<property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV_ASSIGN,EQUAL,GE,GT,LAND,LCURLY,LE,LITERAL_ASSERT,LITERAL_CATCH,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_RETURN,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS_ASSIGN,QUESTION,RCURLY,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND,WILDCARD_TYPE"/>
<property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,DIV_ASSIGN,EQUAL,GE,GT,LAND,LE,LITERAL_ASSERT,LITERAL_CATCH,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_RETURN,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS_ASSIGN,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND,WILDCARD_TYPE"/>
</module>
<module name="ModifierOrder"/>
<module name="RedundantModifier"/>
......
package org.h2.test.jaqu;
//## Java 1.6 begin ##
import java.util.Arrays;
import java.util.List;
//## Java 1.6 end ##
/**
* A table containing customer data.
*/
public class Customer {
public String customerId;
public String region;
public Customer() {
// public constructor
}
public Customer(String customerId, String region) {
this.customerId = customerId;
this.region = region;
}
//## Java 1.6 begin ##
public static List<Customer> getCustomerList() {
Customer[] list = new Customer[] {
new Customer("ALFKI", "WA"),
new Customer("ANATR", "WA"),
new Customer("ANTON", "CA") };
return Arrays.asList(list);
}
//## Java 1.6 end ##
}
package org.h2.test.jaqu;
//## Java 1.6 begin ##
import static org.h2.jaqu.Define.*;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.h2.jaqu.Table;
//## Java 1.6 end ##
/**
* A table containing order data.
*/
//## Java 1.6 begin ##
public class Order implements Table {
public String customerId;
public Integer orderId;
public Date orderDate;
public BigDecimal total;
public Order(String customerId, Integer orderId, String total, String orderDate) {
this.customerId = customerId;
this.orderId = orderId;
this.total = new BigDecimal(total);
this.orderDate = java.sql.Date.valueOf(orderDate);
}
public Order() {
// public constructor
}
public void define() {
tableName("Orders");
primaryKey(customerId, orderId);
}
public static List<Order> getOrderList() {
Order[] list = new Order[] {
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);
}
}
//## Java 1.6 end ##
package org.h2.test.jaqu;
//## Java 1.6 begin ##
import java.util.Arrays;
import java.util.List;
import org.h2.jaqu.Table;
import static org.h2.jaqu.Define.*;
/**
* A table containing product data.
*/
//## Java 1.6 begin ##
public class Product implements Table {
public Integer productId;
public String productName;
public String category;
public Double unitPrice;
public Integer unitsInStock;
public Product() {
// public constructor
}
private Product(int productId, String productName, String category, double unitPrice, int unitsInStock) {
this.productId = productId;
this.productName = productName;
this.category = category;
this.unitPrice = unitPrice;
this.unitsInStock = unitsInStock;
}
public void define() {
tableName("Product");
primaryKey(productId);
index(productName, category);
}
private static Product create(int productId, String productName, String category, double unitPrice, int unitsInStock) {
return new Product(productId, productName, category, unitPrice, unitsInStock);
}
public static List<Product> getProductList() {
Product[] list = new Product[] {
create(1, "Chai", "Beverages", 18, 39),
create(2, "Chang", "Beverages", 19.0, 17),
create(3, "Aniseed Syrup", "Condiments", 10.0, 13),
create(4, "Chef Anton's Cajun Seasoning", "Condiments", 22.0, 53),
create(5, "Chef Anton's Gumbo Mix", "Condiments", 21.3500, 0),
create(6, "Grandma's Boysenberry Spread", "Condiments", 25.0, 120),
create(7, "Uncle Bob's Organic Dried Pears", "Produce", 30.0, 15),
create(8, "Northwoods Cranberry Sauce", "Condiments", 40.0, 6),
create(9, "Mishi Kobe Niku", "Meat/Poultry", 97.0, 29),
create(10, "Ikura", "Seafood", 31.0, 31),
create(11, "Queso Cabrales", "Dairy Products", 21.0, 22),
create(12, "Queso Manchego La Pastora", "Dairy Products", 38.0, 86),
create(13, "Konbu", "Seafood", 6.0, 24),
create(14, "Tofu", "Produce", 23.2500, 35),
create(15, "Genen Shouyu", "Condiments", 15.50, 39),
create(16, "Pavlova", "Confections", 17.4500, 29),
create(17, "Alice Mutton", "Meat/Poultry", 39.0, 0),
create(18, "Carnarvon Tigers", "Seafood", 62.50, 42),
create(19, "Teatime Chocolate Biscuits", "Confections", 9.20, 25),
create(20, "Sir Rodney's Marmalade", "Confections", 81.0, 40),
create(21, "Sir Rodney's Scones", "Confections", 10.0, 3),
create(22, "Gustaf's Knaeckebroed", "Grains/Cereals", 21.0, 104),
create(23, "Tunnbroed", "Grains/Cereals", 9.0, 61),
create(24, "Guarana Fantastica", "Beverages", 4.50, 20),
create(25, "NuNuCa Nuss-Nougat-Creme", "Confections", 14.0, 76),
create(26, "Gumbaer Gummibaerchen", "Confections", 31.2300, 15),
create(27, "Schoggi Schokolade", "Confections", 43.90, 49),
create(28, "Roessle Sauerkraut", "Produce", 45.60, 26),
create(29, "Thueringer Rostbratwurst", "Meat/Poultry", 123.7900, 0),
create(30, "Nord-Ost Matjeshering", "Seafood", 25.8900, 10),
create(31, "Gorgonzola Telino", "Dairy Products", 12.50, 0),
create(32, "Mascarpone Fabioli", "Dairy Products", 32.0, 9),
create(33, "Geitost", "Dairy Products", 2.50, 112),
create(34, "Sasquatch Ale", "Beverages", 14.0, 111),
create(35, "Steeleye Stout", "Beverages", 18.0, 20),
create(36, "Inlagd Sill", "Seafood", 19.0, 112),
create(37, "Gravad lax", "Seafood", 26.0, 11),
create(38, "Cote de Blaye", "Beverages", 263.50, 17),
create(39, "Chartreuse verte", "Beverages", 18.0, 69),
create(40, "Boston Crab Meat", "Seafood", 18.40, 123),
create(41, "Jack's New England Clam Chowder", "Seafood", 9.6500, 85),
create(42, "Singaporean Hokkien Fried Mee", "Grains/Cereals", 14.0, 26),
create(43, "Ipoh Coffee", "Beverages", 46.0, 17),
create(44, "Gula Malacca", "Condiments", 19.4500, 27),
create(45, "Rogede sild", "Seafood", 9.50, 5),
create(46, "Spegesild", "Seafood", 12.0, 95),
create(47, "Zaanse koeken", "Confections", 9.50, 36),
create(48, "Chocolade", "Confections", 12.7500, 15),
create(49, "Maxilaku", "Confections", 20.0, 10),
create(50, "Valkoinen suklaa", "Confections", 16.2500, 65),
create(51, "Manjimup Dried Apples", "Produce", 53.0, 20),
create(52, "Filo Mix", "Grains/Cereals", 7.0, 38),
create(53, "Perth Pasties", "Meat/Poultry", 32.80, 0),
create(54, "Tourtiere", "Meat/Poultry", 7.4500, 21),
create(55, "Pate chinois", "Meat/Poultry", 24.0, 115),
create(56, "Gnocchi di nonna Alice", "Grains/Cereals", 38.0, 21),
create(57, "Ravioli Angelo", "Grains/Cereals", 19.50, 36),
create(58, "Escargots de Bourgogne", "Seafood", 13.2500, 62),
create(59, "Raclette Courdavault", "Dairy Products", 55.0, 79),
create(60, "Camembert Pierrot", "Dairy Products", 34.0, 19),
create(61, "Sirop d'erable", "Condiments", 28.50, 113),
create(62, "Tarte au sucre", "Confections", 49.30, 17),
create(63, "Vegie-spread", "Condiments", 43.90, 24),
create(64, "Wimmers gute Semmelknoedel", "Grains/Cereals", 33.2500, 22),
create(65, "Louisiana Fiery Hot Pepper Sauce", "Condiments", 21.0500, 76),
create(66, "Louisiana Hot Spiced Okra", "Condiments", 17.0, 4),
create(67, "Laughing Lumberjack Lager", "Beverages", 14.0, 52),
create(68, "Scottish Longbreads", "Confections", 12.50, 6),
create(69, "Gudbrandsdalsost", "Dairy Products", 36.0, 26),
create(70, "Outback Lager", "Beverages", 15.0, 15),
create(71, "Flotemysost", "Dairy Products", 21.50, 26),
create(72, "Mozzarella di Giovanni", "Dairy Products", 34.80, 14),
create(73, "Roed Kaviar", "Seafood", 15.0, 101),
create(74, "Longlife Tofu", "Produce", 10.0, 4),
create(75, "Rhoenbraeu Klosterbier", "Beverages", 7.7500, 125),
create(76, "Lakkalikoeoeri", "Beverages", 18.0, 57),
create(77, "Original Frankfurter gruene Sosse", "Condiments", 13.0, 32) };
return Arrays.asList(list);
}
}
//## Java 1.6 end ##
/*
* 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.test.jaqu;
//## Java 1.6 begin ##
import java.math.BigDecimal;
import java.util.List;
import org.h2.jaqu.Db;
import org.h2.test.TestBase;
//## Java 1.6 end ##
/**
* Implementation of the 101 LINQ Samples as described in
* http://msdn2.microsoft.com/en-us/vcsharp/aa336760.aspx
*/
//## Java 1.6 begin ##
public class SamplesTest extends TestBase {
private Db db;
public void test() throws Exception {
db = Db.open("jdbc:h2:mem:", "sa", "sa");
db.insertAll(Product.getProductList());
db.insertAll(Customer.getCustomerList());
db.insertAll(Order.getOrderList());
testSelectManyCompoundFrom2();
testAnonymousTypes3();
testWhereSimple4();
testWhereSimple2();
testWhereSimple3();
testSelectSimple2();
db.close();
}
private void testWhereSimple2() throws Exception {
// var soldOutProducts =
// from p in products
// where p.UnitsInStock == 0
// select p;
Product p = db.alias(Product.class);
List<Product> soldOutProducts =
db.from(p).
where(p.unitsInStock).is(0).
orderBy(p.productId).select();
String result = "";
for (Product x : soldOutProducts) {
result += x.productName + ";";
}
assertEquals(result, "Chef Anton's Gumbo Mix;Alice Mutton;Thueringer Rostbratwurst;Gorgonzola Telino;Perth Pasties;");
}
private void testWhereSimple3() throws Exception {
// var expensiveInStockProducts =
// from p in products
// where p.UnitsInStock > 0
// && p.UnitPrice > 3.00M
// select p;
Product p = db.alias(Product.class);
List<Product> expensiveInStockProducts =
db.from(p).
where(p.unitsInStock).isBigger(0).
and(p.unitPrice).isBigger(3.0).
orderBy(p.productId).select();
String result = "";
for (Product x : expensiveInStockProducts) {
result += x.productName + ";";
}
assertEquals(
result,
"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;"
+ "Queso Cabrales;Queso Manchego La Pastora;Konbu;Tofu;Genen Shouyu;Pavlova;"
+ "Carnarvon Tigers;Teatime Chocolate Biscuits;Sir Rodney's Marmalade;Sir Rodney's Scones;"
+ "Gustaf's Knaeckebroed;Tunnbroed;Guarana Fantastica;NuNuCa Nuss-Nougat-Creme;Gumbaer Gummibaerchen;"
+ "Schoggi Schokolade;Roessle Sauerkraut;Nord-Ost Matjeshering;Mascarpone Fabioli;Sasquatch Ale;"
+ "Steeleye Stout;Inlagd Sill;Gravad lax;Cote de Blaye;"
+ "Chartreuse verte;Boston Crab Meat;Jack's New England Clam Chowder;"
+ "Singaporean Hokkien Fried Mee;Ipoh Coffee;Gula Malacca;Rogede sild;"
+ "Spegesild;Zaanse koeken;Chocolade;Maxilaku;Valkoinen suklaa;"
+ "Manjimup Dried Apples;Filo Mix;Tourtiere;Pate chinois;"
+ "Gnocchi di nonna Alice;Ravioli Angelo;Escargots de Bourgogne;"
+ "Raclette Courdavault;Camembert Pierrot;Sirop d'erable;"
+ "Tarte au sucre;Vegie-spread;Wimmers gute Semmelknoedel;"
+ "Louisiana Fiery Hot Pepper Sauce;Louisiana Hot Spiced Okra;"
+ "Laughing Lumberjack Lager;Scottish Longbreads;Gudbrandsdalsost;"
+ "Outback Lager;Flotemysost;Mozzarella di Giovanni;Roed Kaviar;"
+ "Longlife Tofu;Rhoenbraeu Klosterbier;Lakkalikoeoeri;"
+ "Original Frankfurter gruene Sosse;");
}
private void testWhereSimple4() throws Exception {
// var waCustomers =
// from c in customers
// where c.Region == "WA"
// select c;
Customer c = db.alias(Customer.class);
List<Customer> waCustomers =
db.from(c).
where(c.region).is("WA").
select();
for (Customer cu : waCustomers) {
assertEquals("WA", cu.region);
}
}
private void testSelectSimple2() throws Exception {
// var productNames =
// from p in products
// select p.ProductName;
Product p = db.alias(Product.class);
List<String> productNames =
db.from(p).
orderBy(p.productId).select(p.productName);
List<Product> products = Product.getProductList();
for (int i = 0; i < products.size(); i++) {
assertEquals(products.get(i).productName, productNames.get(i));
}
}
//## Java 1.6 end ##
/**
* A result set class containing the product name and price.
*/
//## Java 1.6 begin ##
public static class ProductPrice {
public String productName;
public String category;
public Double price;
}
private void testAnonymousTypes3() throws Exception {
// var productInfos =
// from p in products
// select new {
// p.ProductName,
// p.Category,
// Price = p.UnitPrice
// };
final Product p = db.alias(Product.class);
List<ProductPrice> productInfos =
db.from(p).orderBy(p.productId).
select(new ProductPrice() { {
productName = p.productName;
category = p.category;
price = p.unitPrice;
}});
List<Product> products = Product.getProductList();
assertEquals(products.size(), productInfos.size());
for (int i = 0; i < products.size(); i++) {
ProductPrice pr = productInfos.get(i);
Product p2 = products.get(i);
assertEquals(p2.productName, pr.productName);
assertEquals(p2.category, pr.category);
assertEquals(p2.unitPrice, pr.price);
}
}
//## Java 1.6 end ##
/**
* A result set class containing customer data and the order total.
*/
//## Java 1.6 begin ##
public static class CustOrder {
public String customerId;
public Integer orderId;
public BigDecimal total;
}
private void testSelectManyCompoundFrom2() {
// var orders =
// from c in customers,
// o in c.Orders
// where o.Total < 500.00M
// select new {
// c.CustomerID,
// o.OrderID,
// o.Total
// };
final Customer c = db.alias(Customer.class);
final Order o = db.alias(Order.class);
List<CustOrder> orders =
db.from(c).
innerJoin(o).on(c.customerId).is(o.customerId).
where(o.total).isSmaller(new BigDecimal("500.00")).
select(new CustOrder() { {
customerId = c.customerId;
orderId = o.orderId;
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(';');
}
String s = buff.toString();
System.out.println(s);
// int todoImplementListResolution;
// int todoVerifyResult;
}
}
//## Java 1.6 end ##
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
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
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>
Javadoc package documentation
</title></head><body style="font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; font-weight: normal;">
JaQu (Java Query) test cases.
</body></html>
\ No newline at end of file
......@@ -523,4 +523,25 @@ monitor benefit performing conditional significant arithmetic instrumented
doclets extremes instructions printable skips sava sources cms bytecode cfml
cold compiles markup spellchecker interleaved poormans programmed swt railo
clobs resizes precisions scales stopwatch shortly puts captured decremented
him uninterpreted entering composed patched rowlock
\ No newline at end of file
him uninterpreted entering composed patched rowlock
tourtiere okra genen cajun compound poultry matjeshering steeleye guarana
elsewhere dried chowder raclette nord chef kobe gumbaer alfki chocolade
perth mascarpone dairy inlagd gruene vegie category sosse sucre tunnbroed
alice rodney flotemysost uncle anton chinois cranberry pavlova courdavault
rogede sauerkraut maxilaku manjimup thueringer ravioli manchego cereals fiery
queso seasoning chartreuse infos giovanni pastora pierrot valkoinen anatr sill
gnocchi kaviar louisiana konbu gorgonzola outback ipoh wimmers nonna chocolate
cabrales sir grains ikura mishi sild linq erable cust jaqu tarte rostbratwurst
tofu nuss nougat klosterbier fried singaporean roessle lakkalikoeoeri malacca
geitost scones aniseed gula mutton grandma teatime carnarvon chai
gudbrandsdalsost shouyu ost rhoenbraeu beverages blaye confections gute
schoggi stout syrup longbreads seafood condiments gummibaerchen koeken pears
cote spiced mee knaeckebroed verte jack lager schokolade longlife pepper
semmelknoedel spegesild frankfurter laughing boysenberry england gustaf gravad
creme meat fabioli sirop mozzarella niku fantastica pate telino angelo lax
filo gumbo pasties marmalade ale suklaa scottish zaanse hokkien sauce
crab northwoods escargots organic sasquatch bourgogne clam camembert tigers
chang lumberjack roed biscuits
usable
\ No newline at end of file
/*
* 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;
/**
* A enumeration of compare operations.
*/
//## Java 1.6 begin ##
public enum CompareType {
EQUAL("=", true),
BIGGER(">", true),
BIGGER_EQUAL(">=", true),
SMALLER("<", true),
SMALLER_EQUAL("<=", true),
NOT_EQUAL("<>", true),
IS_NOT_NULL("IS NOT NULL", false),
IS_NULL("IS NULL", false),
LIKE("LIKE", true);
private String text;
private boolean hasRightExpression;
CompareType(String text, boolean hasRightExpression) {
this.text = text;
this.hasRightExpression = hasRightExpression;
}
public String toString() {
return text;
}
public boolean hasRightExpression() {
return hasRightExpression;
}
}
//## Java 1.6 end ##
/*
* 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;
/**
* A condition contains one or two operands and a compare operation.
*
* @param <A> the operand type
*/
//## Java 1.6 begin ##
public class Condition<A> implements ConditionToken {
Query< ? > query;
CompareType compareType;
A x, y;
Condition(Query< ? > query, A x, A y, CompareType compareType) {
this.query = query;
this.compareType = compareType;
this.x = x;
this.y = y;
}
public String toString() {
if (compareType.hasRightExpression()) {
return query.getString(x) + compareType.toString() + query.getString(y);
}
return query.getString(x) + compareType.toString();
}
}
//## Java 1.6 end ##
/*
* 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;
/**
* An OR or an AND condition.
*/
//## Java 1.6 begin ##
public enum ConditionAndOr implements ConditionToken {
AND("AND"),
OR("OR");
private String text;
ConditionAndOr(String text) {
this.text = text;
}
public String toString() {
return text;
}
}
//## Java 1.6 end ##
/*
* 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;
/**
* Classes implementing this interface can be used as a token in a conditional
* expression.
*/
public interface ConditionToken {
String toString();
}
/*
* 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.6 begin ##
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.h2.jaqu.TableDefinition.FieldDefinition;
import org.h2.jaqu.util.Utils;
import org.h2.jaqu.util.WeakIdentityHashMap;
import org.h2.util.JdbcUtils;
//## Java 1.6 end ##
/**
* This class represents a connection to a database.
*/
//## Java 1.6 begin ##
public class Db {
private final Connection conn;
private final Map<Class, TableDefinition> classMap = Utils.newHashMap();
private final WeakIdentityHashMap<Object, FieldDefinition> aliasMap = Utils.newWeakIdentityHashMap();
Db(Connection conn) {
this.conn = conn;
}
public static <T> T instance(Class<T> clazz) {
try {
return clazz.newInstance();
} catch (Exception e) {
throw new Error(e);
}
}
public static Db open(String url, String user, String password) {
try {
Connection conn = JdbcUtils.getConnection(null, url, user, password);
return new Db(conn);
} catch (SQLException e) {
throw convert(e);
}
}
public static Db open(String url, String user, char[] password) {
try {
Properties prop = new Properties();
prop.setProperty("user", user);
prop.put("password", password);
Connection conn = JdbcUtils.getConnection(null, url, prop);
return new Db(conn);
} catch (SQLException e) {
throw convert(e);
}
}
private static Error convert(Exception e) {
return new Error(e);
}
public <T> void insert(T t) {
Class< ? > clazz = t.getClass();
define(clazz).createTableIfRequired(this).insert(this, t);
}
public <T extends Object> Query<T> from(T alias) {
return new Query<T>(this, alias);
}
public <T> void createTable(Class<T> clazz) {
define(clazz).createTableIfRequired(this);
}
<T> TableDefinition<T> define(Class<T> clazz) {
TableDefinition def = classMap.get(clazz);
if (def == null) {
def = new TableDefinition(clazz);
def.mapFields();
classMap.put(clazz, def);
if (Table.class.isAssignableFrom(clazz)) {
T t = instance(clazz);
Table table = (Table) t;
Define.define(def, table);
}
}
return def;
}
public <T> T alias(Class<T> clazz) {
TableDefinition def = define(clazz);
T alias = instance(clazz);
def.initObject(alias, aliasMap);
return alias;
}
public void close() {
try {
conn.close();
} catch (Exception e) {
throw new Error(e);
}
}
public <T> void insertAll(List<T> list) {
for (T t : list) {
insert(t);
}
}
void execute(String sql) {
try {
conn.createStatement().execute(sql);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public PreparedStatement prepare(String sql) {
try {
return conn.prepareStatement(sql);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
TableDefinition getTableDefinition(Class< ? > clazz) {
return classMap.get(clazz);
}
public ResultSet executeQuery(String sql) {
try {
return conn.createStatement().executeQuery(sql);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public <X> FieldDefinition<X> getFieldDefinition(X x) {
return aliasMap.get(x);
}
}
//## Java 1.6 end ##
/*
* 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;
/**
* This class provides utility methods to define primary keys, indexes, and set
* the name of the table.
*/
//## Java 1.6 begin ##
public class Define {
private static TableDefinition currentTableDefinition;
private static Table currentTable;
public static void primaryKey(Object... columns) {
checkInDefine();
currentTableDefinition.setPrimaryKey(columns);
}
public static void index(Object... columns) {
checkInDefine();
currentTableDefinition.addIndex(columns);
}
public static void tableName(String tableName) {
currentTableDefinition.setTableName(tableName);
}
static synchronized void define(TableDefinition tableDefinition, Table table) {
currentTableDefinition = tableDefinition;
currentTable = table;
tableDefinition.mapObject(table);
table.define();
tableDefinition.apply();
currentTable = null;
}
private static void checkInDefine() {
if (currentTable == null) {
throw new RuntimeException("This method may only be called from within the define() method, and the define() method is called by the framework.");
}
}
}
//## Java 1.6 end ##
/*
* 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.6 begin ##
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.h2.jaqu.TableDefinition.FieldDefinition;
import org.h2.jaqu.util.Utils;
//## Java 1.6 end ##
/**
* This class represents a query.
*
* @param <T> the return type
*/
//## Java 1.6 begin ##
public class Query<T> {
private Db db;
private T alias;
private TableDefinition aliasDef;
private ArrayList<ConditionToken> conditions = Utils.newArrayList();
// private HashMap<Object, TableDefinition> join = Utils.newHashMap();
public Query(Db db, T alias) {
this.db = db;
this.alias = alias;
aliasDef = db.getTableDefinition(alias.getClass());
}
@SuppressWarnings("unchecked")
private <X> Class<X> getClass(X x) {
return (Class<X>) x.getClass();
}
public List<T> select() {
List<T> result = Utils.newArrayList();
ResultSet rs = db.executeQuery(toString());
Class<T> aliasClass = getClass(alias);
try {
while (rs.next()) {
T item = Utils.newObject(aliasClass);
aliasDef.readRow(item, rs);
result.add(item);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
return result;
}
public <X, Z> List<X> select(Z x) {
Class< ? > clazz = x.getClass();
if (Utils.isSimpleType(clazz)) {
return selectSimple((X) x);
}
clazz = clazz.getSuperclass();
return select((Class<X>) clazz, (X) x);
}
private <X> List<X> select(Class<X> clazz, X x) {
List<X> result = Utils.newArrayList();
TableDefinition<X> def = db.define(clazz);
ResultSet rs = db.executeQuery(toString());
Class<T> aliasClass = getClass(alias);
try {
while (rs.next()) {
T item = Utils.newObject(aliasClass);
aliasDef.readRow(item, rs);
X item2 = Utils.newObject(clazz);
def.copyAttributeValues(db, item, item2, x);
result.add(item2);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
return result;
}
public <X> List<X> selectSimple(X x) {
List<X> result = Utils.newArrayList();
ResultSet rs = db.executeQuery(toString());
FieldDefinition<X> def = db.getFieldDefinition(x);
try {
while (rs.next()) {
X item;
if (def == null) {
item = x;
} else {
item = def.read(rs);
}
result.add(item);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
return result;
}
public <A> QueryCondition<T, A> where(A x) {
return new QueryCondition<T, A>(this, x);
}
//## Java 1.6 end ##
/**
* Order by a number of columns.
*
* @param columns the columns
* @return the query
*/
//## Java 1.6 begin ##
public Query<T> orderBy(Integer... columns) {
return this;
}
String getString(Object x) {
FieldDefinition def = db.getFieldDefinition(x);
if (def != null) {
return def.columnName;
}
return Utils.quoteSQL(x);
}
public void addConditionToken(ConditionToken condition) {
conditions.add(condition);
}
public String toString() {
StringBuffer buff = new StringBuffer("SELECT * FROM ");
buff.append(aliasDef.tableName);
if (conditions.size() > 0) {
buff.append(" WHERE ");
for (ConditionToken token : conditions) {
buff.append(token.toString());
buff.append(' ');
}
}
return buff.toString();
}
//## Java 1.6 end ##
/**
* Join another table.
*
* @param u an alias for the table to join
* @return the joined query
*/
//## Java 1.6 begin ##
public QueryJoin innerJoin(Object u) {
return new QueryJoin(this);
}
}
//## Java 1.6 end ##
/*
* 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;
/**
* This class represents a query with an incomplete condition.
*
* @param <T> the return type of the query
* @param <A> the incomplete condition data type
*/
//## Java 1.6 begin ##
public class QueryCondition<T, A> {
private Query<T> query;
private A x;
public QueryCondition(Query<T> query, A x) {
this.query = query;
this.x = x;
}
public QueryWhere<T> is(A y) {
query.addConditionToken(new Condition<A>(query, x, y, CompareType.EQUAL));
return new QueryWhere<T>(query);
}
public QueryWhere<T> isBigger(A y) {
query.addConditionToken(new Condition<A>(query, x, y, CompareType.BIGGER));
return new QueryWhere<T>(query);
}
public QueryWhere<T> isSmaller(A y) {
query.addConditionToken(new Condition<A>(query, x, y, CompareType.SMALLER));
return new QueryWhere<T>(query);
}
}
//## Java 1.6 end ##
/*
* 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;
/**
* This class represents a query with a join.
*/
//## Java 1.6 begin ##
public class QueryJoin {
Query< ? > query;
QueryJoin(Query< ? > query) {
this.query = query;
}
public <A> QueryJoinCondition<A> on(A x) {
return new QueryJoinCondition<A>(query, x);
}
}
//## Java 1.6 end ##
/*
* 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;
/**
* This class represents a query with join and an incomplete condition.
*
* @param <A> the incomplete condition data type
*/
//## Java 1.6 begin ##
public class QueryJoinCondition<A> {
private Query< ? > query;
private A x;
public QueryJoinCondition(Query< ? > query, A x) {
this.query = query;
this.x = x;
}
public Query< ? > is(A y) {
query.addConditionToken(new Condition<A>(query, x, y, CompareType.EQUAL));
return query;
}
}
//## Java 1.6 end ##
/*
* 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.6 begin ##
import java.util.List;
//## Java 1.6 end ##
/**
* This class represents a query with a condition.
*
* @param <T> the return type
*/
//## Java 1.6 begin ##
public class QueryWhere<T> {
Query<T> query;
QueryWhere(Query<T> query) {
this.query = query;
}
public <A> QueryCondition<T, A> and(A x) {
query.addConditionToken(ConditionAndOr.AND);
return new QueryCondition<T, A>(query, x);
}
public <A> QueryCondition<T, A> or(A x) {
query.addConditionToken(ConditionAndOr.OR);
return new QueryCondition<T, A>(query, x);
}
public <X, Z> List<X> select(Z x) {
return (List<X>) query.select(x);
}
public List<T> select() {
return query.select();
}
//## Java 1.6 end ##
/**
* Order by a number of columns.
*
* @param columns the columns
* @return the query
*/
//## Java 1.6 begin ##
public QueryWhere<T> orderBy(Integer... columns) {
return this;
}
}
//## Java 1.6 end ##
/*
* 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;
/**
* A class that implements this interface can be used as a database table.
*/
public interface Table {
/**
* This method is called to let the table define the primary key, indexes,
* and the table name.
*/
void define();
}
/*
* 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.6 begin ##
import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.Map;
import org.h2.jaqu.util.Utils;
//## Java 1.6 end ##
/**
* A table definition contains the index definitions of a table, the field
* definitions, the table name, and other meta data.
*
* @param <T> the table type
*/
//## Java 1.6 begin ##
class TableDefinition<T> {
//## Java 1.6 end ##
/**
* The meta data of an index.
*/
//## Java 1.6 begin ##
static class IndexDefinition {
boolean unique;
String indexName;
String[] columnNames;
}
//## Java 1.6 end ##
/**
* The meta data of a field.
*/
//## Java 1.6 begin ##
static class FieldDefinition<X> {
String columnName;
Field field;
String dataType;
public Object getValue(Object obj) {
try {
return field.get(obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void initWithNewObject(Object obj) {
Object o = Utils.newObject(field.getType());
setValue(obj, o);
}
void setValue(Object obj, Object o) {
try {
field.set(obj, o);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
public X read(ResultSet rs) {
try {
return (X) rs.getObject(columnName);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
String tableName;
private Class<T> clazz;
private ArrayList<FieldDefinition> fields = Utils.newArrayList();
private IdentityHashMap<Object, FieldDefinition> fieldMap = Utils.newIdentityHashMap();
private String[] primaryKeyColumnNames;
private ArrayList<IndexDefinition> indexes = Utils.newArrayList();
TableDefinition(Class<T> clazz) {
this.clazz = clazz;
tableName = clazz.getSimpleName();
}
void setTableName(String tableName) {
this.tableName = tableName;
}
public void setPrimaryKey(Object[] primaryKeyColumns) {
this.primaryKeyColumnNames = mapColumnNames(primaryKeyColumns);
}
<A> String getColumnName(A fieldObject) {
FieldDefinition def = fieldMap.get(fieldObject);
return def == null ? null : def.columnName;
}
private String[] mapColumnNames(Object[] columns) {
int len = columns.length;
String[] columnNames = new String[len];
for (int i = 0; i < len; i++) {
columnNames[i] = getColumnName(columns[i]);
}
return columnNames;
}
public void addIndex(Object[] columns) {
IndexDefinition index = new IndexDefinition();
index.indexName = tableName + "_" + indexes.size();
index.columnNames = mapColumnNames(columns);
indexes.add(index);
}
public void apply() {
// TODO Auto-generated method stub
}
public void mapFields() {
Field[] classFields = clazz.getFields();
for (Field f : classFields) {
FieldDefinition fieldDef = new FieldDefinition();
fieldDef.field = f;
fieldDef.columnName = f.getName();
fieldDef.dataType = getDataType(f);
fields.add(fieldDef);
}
}
private String getDataType(Field field) {
Class< ? > clazz = field.getType();
if (clazz == Integer.class) {
return "INT";
} else if (clazz == String.class) {
return "VARCHAR";
} else if (clazz == Double.class) {
return "DOUBLE";
}
return "VARCHAR";
// TODO add more data types
}
void insert(Db db, Object obj) {
StringBuilder buff = new StringBuilder("INSERT INTO ");
buff.append(tableName);
buff.append(" VALUES(");
for (int i = 0; i < fields.size(); i++) {
if (i > 0) {
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);
Object value = field.getValue(obj);
setValue(prep, i + 1, value);
}
try {
prep.execute();
} 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);
}
}
public TableDefinition createTableIfRequired(Db db) {
StringBuilder buff = new StringBuilder("CREATE TABLE IF NOT EXISTS ");
buff.append(tableName);
buff.append('(');
for (int i = 0; i < fields.size(); i++) {
FieldDefinition field = fields.get(i);
if (i > 0) {
buff.append(", ");
}
buff.append(field.columnName);
buff.append(' ');
buff.append(field.dataType);
}
if (primaryKeyColumnNames != null) {
buff.append(", PRIMARY KEY(");
for (int i = 0; i < primaryKeyColumnNames.length; i++) {
if (i > 0) {
buff.append(", ");
}
buff.append(primaryKeyColumnNames[i]);
}
buff.append(')');
}
buff.append(')');
db.execute(buff.toString());
// TODO create indexes
return this;
}
public void mapObject(Object obj) {
fieldMap.clear();
initObject(obj, fieldMap);
}
void initObject(Object obj, Map<Object, FieldDefinition> map) {
for (FieldDefinition def : fields) {
def.initWithNewObject(obj);
map.put(def.getValue(obj), def);
}
}
void readRow(Object item, ResultSet rs) {
for (FieldDefinition def : fields) {
Object o = def.read(rs);
def.setValue(item, o);
}
}
<U, X> void copyAttributeValues(Db db, U from, X to, X map) {
for (FieldDefinition def : fields) {
Object obj = def.getValue(map);
FieldDefinition fd = db.getFieldDefinition(obj);
Object value = fd.getValue(from);
def.setValue(to, value);
}
}
}
//## Java 1.6 end ##
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
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
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>
Javadoc package documentation
</title></head><body style="font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; font-weight: normal;">
The implementation of the JaQu (Java Query) tool.
</body></html>
\ No newline at end of file
/*
* 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.util;
/**
* This utility class contains functions related to class loading.
* There is a mechanism to restrict class loading.
*/
public class ClassUtils {
private ClassUtils() {
// utility class
}
//## Java 1.6 begin ##
public static Class< ? > loadClass(String className) {
try {
return Class.forName(className);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//## Java 1.6 end ##
}
/*
* 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.util;
//## Java 1.6 begin ##
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
//## Java 1.6 end ##
/**
* Messages used in the database engine.
* Use the PropertiesToUTF8 tool to translate properties files to UTF-8 and back.
* If the word 'SQL' appears then the whole SQL statement must be a parameter,
* otherwise this may be added: '; SQL statement: ' + sql
*/
public class Message {
private Message() {
// utility class
}
/**
* Convert an exception to a SQL exception using the default mapping.
*
* @param e the root cause
* @return the SQL exception object
*/
//## Java 1.6 begin ##
public static SQLException convert(Throwable e) {
if (e instanceof SQLException) {
return (SQLException) e;
} else if (e instanceof InvocationTargetException) {
InvocationTargetException te = (InvocationTargetException) e;
Throwable t = te.getTargetException();
if (t instanceof SQLException) {
return (SQLException) t;
}
return new SQLException("Invocation exception: " + t.toString(), e);
} else if (e instanceof IOException) {
return new SQLException("IO exception: " + e.toString(), e);
}
return new SQLException("General exception: " + e.toString(), e);
}
//## Java 1.6 end ##
}
/*
* 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.util;
//## Java 1.6 begin ##
import java.lang.reflect.Constructor;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import org.h2.util.StringUtils;
//## Java 1.6 end ##
/**
* Generic utility methods.
*/
//## Java 1.6 begin ##
public class Utils {
private static volatile long counter;
private static final boolean MAKE_ACCESSIBLE = true;
public static <T> ArrayList<T> newArrayList() {
return new ArrayList<T>();
}
public static <A, B> HashMap<A, B> newHashMap() {
return new HashMap<A, B>();
}
public static <A, B> Map<A, B> newSynchronizedHashMap() {
HashMap<A, B> map = newHashMap();
return Collections.synchronizedMap(map);
}
public static <A, B> WeakIdentityHashMap<A, B> newWeakIdentityHashMap() {
return new WeakIdentityHashMap<A, B>();
}
public static <A, B> IdentityHashMap<A, B> newIdentityHashMap() {
return new IdentityHashMap<A, B>();
}
@SuppressWarnings("unchecked")
public static <T> T newObject(Class<T> clazz) {
if (clazz == Integer.class) {
return (T) new Integer((int) counter++);
} else if (clazz == String.class) {
return (T) ("" + counter++);
} else if (clazz == Long.class) {
return (T) new Long(counter++);
} else if (clazz == Short.class) {
return (T) new Short((short) counter++);
} else if (clazz == Byte.class) {
return (T) new Byte((byte) counter++);
} else if (clazz == Float.class) {
return (T) new Float(counter++);
} else if (clazz == Double.class) {
return (T) new Double(counter++);
} else if (clazz == Boolean.class) {
return (T) Boolean.FALSE;
} else if (clazz == BigDecimal.class) {
return (T) new BigDecimal(counter++);
} else if (clazz == BigInteger.class) {
return (T) new BigInteger("" + counter++);
} else if (clazz == List.class) {
return (T) new ArrayList();
}
try {
return clazz.newInstance();
} catch (Exception e) {
if (MAKE_ACCESSIBLE) {
Constructor[] constructors = clazz.getDeclaredConstructors();
// try 0 length constructors
for (Constructor c : constructors) {
if (c.getParameterTypes().length == 0) {
c.setAccessible(true);
try {
return clazz.newInstance();
} catch (Exception e2) {
// ignore
}
}
}
// try 1 length constructors
for (Constructor c : constructors) {
if (c.getParameterTypes().length == 1) {
c.setAccessible(true);
try {
return (T) c.newInstance(new Object[1]);
} catch (Exception e2) {
// ignore
}
}
}
}
throw new RuntimeException("Exception trying to create " + clazz.getName() + ": " + e, e);
}
}
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) {
if (Number.class.isAssignableFrom(clazz)) {
return true;
} else if (clazz == String.class) {
return true;
}
return false;
}
}
//## Java 1.6 end ##
/*
* 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.util;
//## Java 1.6 begin ##
import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
//## Java 1.6 end ##
/**
* This hash map uses weak references, so that elements that are no longer
* referenced elsewhere can be garbage collected. It also uses object identity
* to compare keys.
*
* @param <K> the keys
* @param <V> the value
*/
//## Java 1.6 begin ##
public class WeakIdentityHashMap<K, V> implements Map<K, V> {
private static final int MAX_LOAD = 90;
private static final WeakReference DELETED_KEY = new WeakReference(null);
private int mask, len, size, deletedCount, level;
private int maxSize, minSize, maxDeleted;
private WeakReference<K>[] keys;
private V[] values;
public WeakIdentityHashMap() {
reset(2);
}
public int size() {
return size;
}
private void checkSizePut() {
if (deletedCount > size) {
rehash(level);
}
if (size + deletedCount >= maxSize) {
rehash(level + 1);
}
}
private void checkSizeRemove() {
if (size < minSize && level > 0) {
rehash(level - 1);
} else if (deletedCount > maxDeleted) {
rehash(level);
}
}
private int getIndex(Object key) {
return System.identityHashCode(key) & mask;
}
private void reset(int newLevel) {
minSize = size * 3 / 4;
size = 0;
level = newLevel;
len = 2 << level;
mask = len - 1;
maxSize = (int) (len * MAX_LOAD / 100L);
deletedCount = 0;
maxDeleted = 20 + len / 2;
keys = new WeakReference[len];
values = (V[]) new Object[len];
}
public V put(K key, V value) {
checkSizePut();
int index = getIndex(key);
int plus = 1;
int deleted = -1;
do {
WeakReference<K> k = keys[index];
if (k == null) {
// found an empty record
if (deleted >= 0) {
index = deleted;
deletedCount--;
}
size++;
keys[index] = new WeakReference<K>(key);
values[index] = value;
return null;
} else if (k == DELETED_KEY) {
if (deleted < 0) {
// found the first deleted record
deleted = index;
}
} else {
Object r = k.get();
if (r == null) {
delete(index);
} else if (r == key) {
// update existing
V old = values[index];
values[index] = value;
return old;
}
}
index = (index + plus++) & mask;
} while(plus <= len);
throw new Error("hashmap is full");
}
public V remove(Object key) {
checkSizeRemove();
int index = getIndex(key);
int plus = 1;
do {
WeakReference<K> k = keys[index];
if (k == null) {
// found an empty record
return null;
} else if (k == DELETED_KEY) {
// continue
} else {
Object r = k.get();
if (r == null) {
delete(index);
} else if (r == key) {
// found the record
V old = values[index];
delete(index);
return old;
}
}
index = (index + plus++) & mask;
k = keys[index];
} while(plus <= len);
// not found
return null;
}
private void delete(int index) {
keys[index] = DELETED_KEY;
values[index] = null;
deletedCount++;
size--;
}
private void rehash(int newLevel) {
WeakReference<K>[] oldKeys = keys;
V[] oldValues = values;
reset(newLevel);
for (int i = 0; i < oldKeys.length; i++) {
WeakReference<K> k = oldKeys[i];
if (k != null && k != DELETED_KEY) {
K key = k.get();
if (key != null) {
put(key, oldValues[i]);
}
}
}
}
public V get(Object key) {
int index = getIndex(key);
int plus = 1;
do {
WeakReference<K> k = keys[index];
if (k == null) {
return null;
} else if (k == DELETED_KEY) {
// continue
} else {
Object r = k.get();
if (r == null) {
delete(index);
} else if (r == key) {
return values[index];
}
}
index = (index + plus++) & mask;
} while(plus <= len);
return null;
}
public void clear() {
reset(2);
}
public boolean containsKey(Object key) {
return get(key) != null;
}
public boolean containsValue(Object value) {
if (value == null) {
return false;
}
for (V item: values) {
if (value.equals(item)) {
return true;
}
}
return false;
}
public Set<java.util.Map.Entry<K, V>> entrySet() {
throw new UnsupportedOperationException();
}
public boolean isEmpty() {
return size == 0;
}
public Set<K> keySet() {
throw new UnsupportedOperationException();
}
public void putAll(Map< ? extends K, ? extends V> m) {
throw new UnsupportedOperationException();
}
public Collection<V> values() {
throw new UnsupportedOperationException();
}
}
//## Java 1.6 end ##
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
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
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>
Javadoc package documentation
</title></head><body style="font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; font-weight: normal;">
Utility classes used for the JaQu (Java Query) tool.
</body></html>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论