diff options
author | James Moger <james.moger@gmail.com> | 2013-03-08 21:14:50 -0500 |
---|---|---|
committer | James Moger <james.moger@gmail.com> | 2013-03-08 21:14:50 -0500 |
commit | d8915c7da130b8a6de6f2c911effe0e10dbe4d12 (patch) | |
tree | dec81ecb015b1e1102f019fd0d3d3ac5bb5492d0 /src/com | |
parent | 926634baaccf8f19f30fa179298ca7edebfeb58d (diff) | |
download | iciql-d8915c7da130b8a6de6f2c911effe0e10dbe4d12.tar.gz iciql-d8915c7da130b8a6de6f2c911effe0e10dbe4d12.zip |
Conform to Apache standard directory layout
Diffstat (limited to 'src/com')
68 files changed, 0 insertions, 13253 deletions
diff --git a/src/com/iciql/CompareType.java b/src/com/iciql/CompareType.java deleted file mode 100644 index 84e29fe..0000000 --- a/src/com/iciql/CompareType.java +++ /dev/null @@ -1,45 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-/**
- * An enumeration of compare operations.
- */
-
-enum CompareType {
- EQUAL("=", true), EXCEEDS(">", true), AT_LEAST(">=", true), LESS_THAN("<", true), AT_MOST("<=", true), NOT_EQUAL(
- "<>", true), IS_NOT_NULL("IS NOT NULL", false), IS_NULL("IS NULL", false), LIKE("LIKE", true), BETWEEN(
- "BETWEEN", true);
-
- private String text;
- private boolean hasRightExpression;
-
- CompareType(String text, boolean hasRightExpression) {
- this.text = text;
- this.hasRightExpression = hasRightExpression;
- }
-
- String getString() {
- return text;
- }
-
- boolean hasRightExpression() {
- return hasRightExpression;
- }
-
-}
diff --git a/src/com/iciql/Condition.java b/src/com/iciql/Condition.java deleted file mode 100644 index 17cb117..0000000 --- a/src/com/iciql/Condition.java +++ /dev/null @@ -1,55 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-/**
- * A condition contains one or two operands and a compare operation.
- *
- * @param <A>
- * the operand type
- */
-
-class Condition<A> implements Token {
- CompareType compareType;
- A x, y, z;
-
- Condition(A x, A y, CompareType compareType) {
- this(x, y, null, compareType);
- }
-
- Condition(A x, A y, A z, CompareType compareType) {
- this.compareType = compareType;
- this.x = x;
- this.y = y;
- this.z = z;
- }
-
- public <T> void appendSQL(SQLStatement stat, Query<T> query) {
- query.appendSQL(stat, null, x);
- stat.appendSQL(" ");
- stat.appendSQL(compareType.getString());
- if (compareType.hasRightExpression()) {
- stat.appendSQL(" ");
- if (z == null) {
- query.appendSQL(stat, x, y);
- } else {
- query.appendSQL(stat, x, y, z, compareType);
- }
- }
- }
-}
diff --git a/src/com/iciql/ConditionAndOr.java b/src/com/iciql/ConditionAndOr.java deleted file mode 100644 index 4d1cd0e..0000000 --- a/src/com/iciql/ConditionAndOr.java +++ /dev/null @@ -1,37 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-/**
- * An OR or an AND condition.
- */
-
-enum ConditionAndOr implements Token {
- AND("AND"), OR("OR");
-
- private String text;
-
- ConditionAndOr(String text) {
- this.text = text;
- }
-
- public <T> void appendSQL(SQLStatement stat, Query<T> query) {
- stat.appendSQL(text);
- }
-
-}
diff --git a/src/com/iciql/Constants.java b/src/com/iciql/Constants.java deleted file mode 100644 index 8b54493..0000000 --- a/src/com/iciql/Constants.java +++ /dev/null @@ -1,38 +0,0 @@ -/*
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-/**
- * Iciql constants.
- */
-public class Constants {
-
- public static final String NAME = "iciql";
-
- // The build script extracts this exact line so be careful editing it
- // and only use A-Z a-z 0-9 .-_ in the string.
- public static final String VERSION = "1.2.0-SNAPSHOT";
-
- // The build script extracts this exact line so be careful editing it
- // and only use A-Z a-z 0-9 .-_ in the string.
- public static final String VERSION_DATE = "PENDING";
-
- // The build script extracts this exact line so be careful editing it
- // and only use A-Z a-z 0-9 .-_ in the string.
- public static final String API_CURRENT = "15";
-
-}
diff --git a/src/com/iciql/Db.java b/src/com/iciql/Db.java deleted file mode 100644 index ecd373c..0000000 --- a/src/com/iciql/Db.java +++ /dev/null @@ -1,774 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- * Copyright 2012 Frédéric Gaillard.
- * Copyright 2012 Alex Telepov.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.SQLFeatureNotSupportedException;
-import java.sql.Savepoint;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.sql.DataSource;
-
-import com.iciql.DbUpgrader.DefaultDbUpgrader;
-import com.iciql.Iciql.IQTable;
-import com.iciql.Iciql.IQVersion;
-import com.iciql.Iciql.IQView;
-import com.iciql.util.IciqlLogger;
-import com.iciql.util.JdbcUtils;
-import com.iciql.util.StringUtils;
-import com.iciql.util.Utils;
-import com.iciql.util.WeakIdentityHashMap;
-
-/**
- * This class represents a connection to a database.
- */
-
-public class Db {
-
- /**
- * This map It holds unique tokens that are generated by functions such as
- * Function.sum(..) in "db.from(p).select(Function.sum(p.unitPrice))". It
- * doesn't actually hold column tokens, as those are bound to the query
- * itself.
- */
- private static final Map<Object, Token> TOKENS;
-
- private static final Map<String, Class<? extends SQLDialect>> DIALECTS;
-
- private final Connection conn;
- private final Map<Class<?>, TableDefinition<?>> classMap = Collections
- .synchronizedMap(new HashMap<Class<?>, TableDefinition<?>>());
- private final SQLDialect dialect;
- private DbUpgrader dbUpgrader = new DefaultDbUpgrader();
- private final Set<Class<?>> upgradeChecked = Collections.synchronizedSet(new HashSet<Class<?>>());
-
- private boolean skipCreate;
- private boolean autoSavePoint = true;
-
- static {
- TOKENS = Collections.synchronizedMap(new WeakIdentityHashMap<Object, Token>());
- DIALECTS = Collections.synchronizedMap(new HashMap<String, Class<? extends SQLDialect>>());
- // can register by...
- // 1. Connection class name
- // 2. DatabaseMetaData.getDatabaseProductName()
- DIALECTS.put("Apache Derby", SQLDialectDerby.class);
- DIALECTS.put("H2", SQLDialectH2.class);
- DIALECTS.put("HSQL Database Engine", SQLDialectHSQL.class);
- DIALECTS.put("MySQL", SQLDialectMySQL.class);
- DIALECTS.put("PostgreSQL", SQLDialectPostgreSQL.class);
- DIALECTS.put("Microsoft SQL Server", SQLDialectMSSQL.class);
- }
-
- private Db(Connection conn) {
- this.conn = conn;
- String databaseName = null;
- DatabaseMetaData data = null;
- try {
- data = conn.getMetaData();
- databaseName = data.getDatabaseProductName();
- } catch (SQLException s) {
- throw new IciqlException(s, "failed to retrieve database metadata!");
- }
- dialect = getDialect(databaseName, conn.getClass().getName());
- dialect.configureDialect(databaseName, data);
- }
-
- /**
- * Register a new/custom dialect class. You can use this method to replace
- * any existing dialect or to add a new one.
- *
- * @param token
- * the fully qualified name of the connection class or the
- * expected result of DatabaseMetaData.getDatabaseProductName()
- * @param dialectClass
- * the dialect class to register
- */
- public static void registerDialect(String token, Class<? extends SQLDialect> dialectClass) {
- DIALECTS.put(token, dialectClass);
- }
-
- SQLDialect getDialect(String databaseName, String className) {
- Class<? extends SQLDialect> dialectClass = null;
- if (DIALECTS.containsKey(className)) {
- // dialect registered by connection class name
- dialectClass = DIALECTS.get(className);
- } else if (DIALECTS.containsKey(databaseName)) {
- // dialect registered by database name
- dialectClass = DIALECTS.get(databaseName);
- } else {
- // did not find a match, use default
- dialectClass = SQLDialectDefault.class;
- }
- return instance(dialectClass);
- }
-
- static <X> X registerToken(X x, Token token) {
- TOKENS.put(x, token);
- return x;
- }
-
- static Token getToken(Object x) {
- return TOKENS.get(x);
- }
-
- static <T> T instance(Class<T> clazz) {
- try {
- return clazz.newInstance();
- } catch (Exception e) {
- throw new IciqlException(e);
- }
- }
-
- public static Db open(String url) {
- try {
- Connection conn = JdbcUtils.getConnection(null, url, null, null);
- return new Db(conn);
- } catch (SQLException e) {
- throw new IciqlException(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 new IciqlException(e);
- }
- }
-
- public static Db open(String url, String user, char[] password) {
- try {
- Connection conn = JdbcUtils.getConnection(null, url, user, password == null ? null : new String(password));
- return new Db(conn);
- } catch (SQLException e) {
- throw new IciqlException(e);
- }
- }
-
- /**
- * Create a new database instance using a data source. This method is fast,
- * so that you can always call open() / close() on usage.
- *
- * @param ds
- * the data source
- * @return the database instance.
- */
- public static Db open(DataSource ds) {
- try {
- return new Db(ds.getConnection());
- } catch (SQLException e) {
- throw new IciqlException(e);
- }
- }
-
- public static Db open(Connection conn) {
- return new Db(conn);
- }
-
-
-
- /**
- * Convenience function to avoid import statements in application code.
- */
- public void activateConsoleLogger() {
- IciqlLogger.activateConsoleLogger();
- }
-
- /**
- * Convenience function to avoid import statements in application code.
- */
- public void deactivateConsoleLogger() {
- IciqlLogger.deactivateConsoleLogger();
- }
-
- public <T> void insert(T t) {
- Class<?> clazz = t.getClass();
- long rc = define(clazz).createIfRequired(this).insert(this, t, false);
- if (rc == 0) {
- throw new IciqlException("Failed to insert {0}. Affected rowcount == 0.", t);
- }
- }
-
- public <T> long insertAndGetKey(T t) {
- Class<?> clazz = t.getClass();
- return define(clazz).createIfRequired(this).insert(this, t, true);
- }
-
- /**
- * Merge INSERTS if the record does not exist or UPDATES the record if it
- * does exist. Not all databases support MERGE and the syntax varies with
- * the database.
- *
- * If the database does not support a MERGE syntax the dialect can try to
- * simulate a merge by implementing:
- * <p>
- * INSERT INTO foo... (SELECT ?,... FROM foo WHERE pk=? HAVING count(*)=0)
- * <p>
- * iciql will check the affected row count returned by the internal merge
- * method and if the affected row count = 0, it will issue an update.
- * <p>
- * See the Derby dialect for an implementation of this technique.
- * <p>
- * If the dialect does not support merge an IciqlException will be thrown.
- *
- * @param t
- */
- public <T> void merge(T t) {
- Class<?> clazz = t.getClass();
- TableDefinition<?> def = define(clazz).createIfRequired(this);
- int rc = def.merge(this, t);
- if (rc == 0) {
- rc = def.update(this, t);
- }
- if (rc == 0) {
- throw new IciqlException("merge failed");
- }
- }
-
- public <T> int update(T t) {
- Class<?> clazz = t.getClass();
- return define(clazz).createIfRequired(this).update(this, t);
- }
-
- public <T> int delete(T t) {
- Class<?> clazz = t.getClass();
- return define(clazz).createIfRequired(this).delete(this, t);
- }
-
- public <T extends Object> Query<T> from(T alias) {
- Class<?> clazz = alias.getClass();
- define(clazz).createIfRequired(this);
- return Query.from(this, alias);
- }
-
- @SuppressWarnings("unchecked")
- public <T> int dropTable(Class<? extends T> modelClass) {
- TableDefinition<T> def = (TableDefinition<T>) define(modelClass);
- SQLStatement stat = new SQLStatement(this);
- getDialect().prepareDropTable(stat, def);
- IciqlLogger.drop(stat.getSQL());
- int rc = 0;
- try {
- rc = stat.executeUpdate();
- } catch (IciqlException e) {
- if (e.getIciqlCode() != IciqlException.CODE_OBJECT_NOT_FOUND) {
- throw e;
- }
- }
- // remove this model class from the table definition cache
- classMap.remove(modelClass);
- // remove this model class from the upgrade checked cache
- upgradeChecked.remove(modelClass);
- return rc;
- }
-
- @SuppressWarnings("unchecked")
- public <T> int dropView(Class<? extends T> modelClass) {
- TableDefinition<T> def = (TableDefinition<T>) define(modelClass);
- SQLStatement stat = new SQLStatement(this);
- getDialect().prepareDropView(stat, def);
- IciqlLogger.drop(stat.getSQL());
- int rc = 0;
- try {
- rc = stat.executeUpdate();
- } catch (IciqlException e) {
- if (e.getIciqlCode() != IciqlException.CODE_OBJECT_NOT_FOUND) {
- throw e;
- }
- }
- // remove this model class from the table definition cache
- classMap.remove(modelClass);
- // remove this model class from the upgrade checked cache
- upgradeChecked.remove(modelClass);
- return rc;
- }
-
- public <T> List<T> buildObjects(Class<? extends T> modelClass, ResultSet rs) {
- return buildObjects(modelClass, false, rs);
- }
-
- @SuppressWarnings("unchecked")
- public <T> List<T> buildObjects(Class<? extends T> modelClass, boolean wildcardSelect, ResultSet rs) {
- List<T> result = new ArrayList<T>();
- TableDefinition<T> def = (TableDefinition<T>) define(modelClass);
- try {
- int[] columns = def.mapColumns(wildcardSelect, rs);
- while (rs.next()) {
- T item = Utils.newObject(modelClass);
- def.readRow(item, rs, columns);
- result.add(item);
- }
- } catch (SQLException e) {
- throw new IciqlException(e);
- }
- return result;
- }
-
- Db upgradeDb() {
- if (!upgradeChecked.contains(dbUpgrader.getClass())) {
- // flag as checked immediately because calls are nested.
- upgradeChecked.add(dbUpgrader.getClass());
-
- IQVersion model = dbUpgrader.getClass().getAnnotation(IQVersion.class);
- if (model.value() == 0) {
- // try superclass
- Class<?> superClass = dbUpgrader.getClass().getSuperclass();
- if (superClass.isAnnotationPresent(IQVersion.class)) {
- model = superClass.getAnnotation(IQVersion.class);
- }
- }
- if (model.value() > 0) {
- DbVersion v = new DbVersion();
- // (SCHEMA="" && TABLE="") == DATABASE
- DbVersion dbVersion = from(v).where(v.schemaName).is("").and(v.tableName).is("")
- .selectFirst();
- if (dbVersion == null) {
- // database has no version registration, but model specifies
- // version: insert DbVersion entry and return.
- DbVersion newDb = new DbVersion(model.value());
- // database is an older version than the model
- boolean success = dbUpgrader.upgradeDatabase(this, 0, newDb.version);
- if (success) {
- insert(newDb);
- }
- } else {
- // database has a version registration:
- // check to see if upgrade is required.
- if ((model.value() > dbVersion.version) && (dbUpgrader != null)) {
- // database is an older version than the model
- boolean success = dbUpgrader.upgradeDatabase(this, dbVersion.version, model.value());
- if (success) {
- dbVersion.version = model.value();
- update(dbVersion);
- }
- }
- }
- }
- }
- return this;
- }
-
- <T> void upgradeTable(TableDefinition<T> model) {
- if (!upgradeChecked.contains(model.getModelClass())) {
- // flag is checked immediately because calls are nested
- upgradeChecked.add(model.getModelClass());
-
- if (model.tableVersion > 0) {
- // table is using iciql version tracking.
- DbVersion v = new DbVersion();
- String schema = StringUtils.isNullOrEmpty(model.schemaName) ? "" : model.schemaName;
- DbVersion dbVersion = from(v).where(v.schemaName).is(schema).and(v.tableName)
- .is(model.tableName).selectFirst();
- if (dbVersion == null) {
- // table has no version registration, but model specifies
- // version: insert DbVersion entry
- DbVersion newTable = new DbVersion(model.tableVersion);
- newTable.schemaName = schema;
- newTable.tableName = model.tableName;
- insert(newTable);
- } else {
- // table has a version registration:
- // check if upgrade is required
- if ((model.tableVersion > dbVersion.version) && (dbUpgrader != null)) {
- // table is an older version than model
- boolean success = dbUpgrader.upgradeTable(this, schema, model.tableName,
- dbVersion.version, model.tableVersion);
- if (success) {
- dbVersion.version = model.tableVersion;
- update(dbVersion);
- }
- }
- }
- }
- }
- }
-
- <T> TableDefinition<T> define(Class<T> clazz) {
- TableDefinition<T> def = getTableDefinition(clazz);
- if (def == null) {
- upgradeDb();
- def = new TableDefinition<T>(clazz);
- def.mapFields();
- classMap.put(clazz, def);
- if (Iciql.class.isAssignableFrom(clazz)) {
- T t = instance(clazz);
- Iciql table = (Iciql) t;
- Define.define(def, table);
- } else if (clazz.isAnnotationPresent(IQTable.class)) {
- // annotated classes skip the Define().define() static
- // initializer
- T t = instance(clazz);
- def.mapObject(t);
- } else if (clazz.isAnnotationPresent(IQView.class)) {
- // annotated classes skip the Define().define() static
- // initializer
- T t = instance(clazz);
- def.mapObject(t);
- }
- }
- return def;
- }
-
- <T> boolean hasCreated(Class<T> clazz) {
- return upgradeChecked.contains(clazz);
- }
-
- public synchronized void setDbUpgrader(DbUpgrader upgrader) {
- if (!upgrader.getClass().isAnnotationPresent(IQVersion.class)) {
- throw new IciqlException("DbUpgrader must be annotated with " + IQVersion.class.getSimpleName());
- }
- this.dbUpgrader = upgrader;
- upgradeChecked.clear();
- }
-
- public SQLDialect getDialect() {
- return dialect;
- }
-
- public Connection getConnection() {
- return conn;
- }
-
- public void close() {
- try {
- conn.close();
- } catch (Exception e) {
- throw new IciqlException(e);
- }
- }
-
- public <A> TestCondition<A> test(A x) {
- return new TestCondition<A>(x);
- }
-
- public <T> void insertAll(List<T> list) {
- if (list.size() == 0) {
- return;
- }
- Savepoint savepoint = null;
- try {
- Class<?> clazz = list.get(0).getClass();
- TableDefinition<?> def = define(clazz).createIfRequired(this);
- savepoint = prepareSavepoint();
- for (T t : list) {
- PreparedStatement ps = def.createInsertStatement(this, t, false);
- int rc = ps.executeUpdate();
- if (rc == 0) {
- throw new IciqlException("Failed to insert {0}. Affected rowcount == 0.", t);
- }
- }
- commit(savepoint);
- } catch (SQLException e) {
- rollback(savepoint);
- throw new IciqlException(e);
- } catch (IciqlException e) {
- rollback(savepoint);
- throw e;
- }
- }
-
- public <T> List<Long> insertAllAndGetKeys(List<T> list) {
- List<Long> identities = new ArrayList<Long>();
- if (list.size() == 0) {
- return identities;
- }
- Savepoint savepoint = null;
- try {
- Class<?> clazz = list.get(0).getClass();
- TableDefinition<?> def = define(clazz).createIfRequired(this);
- savepoint = prepareSavepoint();
- for (T t : list) {
- long key = def.insert(this, t, true);
- identities.add(key);
- }
- commit(savepoint);
- } catch (IciqlException e) {
- rollback(savepoint);
- throw e;
- }
- return identities;
- }
-
- public <T> void updateAll(List<T> list) {
- if (list.size() == 0) {
- return;
- }
- Savepoint savepoint = null;
- try {
- Class<?> clazz = list.get(0).getClass();
- TableDefinition<?> def = define(clazz).createIfRequired(this);
- savepoint = prepareSavepoint();
- for (T t : list) {
- def.update(this, t);
- }
- commit(savepoint);
- } catch (IciqlException e) {
- rollback(savepoint);
- throw e;
- }
- }
-
- public <T> void deleteAll(List<T> list) {
- if (list.size() == 0) {
- return;
- }
- Savepoint savepoint = null;
- try {
- Class<?> clazz = list.get(0).getClass();
- TableDefinition<?> def = define(clazz).createIfRequired(this);
- savepoint = prepareSavepoint();
- for (T t : list) {
- def.delete(this, t);
- }
- commit(savepoint);
- } catch (IciqlException e) {
- rollback(savepoint);
- throw e;
- }
- }
-
- PreparedStatement prepare(String sql, boolean returnGeneratedKeys) {
- IciqlException.checkUnmappedField(sql);
- try {
- if (returnGeneratedKeys) {
- return conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
- }
- return conn.prepareStatement(sql);
- } catch (SQLException e) {
- throw IciqlException.fromSQL(sql, e);
- }
- }
-
- Savepoint prepareSavepoint() {
- // don't change auto-commit mode.
- // don't create save point.
- if (!autoSavePoint) {
- return null;
- }
- // create a savepoint
- Savepoint savepoint = null;
- try {
- conn.setAutoCommit(false);
- savepoint = conn.setSavepoint();
- } catch (SQLFeatureNotSupportedException e) {
- // jdbc driver does not support save points
- } catch (SQLException e) {
- throw new IciqlException(e, "Could not create save point");
- }
- return savepoint;
- }
-
- void commit(Savepoint savepoint) {
- if (savepoint != null) {
- try {
- conn.commit();
- conn.setAutoCommit(true);
- } catch (SQLException e) {
- throw new IciqlException(e, "Failed to commit pending transactions");
- }
- }
- }
-
- void rollback(Savepoint savepoint) {
- if (savepoint != null) {
- try {
- conn.rollback(savepoint);
- conn.setAutoCommit(true);
- } catch (SQLException s) {
- throw new IciqlException(s, "Failed to rollback transactions");
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- <T> TableDefinition<T> getTableDefinition(Class<T> clazz) {
- return (TableDefinition<T>) classMap.get(clazz);
- }
-
- /**
- * Run a SQL query directly against the database.
- *
- * Be sure to close the ResultSet with
- *
- * <pre>
- * JdbcUtils.closeSilently(rs, true);
- * </pre>
- *
- * @param sql
- * the SQL statement
- * @param args
- * optional object arguments for x=? tokens in query
- * @return the result set
- */
- public ResultSet executeQuery(String sql, List<?> args) {
- return executeQuery(sql, args.toArray());
- }
-
- /**
- * Run a SQL query directly against the database.
- *
- * Be sure to close the ResultSet with
- *
- * <pre>
- * JdbcUtils.closeSilently(rs, true);
- * </pre>
- *
- * @param sql
- * the SQL statement
- * @param args
- * optional object arguments for x=? tokens in query
- * @return the result set
- */
- public ResultSet executeQuery(String sql, Object... args) {
- try {
- if (args.length == 0) {
- return conn.createStatement().executeQuery(sql);
- } else {
- PreparedStatement stat = conn.prepareStatement(sql);
- int i = 1;
- for (Object arg : args) {
- stat.setObject(i++, arg);
- }
- return stat.executeQuery();
- }
- } catch (SQLException e) {
- throw new IciqlException(e);
- }
- }
-
- /**
- * Run a SQL query directly against the database and map the results to the
- * model class.
- *
- * @param modelClass
- * the model class to bind the query ResultSet rows into.
- * @param sql
- * the SQL statement
- * @return the result set
- */
- public <T> List<T> executeQuery(Class<? extends T> modelClass, String sql, List<?> args) {
- return executeQuery(modelClass, sql, args.toArray());
- }
-
- /**
- * Run a SQL query directly against the database and map the results to the
- * model class.
- *
- * @param modelClass
- * the model class to bind the query ResultSet rows into.
- * @param sql
- * the SQL statement
- * @return the result set
- */
- public <T> List<T> executeQuery(Class<? extends T> modelClass, String sql, Object... args) {
- ResultSet rs = null;
- try {
- if (args.length == 0) {
- rs = conn.createStatement().executeQuery(sql);
- } else {
- PreparedStatement stat = conn.prepareStatement(sql);
- int i = 1;
- for (Object arg : args) {
- stat.setObject(i++, arg);
- }
- rs = stat.executeQuery();
- }
- boolean wildcardSelect = sql.toLowerCase().startsWith("select *")
- || sql.toLowerCase().startsWith("select distinct *");
- return buildObjects(modelClass, wildcardSelect, rs);
- } catch (SQLException e) {
- throw new IciqlException(e);
- } finally {
- JdbcUtils.closeSilently(rs, true);
- }
- }
-
- /**
- * Run a SQL statement directly against the database.
- *
- * @param sql
- * the SQL statement
- * @return the update count
- */
- public int executeUpdate(String sql, Object... args) {
- Statement stat = null;
- try {
- int updateCount;
- if (args.length == 0) {
- stat = conn.createStatement();
- updateCount = stat.executeUpdate(sql);
- } else {
- PreparedStatement ps = conn.prepareStatement(sql);
- int i = 1;
- for (Object arg : args) {
- ps.setObject(i++, arg);
- }
- updateCount = ps.executeUpdate();
- stat = ps;
- }
- return updateCount;
- } catch (SQLException e) {
- throw new IciqlException(e);
- } finally {
- JdbcUtils.closeSilently(stat);
- }
- }
-
- /**
- * Allow to enable/disable globally createIfRequired in TableDefinition.
- * For advanced user wanting to gain full control of transactions.
- * Default value is false.
- * @param skipCreate
- */
- public void setSkipCreate(boolean skipCreate) {
- this.skipCreate = skipCreate;
- }
-
- public boolean getSkipCreate() {
- return this.skipCreate;
- }
-
- /**
- * Allow to enable/disable usage of save point.
- * For advanced user wanting to gain full control of transactions.
- * Default value is false.
- * @param autoSavePoint
- */
- public void setAutoSavePoint(boolean autoSavePoint) {
- this.autoSavePoint = autoSavePoint;
- }
-
- public boolean getAutoSavePoint() {
- return this.autoSavePoint;
- }
-
-}
diff --git a/src/com/iciql/DbInspector.java b/src/com/iciql/DbInspector.java deleted file mode 100644 index acaceea..0000000 --- a/src/com/iciql/DbInspector.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql; - -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.List; - -import com.iciql.Iciql.IQTable; -import com.iciql.util.JdbcUtils; -import com.iciql.util.StringUtils; -import com.iciql.util.Utils; - -/** - * Class to inspect a model and a database for the purposes of model validation - * and automatic model generation. This class finds the available schemas and - * tables and serves as the entry point for model generation and validation. - */ -public class DbInspector { - - private Db db; - private DatabaseMetaData metaData; - private Class<? extends java.util.Date> dateTimeClass = java.util.Date.class; - - public DbInspector(Db db) { - this.db = db; - setPreferredDateTimeClass(db.getDialect().getDateTimeClass()); - } - - /** - * Set the preferred class to store date and time. Possible values are: - * java.util.Date (default) and java.sql.Timestamp. - * - * @param dateTimeClass - * the new class - */ - public void setPreferredDateTimeClass(Class<? extends java.util.Date> dateTimeClass) { - this.dateTimeClass = dateTimeClass; - } - - /** - * Generates models class skeletons for schemas and tables. If the table - * name is undefined, models will be generated for every table within the - * specified schema. Additionally, if no schema is defined, models will be - * generated for all schemas and all tables. - * - * @param schema - * the schema name (optional) - * @param table - * the table name (optional) - * @param packageName - * the package name (optional) - * @param annotateSchema - * (includes schema name in annotation) - * @param trimStrings - * (trims strings to maxLength of column) - * @return a list of complete model classes as strings, each element a class - */ - public List<String> generateModel(String schema, String table, String packageName, - boolean annotateSchema, boolean trimStrings) { - try { - List<String> models = Utils.newArrayList(); - List<TableInspector> tables = getTables(schema, table); - for (TableInspector t : tables) { - t.read(metaData); - String model = t.generateModel(packageName, annotateSchema, trimStrings); - models.add(model); - } - return models; - } catch (SQLException s) { - throw new IciqlException(s); - } - } - - /** - * Validates a model. - * - * @param model - * an instance of the model class - * @param throwOnError - * if errors should cause validation to fail - * @return a list of validation remarks - */ - public <T> List<ValidationRemark> validateModel(T model, boolean throwOnError) { - try { - TableInspector inspector = getTable(model); - inspector.read(metaData); - @SuppressWarnings("unchecked") - Class<T> clazz = (Class<T>) model.getClass(); - TableDefinition<T> def = db.define(clazz); - return inspector.validate(def, throwOnError); - } catch (SQLException s) { - throw new IciqlException(s); - } - } - - private DatabaseMetaData getMetaData() throws SQLException { - if (metaData == null) { - metaData = db.getConnection().getMetaData(); - } - return metaData; - } - - /** - * Get the table in the database based on the model definition. - * - * @param model - * an instance of the model class - * @return the table inspector - */ - private <T> TableInspector getTable(T model) throws SQLException { - @SuppressWarnings("unchecked") - Class<T> clazz = (Class<T>) model.getClass(); - TableDefinition<T> def = db.define(clazz); - boolean forceUpperCase = getMetaData().storesUpperCaseIdentifiers(); - String schema = (forceUpperCase && def.schemaName != null) ? def.schemaName.toUpperCase() - : def.schemaName; - String table = forceUpperCase ? def.tableName.toUpperCase() : def.tableName; - List<TableInspector> tables = getTables(schema, table); - return tables.get(0); - } - - /** - * Returns a list of tables. This method always returns at least one - * element. If no table is found, an exception is thrown. - * - * @param schema - * the schema name - * @param table - * the table name - * @return a list of table inspectors (always contains at least one element) - */ - private List<TableInspector> getTables(String schema, String table) throws SQLException { - ResultSet rs = null; - try { - rs = getMetaData().getSchemas(); - ArrayList<String> schemaList = Utils.newArrayList(); - while (rs.next()) { - schemaList.add(rs.getString("TABLE_SCHEM")); - } - JdbcUtils.closeSilently(rs); - - String iciqlTables = DbVersion.class.getAnnotation(IQTable.class).name(); - - List<TableInspector> tables = Utils.newArrayList(); - if (schemaList.size() == 0) { - schemaList.add(null); - } - for (String s : schemaList) { - rs = getMetaData().getTables(null, s, null, new String[] { "TABLE" }); - while (rs.next()) { - String t = rs.getString("TABLE_NAME"); - if (t.charAt(0) == '"') { - t = t.substring(1); - } - if (t.charAt(t.length() - 1) == '"') { - t = t.substring(0, t.length() - 1); - } - if (!t.equalsIgnoreCase(iciqlTables)) { - tables.add(new TableInspector(s, t, dateTimeClass)); - } - } - } - - if (StringUtils.isNullOrEmpty(schema) && StringUtils.isNullOrEmpty(table)) { - // all schemas and tables - return tables; - } - // schema subset OR table subset OR exact match - List<TableInspector> matches = Utils.newArrayList(); - for (TableInspector t : tables) { - if (t.matches(schema, table)) { - matches.add(t); - } - } - if (matches.size() == 0) { - throw new IciqlException(MessageFormat.format("Failed to find schema={0} table={1}", - schema == null ? "" : schema, table == null ? "" : table)); - } - return matches; - } finally { - JdbcUtils.closeSilently(rs); - } - } - -} diff --git a/src/com/iciql/DbUpgrader.java b/src/com/iciql/DbUpgrader.java deleted file mode 100644 index 1303f4e..0000000 --- a/src/com/iciql/DbUpgrader.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql; - -import com.iciql.Iciql.IQVersion; - -/** - * Interface which defines a class to handle table changes based on model - * versions. An implementation of <i>DbUpgrader</i> must be annotated with the - * <i>IQDatabase</i> annotation, which defines the expected database version - * number. - */ -public interface DbUpgrader { - - /** - * Defines method interface to handle database upgrades. This method is only - * called if your <i>DbUpgrader</i> implementation is annotated with - * IQDatabase. - * - * @param db - * the database - * @param fromVersion - * the old version - * @param toVersion - * the new version - * @return true for successful upgrade. If the upgrade is successful, the - * version registry is automatically updated. - */ - boolean upgradeDatabase(Db db, int fromVersion, int toVersion); - - /** - * Defines method interface to handle table upgrades. - * - * @param db - * the database - * @param schema - * the schema - * @param table - * the table - * @param fromVersion - * the old version - * @param toVersion - * the new version - * @return true for successful upgrade. If the upgrade is successful, the - * version registry is automatically updated. - */ - boolean upgradeTable(Db db, String schema, String table, int fromVersion, int toVersion); - - /** - * The default database upgrader. It throws runtime exception instead of - * handling upgrade requests. - */ - @IQVersion(0) - public static class DefaultDbUpgrader implements DbUpgrader { - - public boolean upgradeDatabase(Db db, int fromVersion, int toVersion) { - throw new IciqlException("Please provide your own DbUpgrader implementation."); - } - - public boolean upgradeTable(Db db, String schema, String table, int fromVersion, int toVersion) { - throw new IciqlException("Please provide your own DbUpgrader implementation."); - } - - } - -} diff --git a/src/com/iciql/DbVersion.java b/src/com/iciql/DbVersion.java deleted file mode 100644 index 6270e14..0000000 --- a/src/com/iciql/DbVersion.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql; - -import com.iciql.Iciql.IQColumn; -import com.iciql.Iciql.IQTable; - -/** - * A system table to track database and table versions. - */ -@IQTable(name = "iq_versions", primaryKey = { "schemaName", "tableName" }, memoryTable = true) -public class DbVersion { - - @IQColumn(length = 255) - String schemaName = ""; - - @IQColumn(length = 255) - String tableName = ""; - - @IQColumn - Integer version; - - public DbVersion() { - // nothing to do - } - - /** - * Constructor for defining a version entry. Both the schema and the table - * are empty strings, which means this is the row for the 'database'. - * - * @param version - * the database version - */ - public DbVersion(int version) { - this.schemaName = ""; - this.tableName = ""; - this.version = version; - } - -} diff --git a/src/com/iciql/Define.java b/src/com/iciql/Define.java deleted file mode 100644 index 1810a4b..0000000 --- a/src/com/iciql/Define.java +++ /dev/null @@ -1,145 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- * Copyright 2012 Frédéric Gaillard.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import com.iciql.Iciql.IndexType;
-
-/**
- * This class provides utility methods to define primary keys, indexes, and set
- * the name of the table.
- */
-
-public class Define {
-
- private static TableDefinition<?> currentTableDefinition;
- private static Iciql currentTable;
-
- public static void skipCreate() {
- checkInDefine();
- currentTableDefinition.defineSkipCreate();
- }
-
- public static void index(IndexType type, Object... columns) {
- checkInDefine();
- currentTableDefinition.defineIndex(null, type, columns);
- }
-
- public static void index(String name, IndexType type, Object... columns) {
- checkInDefine();
- currentTableDefinition.defineIndex(name, type, columns);
- }
-
- public static void constraintUnique(String name, Object... columns) {
- checkInDefine();
- currentTableDefinition.defineConstraintUnique(name, columns);
- }
-
- /*
- * The variable argument type Object can't be used twice :-)
- */
-// public static void constraintForeignKey(String name, String refTableName,
-// ConstraintDeleteType deleteType, ConstraintUpdateType updateType,
-// ConstraintDeferrabilityType deferrabilityType, Object... columns, Object... refColumns) {
-// checkInDefine();
-// currentTableDefinition.defineForeignKey(name, columns, refTableName, Columns, deleteType, updateType, deferrabilityType);
-// }
-
- public static void primaryKey(Object... columns) {
- checkInDefine();
- currentTableDefinition.definePrimaryKey(columns);
- }
-
- public static void schemaName(String schemaName) {
- checkInDefine();
- currentTableDefinition.defineSchemaName(schemaName);
- }
-
- public static void tableName(String tableName) {
- checkInDefine();
- currentTableDefinition.defineTableName(tableName);
- }
-
- public static void viewTableName(String viewTableName) {
- checkInDefine();
- currentTableDefinition.defineViewTableName(viewTableName);
- }
-
- public static void memoryTable() {
- checkInDefine();
- currentTableDefinition.defineMemoryTable();
- }
-
- public static void columnName(Object column, String columnName) {
- checkInDefine();
- currentTableDefinition.defineColumnName(column, columnName);
- }
-
- public static void autoIncrement(Object column) {
- checkInDefine();
- currentTableDefinition.defineAutoIncrement(column);
- }
-
- public static void length(Object column, int length) {
- checkInDefine();
- currentTableDefinition.defineLength(column, length);
- }
-
- public static void scale(Object column, int scale) {
- checkInDefine();
- currentTableDefinition.defineScale(column, scale);
- }
-
- public static void trim(Object column) {
- checkInDefine();
- currentTableDefinition.defineTrim(column);
- }
-
- public static void nullable(Object column, boolean isNullable) {
- checkInDefine();
- currentTableDefinition.defineNullable(column, isNullable);
- }
-
- public static void defaultValue(Object column, String defaultValue) {
- checkInDefine();
- currentTableDefinition.defineDefaultValue(column, defaultValue);
- }
-
- public static void constraint(Object column, String constraint) {
- checkInDefine();
- currentTableDefinition.defineConstraint(column, constraint);
- }
-
- static synchronized <T> void define(TableDefinition<T> tableDefinition, Iciql table) {
- currentTableDefinition = tableDefinition;
- currentTable = table;
- tableDefinition.mapObject(table);
- table.defineIQ();
- currentTable = null;
- currentTableDefinition = null;
- }
-
- private static void checkInDefine() {
- if (currentTable == null) {
- throw new IciqlException("This method may only be called "
- + "from within the define() method, and the define() method "
- + "is called by the framework.");
- }
- }
-
-}
diff --git a/src/com/iciql/Filter.java b/src/com/iciql/Filter.java deleted file mode 100644 index 99dbdc3..0000000 --- a/src/com/iciql/Filter.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql; - -/** - * Represents the WHERE clause of a query. - */ -public interface Filter { - boolean where(); -} diff --git a/src/com/iciql/Function.java b/src/com/iciql/Function.java deleted file mode 100644 index 3faddb7..0000000 --- a/src/com/iciql/Function.java +++ /dev/null @@ -1,149 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import com.iciql.util.Utils;
-
-/**
- * This class provides static methods that represents common SQL functions.
- */
-public class Function implements Token {
-
- // must be a new instance
- private static final Long COUNT_STAR = new Long(0);
-
- protected Object[] x;
- private String name;
-
- protected Function(String name, Object... x) {
- this.name = name;
- this.x = x;
- }
-
- public <T> void appendSQL(SQLStatement stat, Query<T> query) {
- stat.appendSQL(name).appendSQL("(");
- int i = 0;
- for (Object o : x) {
- if (i++ > 0) {
- stat.appendSQL(",");
- }
- query.appendSQL(stat, null, o);
- }
- stat.appendSQL(")");
- }
-
- public static Long count() {
- return COUNT_STAR;
- }
-
- public static Integer length(Object x) {
- return Db.registerToken(Utils.newObject(Integer.class), new Function("LENGTH", x));
- }
-
- @SuppressWarnings("unchecked")
- public static <T extends Number> T sum(T x) {
- return (T) Db.registerToken(Utils.newObject(x.getClass()), new Function("SUM", x));
- }
-
- public static Long count(Object x) {
- return Db.registerToken(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 <T> void appendSQL(SQLStatement stat, Query<T> query) {
- query.appendSQL(stat, null, x[0]);
- stat.appendSQL(" IS NULL");
- }
- });
- }
-
- public static Boolean isNotNull(Object x) {
- return Db.registerToken(Utils.newObject(Boolean.class), new Function("", x) {
- public <T> void appendSQL(SQLStatement stat, Query<T> query) {
- query.appendSQL(stat, null, x[0]);
- stat.appendSQL(" IS NOT NULL");
- }
- });
- }
-
- public static Boolean not(Boolean x) {
- return Db.registerToken(Utils.newObject(Boolean.class), new Function("", x) {
- public <T> void appendSQL(SQLStatement stat, Query<T> query) {
- stat.appendSQL("NOT ");
- query.appendSQL(stat, null, x[0]);
- }
- });
- }
-
- public static Boolean or(Boolean... x) {
- return Db.registerToken(Utils.newObject(Boolean.class), new Function("", (Object[]) x) {
- public <T> void appendSQL(SQLStatement stat, Query<T> query) {
- int i = 0;
- for (Object o : x) {
- if (i++ > 0) {
- stat.appendSQL(" OR ");
- }
- query.appendSQL(stat, null, o);
- }
- }
- });
- }
-
- public static Boolean and(Boolean... x) {
- return Db.registerToken(Utils.newObject(Boolean.class), new Function("", (Object[]) x) {
- public <T> void appendSQL(SQLStatement stat, Query<T> query) {
- int i = 0;
- for (Object o : x) {
- if (i++ > 0) {
- stat.appendSQL(" AND ");
- }
- query.appendSQL(stat, null, o);
- }
- }
- });
- }
-
- @SuppressWarnings("unchecked")
- public static <X> X min(X x) {
- Class<X> clazz = (Class<X>) x.getClass();
- X o = Utils.newObject(clazz);
- return Db.registerToken(o, new Function("MIN", x));
- }
-
- @SuppressWarnings("unchecked")
- public static <X> X max(X x) {
- Class<X> clazz = (Class<X>) x.getClass();
- X o = Utils.newObject(clazz);
- 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 <T> void appendSQL(SQLStatement stat, Query<T> query) {
- stat.appendSQL("(");
- query.appendSQL(stat, null, x[0]);
- stat.appendSQL(" LIKE ");
- query.appendSQL(stat, x[0], x[1]);
- stat.appendSQL(")");
- }
- });
- }
-
-}
diff --git a/src/com/iciql/Iciql.java b/src/com/iciql/Iciql.java deleted file mode 100644 index 9f73ffa..0000000 --- a/src/com/iciql/Iciql.java +++ /dev/null @@ -1,731 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- * Copyright 2012 Frédéric Gaillard.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * A class that implements this interface can be used as a database table.
- * <p>
- * You may implement the Table interface on your model object and optionally use
- * IQColumn annotations (which imposes a compile-time and runtime-dependency on
- * iciql), or may choose to use the IQTable and IQColumn annotations only (which
- * imposes a compile-time and runtime-dependency on this file only).
- * <p>
- * If a class is annotated with IQTable and at the same time implements Table,
- * the define() method is not called.
- * <p>
- * Fully Supported Data Types:
- * <table>
- * <tr>
- * <th colspan="2">All Databases</th>
- * </tr>
- * <tr>
- * <td>java.lang.String</td>
- * <td>VARCHAR (length > 0) or CLOB (length == 0)</td>
- * </tr>
- * <tr>
- * <td>java.lang.Boolean</td>
- * <td>BIT</td>
- * </tr>
- * <tr>
- * <td>java.lang.Byte</td>
- * <td>TINYINT</td>
- * </tr>
- * <tr>
- * <td>java.lang.Short</td>
- * <td>SMALLINT</td>
- * </tr>
- * <tr>
- * <td>java.lang.Integer</td>
- * <td>INT</td>
- * </tr>
- * <tr>
- * <td>java.lang.Long</td>
- * <td>BIGINT</td>
- * </tr>
- * <tr>
- * <td>java.lang.Float</td>
- * <td>REAL</td>
- * </tr>
- * <tr>
- * <td>java.lang.Double</td>
- * <td>DOUBLE</td>
- * </tr>
- * <tr>
- * <td>java.math.BigDecimal</td>
- * <td>DECIMAL (length == 0)<br/>
- * DECIMAL(length, scale) (length > 0)</td>
- * </tr>
- * <tr>
- * <td>java.sql.Date</td>
- * <td>DATE</td>
- * </tr>
- * <tr>
- * <td>java.sql.Time</td>
- * <td>TIME</td>
- * </tr>
- * <tr>
- * <td>java.sql.Timestamp</td>
- * <td>TIMESTAMP</td>
- * </tr>
- * <tr>
- * <td>java.util.Date</td>
- * <td>TIMESTAMP</td>
- * </tr>
- * <tr>
- * <td>java.lang.Enum.name()</td>
- * <td>VARCHAR (length > 0) or CLOB (length == 0)<br/>
- * EnumType.NAME</td>
- * </tr>
- * <tr>
- * <td>java.lang.Enum.ordinal()</td>
- * <td>INT<br/>
- * EnumType.ORDINAL</td>
- * </tr>
- * <tr>
- * <td>java.lang.Enum implements<br/>
- * com.iciql.Iciql.EnumID.enumId()</td>
- * <td>INT<br/>
- * EnumType.ENUMID</td>
- * </tr>
- * <tr>
- * <th colspan="2">H2 Databases</th>
- * </tr>
- * <tr>
- * <td>java.util.UUID</td>
- * <td>UUID</td>
- * </tr>
- * </table>
- * <p>
- * Partially Supported Data Types:
- * <p>
- * The following data types can be mapped to columns for all general statements
- * BUT these field types may not be used to specify compile-time clauses or
- * constraints.
- * <table>
- * <tr>
- * <td>byte []</td>
- * <td>BLOB</td>
- * </tr>
- * <tr>
- * <td>boolean</td>
- * <td>BIT</td>
- * </tr>
- * <tr>
- * <td>byte</td>
- * <td>TINYINT</td>
- * </tr>
- * <tr>
- * <td>short</td>
- * <td>SMALLINT</td>
- * </tr>
- * <tr>
- * <td>int</td>
- * <td>INT</td>
- * </tr>
- * <tr>
- * <td>long</td>
- * <td>BIGINT</td>
- * </tr>
- * <tr>
- * <td>float</td>
- * <td>REAL</td>
- * </tr>
- * <tr>
- * <td>double</td>
- * <td>DOUBLE</td>
- * </tr>
- * </table>
- * <p>
- * Table and field mapping: by default, the mapped table name is the class name
- * and the public fields are reflectively mapped, by their name, to columns. As
- * an alternative, you may specify both the table and column definition by
- * annotations.
- * <p>
- * Table Interface: you may set additional parameters such as table name,
- * primary key, and indexes in the define() method.
- * <p>
- * Annotations: you may use the annotations with or without implementing the
- * Table interface. The annotations allow you to decouple your model completely
- * from iciql other than this file.
- * <p>
- * Automatic model generation: you may automatically generate model classes as
- * strings with the Db and DbInspector objects:
- *
- * <pre>
- * Db db = Db.open("jdbc:h2:mem:", "sa", "sa");
- * DbInspector inspector = new DbInspector(db);
- * List<String> models =
- * inspector.generateModel(schema, table, packageName,
- * annotateSchema, trimStrings)
- * </pre>
- *
- * Or you may use the GenerateModels tool to generate and save your classes to
- * the file system:
- *
- * <pre>
- * java -jar iciql.jar
- * -url "jdbc:h2:mem:"
- * -user sa -password sa -schema schemaName -table tableName
- * -package packageName -folder destination
- * -annotateSchema false -trimStrings true
- * </pre>
- *
- * Model validation: you may validate your model class with DbInspector object.
- * The DbInspector will report errors, warnings, and suggestions:
- *
- * <pre>
- * Db db = Db.open("jdbc:h2:mem:", "sa", "sa");
- * DbInspector inspector = new DbInspector(db);
- * List<Validation> remarks = inspector.validateModel(new MyModel(), throwOnError);
- * for (Validation remark : remarks) {
- * System.out.println(remark);
- * }
- * </pre>
- */
-public interface Iciql {
-
- /**
- * An annotation for an iciql version.
- * <p>
- *
- * @IQVersion(1)
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.TYPE)
- public @interface IQVersion {
-
- /**
- * If set to a non-zero value, iciql maintains a "iq_versions" table
- * within your database. The version number is used to call to a
- * registered DbUpgrader implementation to perform relevant ALTER
- * statements. Default: 0. You must specify a DbUpgrader on your Db
- * object to use this parameter.
- */
- int value() default 0;
-
- }
-
- /**
- * An annotation for a schema.
- * <p>
- *
- * @IQSchema("PUBLIC")
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.TYPE)
- public @interface IQSchema {
-
- /**
- * The schema may be optionally specified. Default: unspecified.
- */
- String value() default "";
-
- }
-
- /**
- * Enumeration defining the four index types.
- */
- public static enum IndexType {
- STANDARD, UNIQUE, HASH, UNIQUE_HASH;
- }
-
- /**
- * An index annotation.
- * <p>
- * <ul>
- * <li>@IQIndex("name")
- * <li>@IQIndex({"street", "city"})
- * <li>@IQIndex(name="streetidx", value={"street", "city"})
- * <li>@IQIndex(name="addressidx", type=IndexType.UNIQUE,
- * value={"house_number", "street", "city"})
- * </ul>
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.TYPE)
- public @interface IQIndex {
-
- /**
- * Index name. If null or empty, iciql will generate one.
- */
- String name() default "";
-
- /**
- * Type of the index.
- * <ul>
- * <li>com.iciql.iciql.IndexType.STANDARD
- * <li>com.iciql.iciql.IndexType.UNIQUE
- * <li>com.iciql.iciql.IndexType.HASH
- * <li>com.iciql.iciql.IndexType.UNIQUE_HASH
- * </ul>
- *
- * HASH indexes may only be valid for single column indexes.
- *
- */
- IndexType type() default IndexType.STANDARD;
-
- /**
- * Columns to include in index.
- * <ul>
- * <li>single column index: value = "id"
- * <li>multiple column index: value = { "id", "name", "date" }
- * </ul>
- */
- String[] value() default {};
- }
-
- /**
- * Enumeration defining the ON DELETE actions.
- */
- public static enum ConstraintDeleteType {
- UNSET, CASCADE, RESTRICT, SET_NULL, NO_ACTION, SET_DEFAULT;
- }
-
- /**
- * Enumeration defining the ON UPDATE actions.
- */
- public static enum ConstraintUpdateType {
- UNSET, CASCADE, RESTRICT, SET_NULL, NO_ACTION, SET_DEFAULT;
- }
-
- /**
- * Enumeration defining the deferrability.
- */
- public static enum ConstraintDeferrabilityType {
- UNSET, DEFERRABLE_INITIALLY_DEFERRED, DEFERRABLE_INITIALLY_IMMEDIATE, NOT_DEFERRABLE;
- }
-
- /**
- * A foreign key constraint annotation.
- * <p>
- * <ul>
- * <li>@IQContraintForeignKey(
- * foreignColumns = { "idaccount"},
- * referenceName = "account",
- * referenceColumns = { "id" },
- * deleteType = ConstrainDeleteType.CASCADE,
- * updateType = ConstraintUpdateType.NO_ACTION )
- * </ul>
- * Note : reference columns should have a unique constraint defined in referenceName table,
- * some database used to define a unique index instead of a unique constraint
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.TYPE)
- public @interface IQContraintForeignKey {
-
- /**
- * Constraint name. If null or empty, iciql will generate one.
- */
- String name() default "";
-
- /**
- * Type of the action on delete, default to unspecified.
- * <ul>
- * <li>com.iciql.iciql.ConstrainDeleteType.CASCADE
- * <li>com.iciql.iciql.ConstrainDeleteType.RESTRICT
- * <li>com.iciql.iciql.ConstrainDeleteType.SET_NULL
- * <li>com.iciql.iciql.ConstrainDeleteType.NO_ACTION
- * <li>com.iciql.iciql.ConstrainDeleteType.SET_DEFAULT
- * </ul>
- */
- ConstraintDeleteType deleteType() default ConstraintDeleteType.UNSET;
-
- /**
- * Type of the action on update, default to unspecified.
- * <ul>
- * <li>com.iciql.iciql.ConstrainUpdateType.CASCADE
- * <li>com.iciql.iciql.ConstrainUpdateType.RESTRICT
- * <li>com.iciql.iciql.ConstrainUpdateType.SET_NULL
- * <li>com.iciql.iciql.ConstrainUpdateType.NO_ACTION
- * <li>com.iciql.iciql.ConstrainUpdateType.SET_DEFAULT
- * </ul>
- */
- ConstraintUpdateType updateType() default ConstraintUpdateType.UNSET;
-
- /**
- * Type of the deferrability mode, default to unspecified
- * <ul>
- * <li>com.iciql.iciql.ConstrainUpdateType.CASCADE
- * <li>ConstraintDeferrabilityType.DEFERRABLE_INITIALLY_DEFERRED
- * <li>ConstraintDeferrabilityType.DEFERRABLE_INITIALLY_IMMEDIATE
- * <li>ConstraintDeferrabilityType.NOT_DEFERRABLE
- * </ul>
- */
- ConstraintDeferrabilityType deferrabilityType() default ConstraintDeferrabilityType.UNSET;
-
- /**
- * The source table for the columns defined as foreign.
- */
- String tableName() default "";
-
- /**
- * Columns defined as 'foreign'.
- * <ul>
- * <li>single column : foreignColumns = "id"
- * <li>multiple column : foreignColumns = { "id", "name", "date" }
- * </ul>
- */
- String[] foreignColumns() default {};
-
- /**
- * The reference table for the columns defined as references.
- */
- String referenceName() default "";
-
- /**
- * Columns defined as 'references'.
- * <ul>
- * <li>single column : referenceColumns = "id"
- * <li>multiple column : referenceColumns = { "id", "name", "date" }
- * </ul>
- */
- String[] referenceColumns() default {};
- }
-
- /**
- * Annotation to specify multiple foreign keys constraints.
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.TYPE)
- public @interface IQContraintsForeignKey {
- IQContraintForeignKey[] value() default {};
- }
-
- /**
- * A unique constraint annotation.
- * <p>
- * <ul>
- * <li>@IQContraintUnique(uniqueColumns = { "street", "city" })
- * <li>@IQContraintUnique(name="streetconstraint", uniqueColumns = { "street", "city" })
- * </ul>
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.TYPE)
- public @interface IQContraintUnique {
-
- /**
- * Constraint name. If null or empty, iciql will generate one.
- */
- String name() default "";
-
- /**
- * Columns defined as 'unique'.
- * <ul>
- * <li>single column : uniqueColumns = "id"
- * <li>multiple column : uniqueColumns = { "id", "name", "date" }
- * </ul>
- */
- String[] uniqueColumns() default {};
-
- }
-
- /**
- * Annotation to specify multiple unique constraints.
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.TYPE)
- public @interface IQContraintsUnique {
- IQContraintUnique[] value() default {};
- }
-
- /**
- * Annotation to define a view.
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.TYPE)
- public @interface IQView {
-
- /**
- * The view name. If not specified the class name is used as the view
- * name.
- * <p>
- * The view name may still be overridden in the define() method if the
- * model class is not annotated with IQView. Default: unspecified.
- */
- String name() default "";
-
- /**
- * The source table for the view.
- * <p>
- * The view name may still be overridden in the define() method if the
- * model class is not annotated with IQView. Default: unspecified.
- */
- String tableName() default "";
-
- /**
- * The inherit columns allows this model class to inherit columns from
- * its super class. Any IQTable annotation present on the super class is
- * ignored. Default: false.
- */
- boolean inheritColumns() default false;
-
- /**
- * Whether or not iciql tries to create the view. Default:
- * true.
- */
- boolean create() default true;
-
- /**
- * If true, only fields that are explicitly annotated as IQColumn are
- * mapped. Default: true.
- */
- boolean annotationsOnly() default true;
- }
-
- /**
- * String snippet defining SQL constraints for a field. Use "this" as
- * a placeholder for the column name. "this" will be substituted at
- * runtime.
- * <p>
- * IQConstraint("this > 2 AND this <= 7")
- * <p>
- * This snippet may still be overridden in the define() method if the
- * model class is not annotated with IQTable or IQView. Default: unspecified.
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface IQConstraint {
-
- String value() default "";
- }
-
- /**
- * Annotation to specify multiple indexes.
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.TYPE)
- public @interface IQIndexes {
- IQIndex[] value() default {};
- }
-
- /**
- * Annotation to define a table.
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.TYPE)
- public @interface IQTable {
-
- /**
- * The table name. If not specified the class name is used as the table
- * name.
- * <p>
- * The table name may still be overridden in the define() method if the
- * model class is not annotated with IQTable. Default: unspecified.
- */
- String name() default "";
-
- /**
- * The primary key may be optionally specified. If it is not specified,
- * then no primary key is set by the IQTable annotation. You may specify
- * a composite primary key.
- * <ul>
- * <li>single column primaryKey: value = "id"
- * <li>compound primary key: value = { "id", "name" }
- * </ul>
- * The primary key may still be overridden in the define() method if the
- * model class is not annotated with IQTable. Default: unspecified.
- */
- String[] primaryKey() default {};
-
- /**
- * The inherit columns allows this model class to inherit columns from
- * its super class. Any IQTable annotation present on the super class is
- * ignored. Default: false.
- */
- boolean inheritColumns() default false;
-
- /**
- * Whether or not iciql tries to create the table and indexes. Default:
- * true.
- */
- boolean create() default true;
-
- /**
- * If true, only fields that are explicitly annotated as IQColumn are
- * mapped. Default: true.
- */
- boolean annotationsOnly() default true;
-
- /**
- * If true, this table is created as a memory table where data is
- * persistent, but index data is kept in main memory. Valid only for H2
- * and HSQL databases. Default: false.
- */
- boolean memoryTable() default false;
- }
-
- /**
- * Annotation to define a column. Annotated fields may have any scope
- * (however, the JVM may raise a SecurityException if the SecurityManager
- * doesn't allow iciql to access the field.)
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface IQColumn {
-
- /**
- * If not specified, the field name is used as the column name. Default:
- * the field name.
- */
- String name() default "";
-
- /**
- * This column is the primary key. Default: false.
- */
- boolean primaryKey() default false;
-
- /**
- * The column is created with a sequence as the default value. Default:
- * false.
- */
- boolean autoIncrement() default false;
-
- /**
- * Length is used to define the length of a VARCHAR column or to define
- * the precision of a DECIMAL(precision, scale) expression.
- * <p>
- * If larger than zero, it is used during the CREATE TABLE phase. For
- * string values it may also be used to prevent database exceptions on
- * INSERT and UPDATE statements (see trim).
- * <p>
- * Any length set in define() may override this annotation setting if
- * the model class is not annotated with IQTable. Default: 0.
- */
- int length() default 0;
-
- /**
- * Scale is used during the CREATE TABLE phase to define the scale of a
- * DECIMAL(precision, scale) expression.
- * <p>
- * Any scale set in define() may override this annotation setting if the
- * model class is not annotated with IQTable. Default: 0.
- */
- int scale() default 0;
-
- /**
- * If true, iciql will automatically trim the string if it exceeds
- * length (value.substring(0, length)). Default: false.
- */
- boolean trim() default false;
-
- /**
- * If false, iciql will set the column NOT NULL during the CREATE TABLE
- * phase. Default: true.
- */
- boolean nullable() default true;
-
- /**
- * The default value assigned to the column during the CREATE TABLE
- * phase. This field could contain a literal single-quoted value, or a
- * function call. Empty strings are considered NULL. Examples:
- * <ul>
- * <li>defaultValue="" (null)
- * <li>defaultValue="CURRENT_TIMESTAMP"
- * <li>defaultValue="''" (empty string)
- * <li>defaultValue="'0'"
- * <li>defaultValue="'1970-01-01 00:00:01'"
- * </ul>
- * if the default value is specified, and auto increment is disabled,
- * and primary key is disabled, then this value is included in the
- * "DEFAULT ..." phrase of a column during the CREATE TABLE process.
- * <p>
- * Alternatively, you may specify a default object value on the field
- * and this will be converted to a properly formatted DEFAULT expression
- * during the CREATE TABLE process.
- * <p>
- * Default: unspecified (null).
- */
- String defaultValue() default "";
-
- }
-
- /**
- * Interface for using the EnumType.ENUMID enumeration mapping strategy.
- * <p>
- * Enumerations wishing to use EnumType.ENUMID must implement this
- * interface.
- */
- public interface EnumId {
- int enumId();
- }
-
- /**
- * Enumeration representing how to map a java.lang.Enum to a column.
- * <p>
- * <ul>
- * <li>NAME - name() : string
- * <li>ORDINAL - ordinal() : int
- * <li>ENUMID - enumId() : int
- * </ul>
- *
- * @see com.iciql.Iciql.EnumId interface
- */
- public enum EnumType {
- NAME, ORDINAL, ENUMID;
-
- public static final EnumType DEFAULT_TYPE = NAME;
- }
-
- /**
- * Annotation to define how a java.lang.Enum is mapped to a column.
- * <p>
- * This annotation can be used on:
- * <ul>
- * <li>a field instance of an enumeration type
- * <li>on the enumeration class declaration
- * </ul>
- * If you choose to annotate the class declaration, that will be the default
- * mapping strategy for all @IQColumn instances of the enum. This can still
- * be overridden for an individual field by specifying the IQEnum
- * annotation.
- * <p>
- * The default mapping is by NAME.
- *
- * <pre>
- * IQEnum(EnumType.NAME)
- * </pre>
- *
- * A string mapping will generate either a VARCHAR, if IQColumn.length > 0
- * or a TEXT column if IQColumn.length == 0
- *
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ ElementType.FIELD, ElementType.TYPE })
- public @interface IQEnum {
- EnumType value() default EnumType.NAME;
- }
-
- /**
- * Annotation to define an ignored field.
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface IQIgnore{
- }
-
- /**
- * This method is called to let the table define the primary key, indexes,
- * and the table name.
- */
- void defineIQ();
-}
diff --git a/src/com/iciql/IciqlException.java b/src/com/iciql/IciqlException.java deleted file mode 100644 index 3f27b73..0000000 --- a/src/com/iciql/IciqlException.java +++ /dev/null @@ -1,177 +0,0 @@ -/*
- * Copyright 2011 James Moger.
- * Copyright 2012 Frédéric Gaillard
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import java.sql.SQLException;
-import java.text.MessageFormat;
-import java.util.regex.Pattern;
-
-/**
- * Iciql wraps all exceptions with this class.
- */
-public class IciqlException extends RuntimeException {
-
- public static final int CODE_UNMAPPED_FIELD = 1;
- public static final int CODE_DUPLICATE_KEY = 2;
- public static final int CODE_OBJECT_NOT_FOUND = 3;
- public static final int CODE_OBJECT_ALREADY_EXISTS = 4;
- public static final int CODE_CONSTRAINT_VIOLATION = 5;
- public static final int CODE_UNCHARACTERIZED = 6;
-
- private static final String TOKEN_UNMAPPED_FIELD = "\\? (=|\\>|\\<|\\<\\>|!=|\\>=|\\<=|LIKE|BETWEEN) \\?";
-
- private static final long serialVersionUID = 1L;
-
- private String sql;
-
- private int iciqlCode;
-
- public IciqlException(Throwable t) {
- super(t.getMessage(), t);
- configureCode(t);
- }
-
- public IciqlException(String message, Object... parameters) {
- super(parameters.length > 0 ? MessageFormat.format(message, parameters) : message);
- }
-
- public IciqlException(Throwable t, String message, Object... parameters) {
- super(parameters.length > 0 ? MessageFormat.format(message, parameters) : message, t);
- configureCode(t);
- }
-
- public static void checkUnmappedField(String sql) {
- if (Pattern.compile(IciqlException.TOKEN_UNMAPPED_FIELD).matcher(sql).find()) {
- IciqlException e = new IciqlException("unmapped field in statement!");
- e.sql = sql;
- e.iciqlCode = CODE_UNMAPPED_FIELD;
- throw e;
- }
- }
-
- public static IciqlException fromSQL(String sql, Throwable t) {
- if (Pattern.compile(TOKEN_UNMAPPED_FIELD).matcher(sql).find()) {
- IciqlException e = new IciqlException(t, "unmapped field in statement!");
- e.sql = sql;
- e.iciqlCode = CODE_UNMAPPED_FIELD;
- return e;
- } else {
- IciqlException e = new IciqlException(t, t.getMessage());
- e.sql = sql;
- return e;
- }
- }
-
- public void setSQL(String sql) {
- this.sql = sql;
- }
-
- public String getSQL() {
- return sql;
- }
-
- public int getIciqlCode() {
- return iciqlCode;
- }
-
- private void configureCode(Throwable t) {
- if (t == null) {
- return;
- }
- if (t instanceof SQLException) {
- // http://developer.mimer.com/documentation/html_92/Mimer_SQL_Mobile_DocSet/App_Return_Codes2.html
- SQLException s = (SQLException) t;
- String state = s.getSQLState();
- if ("23000".equals(state)) {
- // MySQL duplicate primary key on insert
- iciqlCode = CODE_DUPLICATE_KEY;
- if (s.getErrorCode() == 1217) {
- iciqlCode = CODE_CONSTRAINT_VIOLATION;
- }
- } else if ("23505".equals(state)) {
- // Derby duplicate primary key on insert
- iciqlCode = CODE_DUPLICATE_KEY;
- } else if ("42000".equals(state)) {
- // MySQL duplicate unique index value on insert
- iciqlCode = CODE_DUPLICATE_KEY;
- } else if ("42Y07".equals(state)) {
- // Derby schema not found
- iciqlCode = CODE_OBJECT_NOT_FOUND;
- } else if ("42X05".equals(state)) {
- // Derby table not found
- iciqlCode = CODE_OBJECT_NOT_FOUND;
- } else if ("42Y55".equals(state)) {
- // Derby table not found
- iciqlCode = CODE_OBJECT_NOT_FOUND;
- } else if ("42S02".equals(state)) {
- // H2 table not found
- iciqlCode = CODE_OBJECT_NOT_FOUND;
- } else if ("42501".equals(state)) {
- // HSQL table not found
- iciqlCode = CODE_OBJECT_NOT_FOUND;
- } else if ("42P01".equals(state)) {
- // PostgreSQL table not found
- iciqlCode = CODE_OBJECT_NOT_FOUND;
- } else if ("X0X05".equals(state)) {
- // Derby view/table not found exists
- iciqlCode = CODE_OBJECT_NOT_FOUND;
- } else if ("X0Y32".equals(state)) {
- // Derby table already exists
- iciqlCode = CODE_OBJECT_ALREADY_EXISTS;
- } else if ("42P07".equals(state)) {
- // PostgreSQL table or index already exists
- iciqlCode = CODE_OBJECT_ALREADY_EXISTS;
- } else if ("42S01".equals(state)) {
- // MySQL view already exists
- iciqlCode = CODE_OBJECT_ALREADY_EXISTS;
- } else if ("42S11".equals(state)) {
- // H2 index already exists
- iciqlCode = CODE_OBJECT_ALREADY_EXISTS;
- } else if ("42504".equals(state)) {
- // HSQL index already exists
- iciqlCode = CODE_OBJECT_ALREADY_EXISTS;
- } else if ("2BP01".equals(state)) {
- // PostgreSQL constraint violation
- iciqlCode = CODE_CONSTRAINT_VIOLATION;
- } else if ("42533".equals(state)) {
- // HSQL constraint violation
- iciqlCode = CODE_CONSTRAINT_VIOLATION;
- } else if ("X0Y25".equals(state)) {
- // Derby constraint violation
- iciqlCode = CODE_CONSTRAINT_VIOLATION;
- } else {
- // uncharacterized SQL code, we can always rely on iciqlCode != 0 in IciqlException
- iciqlCode = s.getErrorCode() == 0 ? CODE_UNCHARACTERIZED : s.getErrorCode();
- }
- }
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(getClass().getName());
- String message = getLocalizedMessage();
- if (message != null) {
- sb.append(": ").append(message);
- }
- if (sql != null) {
- sb.append('\n').append(sql);
- }
- return sb.toString();
- }
-}
diff --git a/src/com/iciql/ModelUtils.java b/src/com/iciql/ModelUtils.java deleted file mode 100644 index 56e6440..0000000 --- a/src/com/iciql/ModelUtils.java +++ /dev/null @@ -1,499 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql; - -import static com.iciql.util.StringUtils.isNullOrEmpty; - -import java.lang.reflect.Method; -import java.math.BigDecimal; -import java.text.DateFormat; -import java.text.MessageFormat; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.regex.Pattern; - -import com.iciql.TableDefinition.FieldDefinition; -import com.iciql.util.StringUtils; - -/** - * Utility methods for models related to type mapping, default value validation, - * and class or field name creation. - */ -class ModelUtils { - - /** - * The list of supported data types. It is used by the runtime mapping for - * CREATE statements. - */ - private static final Map<Class<?>, String> SUPPORTED_TYPES = new HashMap<Class<?>, String>(); - - static { - Map<Class<?>, String> m = SUPPORTED_TYPES; - m.put(String.class, "VARCHAR"); - m.put(Boolean.class, "BOOLEAN"); - m.put(Byte.class, "TINYINT"); - m.put(Short.class, "SMALLINT"); - m.put(Integer.class, "INT"); - m.put(Long.class, "BIGINT"); - m.put(Float.class, "REAL"); - m.put(Double.class, "DOUBLE"); - m.put(BigDecimal.class, "DECIMAL"); - m.put(java.sql.Timestamp.class, "TIMESTAMP"); - m.put(java.util.Date.class, "TIMESTAMP"); - m.put(java.sql.Date.class, "DATE"); - m.put(java.sql.Time.class, "TIME"); - m.put(byte[].class, "BLOB"); - m.put(UUID.class, "UUID"); - - // map primitives - m.put(boolean.class, m.get(Boolean.class)); - m.put(byte.class, m.get(Byte.class)); - m.put(short.class, m.get(Short.class)); - m.put(int.class, m.get(Integer.class)); - m.put(long.class, m.get(Long.class)); - m.put(float.class, m.get(Float.class)); - m.put(double.class, m.get(Double.class)); - } - - /** - * Convert SQL type aliases to the list of supported types. This map is used - * by generation and validation. - */ - private static final Map<String, String> SQL_TYPES = new HashMap<String, String>(); - - static { - Map<String, String> m = SQL_TYPES; - m.put("CHAR", "VARCHAR"); - m.put("CHARACTER", "VARCHAR"); - m.put("NCHAR", "VARCHAR"); - m.put("VARCHAR_CASESENSITIVE", "VARCHAR"); - m.put("VARCHAR_IGNORECASE", "VARCHAR"); - m.put("LONGVARCHAR", "VARCHAR"); - m.put("VARCHAR2", "VARCHAR"); - m.put("NVARCHAR", "VARCHAR"); - m.put("NVARCHAR2", "VARCHAR"); - m.put("TEXT", "VARCHAR"); - m.put("NTEXT", "VARCHAR"); - m.put("TINYTEXT", "VARCHAR"); - m.put("MEDIUMTEXT", "VARCHAR"); - m.put("LONGTEXT", "VARCHAR"); - m.put("CLOB", "VARCHAR"); - m.put("NCLOB", "VARCHAR"); - - // logic - m.put("BIT", "BOOLEAN"); - m.put("BOOL", "BOOLEAN"); - - // numeric - m.put("BYTE", "TINYINT"); - m.put("INT2", "SMALLINT"); - m.put("YEAR", "SMALLINT"); - m.put("INTEGER", "INT"); - m.put("MEDIUMINT", "INT"); - m.put("INT4", "INT"); - m.put("SIGNED", "INT"); - m.put("INT8", "BIGINT"); - m.put("IDENTITY", "BIGINT"); - m.put("SERIAL", "INT"); - m.put("BIGSERIAL", "BIGINT"); - - // decimal - m.put("NUMBER", "DECIMAL"); - m.put("DEC", "DECIMAL"); - m.put("NUMERIC", "DECIMAL"); - m.put("FLOAT", "DOUBLE"); - m.put("FLOAT4", "DOUBLE"); - m.put("FLOAT8", "DOUBLE"); - m.put("DOUBLE PRECISION", "DOUBLE"); - - // date - m.put("DATETIME", "TIMESTAMP"); - m.put("SMALLDATETIME", "TIMESTAMP"); - - // binary types - m.put("TINYBLOB", "BLOB"); - m.put("MEDIUMBLOB", "BLOB"); - m.put("LONGBLOB", "BLOB"); - m.put("IMAGE", "BLOB"); - m.put("OID", "BLOB"); - } - - private static final List<String> KEYWORDS = Arrays.asList("abstract", "assert", "boolean", "break", - "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", - "enum", "extends", "final", "finally", "float", "for", "goto", "if", "implements", "import", - "instanceof", "int", "interface", "long", "native", "new", "package", "private", "protected", - "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this", - "throw", "throws", "transient", "try", "void", "volatile", "while", "false", "null", "true"); - - /** - * Returns a SQL type mapping for a Java class. - * - * @param fieldDef - * the field to map - * @return - */ - static String getDataType(FieldDefinition fieldDef) { - Class<?> fieldClass = fieldDef.field.getType(); - if (fieldClass.isEnum()) { - switch (fieldDef.enumType) { - case ORDINAL: - case ENUMID: - return "INT"; - case NAME: - default: - return "VARCHAR"; - } - } - if (SUPPORTED_TYPES.containsKey(fieldClass)) { - return SUPPORTED_TYPES.get(fieldClass); - } - throw new IciqlException("Unsupported type " + fieldClass.getName()); - } - - /** - * Returns the Java class for a given SQL type. - * - * @param sqlType - * @param dateTimeClass - * the preferred date class (java.util.Date or - * java.sql.Timestamp) - * @return - */ - static Class<?> getClassForSqlType(String sqlType, Class<? extends java.util.Date> dateTimeClass) { - sqlType = sqlType.toUpperCase(); - // XXX dropping "UNSIGNED" or parts like that could be trouble - sqlType = sqlType.split(" ")[0].trim(); - - if (SQL_TYPES.containsKey(sqlType)) { - // convert the sqlType to a standard type - sqlType = SQL_TYPES.get(sqlType); - } - Class<?> mappedClass = null; - for (Class<?> clazz : SUPPORTED_TYPES.keySet()) { - if (clazz.isPrimitive()) { - // do not map from SQL TYPE to primitive type - continue; - } - if (SUPPORTED_TYPES.get(clazz).equalsIgnoreCase(sqlType)) { - mappedClass = clazz; - - break; - } - } - if (mappedClass != null) { - if (mappedClass.equals(java.util.Date.class) || mappedClass.equals(java.sql.Timestamp.class)) { - return dateTimeClass; - } - return mappedClass; - } - return null; - } - - /** - * Tries to create a convert a SQL table name to a camel case class name. - * - * @param tableName - * the SQL table name - * @return the class name - */ - static String convertTableToClassName(String tableName) { - String[] chunks = StringUtils.arraySplit(tableName, '_', false); - StringBuilder className = new StringBuilder(); - for (String chunk : chunks) { - if (chunk.length() == 0) { - // leading or trailing _ - continue; - } - String[] subchunks = StringUtils.arraySplit(chunk, ' ', false); - for (String subchunk : subchunks) { - if (subchunk.length() == 0) { - // leading or trailing space - continue; - } - className.append(Character.toUpperCase(subchunk.charAt(0))); - className.append(subchunk.substring(1).toLowerCase()); - } - } - return className.toString(); - } - - /** - * Ensures that SQL column names don't collide with Java keywords. - * - * @param columnName - * the column name - * @return the Java field name - */ - static String convertColumnToFieldName(String columnName) { - String lower = columnName.toLowerCase(); - if (KEYWORDS.contains(lower)) { - lower += "Value"; - } - return lower; - } - - /** - * Converts a DEFAULT clause value into an object. - * - * @param field - * definition - * @return object - */ - static Object getDefaultValue(FieldDefinition def, Class<? extends Date> dateTimeClass) { - Class<?> valueType = getClassForSqlType(def.dataType, dateTimeClass); - if (String.class.isAssignableFrom(valueType)) { - if (StringUtils.isNullOrEmpty(def.defaultValue)) { - // literal default must be specified within single quotes - return null; - } - if (def.defaultValue.charAt(0) == '\'' - && def.defaultValue.charAt(def.defaultValue.length() - 1) == '\'') { - // strip leading and trailing single quotes - return def.defaultValue.substring(1, def.defaultValue.length() - 1).trim(); - } - return def.defaultValue; - } - - if (StringUtils.isNullOrEmpty(def.defaultValue)) { - // can not create object from empty string - return null; - } - - // strip leading and trailing single quotes - String content = def.defaultValue; - if (content.charAt(0) == '\'') { - content = content.substring(1); - } - if (content.charAt(content.length() - 1) == '\'') { - content = content.substring(0, content.length() - 2); - } - - if (StringUtils.isNullOrEmpty(content)) { - // can not create object from empty string - return null; - } - - if (Boolean.class.isAssignableFrom(valueType) || boolean.class.isAssignableFrom(valueType)) { - return Boolean.parseBoolean(content); - } - - if (Number.class.isAssignableFrom(valueType)) { - try { - // delegate to static valueOf() method to parse string - Method m = valueType.getMethod("valueOf", String.class); - return m.invoke(null, content); - } catch (NumberFormatException e) { - throw new IciqlException(e, "Failed to parse {0} as a number!", def.defaultValue); - } catch (Throwable t) { - } - } - - String dateRegex = "[0-9]{1,4}[-/\\.][0-9]{1,2}[-/\\.][0-9]{1,2}"; - String timeRegex = "[0-2]{1}[0-9]{1}:[0-5]{1}[0-9]{1}:[0-5]{1}[0-9]{1}"; - - if (java.sql.Date.class.isAssignableFrom(valueType)) { - // this may be a little loose.... - // 00-00-00 - // 00/00/00 - // 00.00.00 - Pattern pattern = Pattern.compile(dateRegex); - if (pattern.matcher(content).matches()) { - DateFormat df = DateFormat.getDateInstance(); - try { - return df.parse(content); - } catch (Exception e) { - throw new IciqlException(e, "Failed to parse {0} as a date!", def.defaultValue); - } - } - } - - if (java.sql.Time.class.isAssignableFrom(valueType)) { - // 00:00:00 - Pattern pattern = Pattern.compile(timeRegex); - if (pattern.matcher(content).matches()) { - DateFormat df = DateFormat.getTimeInstance(); - try { - return df.parse(content); - } catch (Exception e) { - throw new IciqlException(e, "Failed to parse {0} as a time!", def.defaultValue); - } - } - } - - if (java.util.Date.class.isAssignableFrom(valueType)) { - // this may be a little loose.... - // 00-00-00 00:00:00 - // 00/00/00T00:00:00 - // 00.00.00T00:00:00 - Pattern pattern = Pattern.compile(dateRegex + "." + timeRegex); - if (pattern.matcher(content).matches()) { - DateFormat df = DateFormat.getDateTimeInstance(); - try { - return df.parse(content); - } catch (Exception e) { - throw new IciqlException(e, "Failed to parse {0} as a datetimestamp!", def.defaultValue); - } - } - } - return content; - } - - /** - * Converts the object into a DEFAULT clause value. - * - * @param o - * the default object - * @return the value formatted for a DEFAULT clause - */ - static String formatDefaultValue(Object o) { - Class<?> objectClass = o.getClass(); - String value = null; - if (Number.class.isAssignableFrom(objectClass)) { - // NUMBER - return ((Number) o).toString(); - } else if (Boolean.class.isAssignableFrom(objectClass)) { - // BOOLEAN - return o.toString(); - } else if (java.sql.Date.class.isAssignableFrom(objectClass)) { - // DATE - value = new SimpleDateFormat("yyyy-MM-dd").format((Date) o); - } else if (java.sql.Time.class.isAssignableFrom(objectClass)) { - // TIME - value = new SimpleDateFormat("HH:mm:ss").format((Date) o); - } else if (Date.class.isAssignableFrom(objectClass)) { - // DATETIME - value = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) o); - } else if (String.class.isAssignableFrom(objectClass)) { - // STRING - value = o.toString(); - } - if (value == null) { - return "''"; - } - return MessageFormat.format("''{0}''", value); - } - - /** - * Checks the formatting of IQColumn.defaultValue(). - * - * @param defaultValue - * the default value - * @return true if it is - */ - static boolean isProperlyFormattedDefaultValue(String defaultValue) { - if (isNullOrEmpty(defaultValue)) { - return true; - } - Pattern literalDefault = Pattern.compile("'.*'"); - Pattern functionDefault = Pattern.compile("[^'].*[^']"); - return literalDefault.matcher(defaultValue).matches() - || functionDefault.matcher(defaultValue).matches(); - } - - /** - * Checks to see if the default value matches the class. - * - * @param modelClass - * the class - * @param defaultValue - * the value - * @return true if it does - */ - static boolean isValidDefaultValue(Class<?> modelClass, String defaultValue) { - - if (defaultValue == null) { - // NULL - return true; - } - if (defaultValue.trim().length() == 0) { - // NULL (effectively) - return true; - } - - // function / variable - Pattern functionDefault = Pattern.compile("[^'].*[^']"); - if (functionDefault.matcher(defaultValue).matches()) { - // hard to validate this since its in the database - // assume it is good - return true; - } - - // STRING - if (modelClass == String.class) { - Pattern stringDefault = Pattern.compile("'(.|\\n)*'"); - return stringDefault.matcher(defaultValue).matches(); - } - - String dateRegex = "[0-9]{1,4}[-/\\.][0-9]{1,2}[-/\\.][0-9]{1,2}"; - String timeRegex = "[0-2]{1}[0-9]{1}:[0-5]{1}[0-9]{1}:[0-5]{1}[0-9]{1}"; - - // TIMESTAMP - if (modelClass == java.util.Date.class || modelClass == java.sql.Timestamp.class) { - // this may be a little loose.... - // 00-00-00 00:00:00 - // 00/00/00T00:00:00 - // 00.00.00T00:00:00 - Pattern pattern = Pattern.compile("'" + dateRegex + "." + timeRegex + "'"); - return pattern.matcher(defaultValue).matches(); - } - - // DATE - if (modelClass == java.sql.Date.class) { - // this may be a little loose.... - // 00-00-00 - // 00/00/00 - // 00.00.00 - Pattern pattern = Pattern.compile("'" + dateRegex + "'"); - return pattern.matcher(defaultValue).matches(); - } - - // TIME - if (modelClass == java.sql.Time.class) { - // 00:00:00 - Pattern pattern = Pattern.compile("'" + timeRegex + "'"); - return pattern.matcher(defaultValue).matches(); - } - - // NUMBER - if (Number.class.isAssignableFrom(modelClass)) { - // strip single quotes - String unquoted = defaultValue; - if (unquoted.charAt(0) == '\'') { - unquoted = unquoted.substring(1); - } - if (unquoted.charAt(unquoted.length() - 1) == '\'') { - unquoted = unquoted.substring(0, unquoted.length() - 1); - } - - try { - // delegate to static valueOf() method to parse string - Method m = modelClass.getMethod("valueOf", String.class); - m.invoke(null, unquoted); - } catch (NumberFormatException ex) { - return false; - } catch (Throwable t) { - } - } - return true; - } -} diff --git a/src/com/iciql/OrderExpression.java b/src/com/iciql/OrderExpression.java deleted file mode 100644 index f450bfb..0000000 --- a/src/com/iciql/OrderExpression.java +++ /dev/null @@ -1,55 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-/**
- * An expression to order by in a query.
- *
- * @param <T>
- * the query data type
- */
-
-class OrderExpression<T> {
- private Query<T> query;
- private Object expression;
- private boolean desc;
- private boolean nullsFirst;
- private boolean nullsLast;
-
- OrderExpression(Query<T> query, Object expression, boolean desc, boolean nullsFirst, boolean nullsLast) {
- this.query = query;
- this.expression = expression;
- this.desc = desc;
- this.nullsFirst = nullsFirst;
- this.nullsLast = nullsLast;
- }
-
- void appendSQL(SQLStatement stat) {
- query.appendSQL(stat, null, expression);
- if (desc) {
- stat.appendSQL(" DESC");
- }
- if (nullsLast) {
- stat.appendSQL(" NULLS LAST");
- }
- if (nullsFirst) {
- stat.appendSQL(" NULLS FIRST");
- }
- }
-
-}
diff --git a/src/com/iciql/Query.java b/src/com/iciql/Query.java deleted file mode 100644 index 5dc78a5..0000000 --- a/src/com/iciql/Query.java +++ /dev/null @@ -1,947 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import java.lang.reflect.Field;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.List;
-
-import com.iciql.Iciql.EnumType;
-import com.iciql.bytecode.ClassReader;
-import com.iciql.util.JdbcUtils;
-import com.iciql.util.IciqlLogger;
-import com.iciql.util.Utils;
-
-/**
- * This class represents a query.
- *
- * @param <T>
- * the return type
- */
-
-public class Query<T> {
-
- private Db db;
- private SelectTable<T> from;
- private ArrayList<Token> conditions = Utils.newArrayList();
- private ArrayList<UpdateColumn> updateColumnDeclarations = Utils.newArrayList();
- private ArrayList<SelectTable<T>> joins = Utils.newArrayList();
- private final IdentityHashMap<Object, SelectColumn<T>> aliasMap = Utils.newIdentityHashMap();
- private ArrayList<OrderExpression<T>> orderByList = Utils.newArrayList();
- private ArrayList<Object> groupByExpressions = Utils.newArrayList();
- private long limit;
- private long offset;
-
- private Query(Db db) {
- this.db = db;
- }
-
- /**
- * from() is a static factory method to build a Query object.
- *
- * @param db
- * @param alias
- * @return a query object
- */
- @SuppressWarnings("unchecked")
- static <T> Query<T> from(Db db, T alias) {
- Query<T> query = new Query<T>(db);
- TableDefinition<T> def = (TableDefinition<T>) db.define(alias.getClass());
- query.from = new SelectTable<T>(db, query, alias, false);
- def.initSelectObject(query.from, alias, query.aliasMap);
- return query;
- }
-
- public long selectCount() {
- SQLStatement stat = getSelectStatement(false);
- stat.appendSQL("COUNT(*) ");
- appendFromWhere(stat);
- ResultSet rs = stat.executeQuery();
- try {
- rs.next();
- long value = rs.getLong(1);
- return value;
- } catch (SQLException e) {
- throw IciqlException.fromSQL(stat.getSQL(), e);
- } finally {
- JdbcUtils.closeSilently(rs, true);
- }
- }
-
- public List<T> select() {
- return select(false);
- }
-
- public T selectFirst() {
- return select(false).get(0);
- }
-
- public List<T> selectDistinct() {
- return select(true);
- }
-
- @SuppressWarnings("unchecked")
- public <X, Z> X selectFirst(Z x) {
- List<X> list = (List<X>) select(x);
- return list.isEmpty() ? null : list.get(0);
- }
-
- public <X> void createView(Class<X> viewClass) {
- TableDefinition<X> viewDef = db.define(viewClass);
-
- SQLStatement fromWhere = new SQLStatement(db);
- appendFromWhere(fromWhere, false);
-
- SQLStatement stat = new SQLStatement(db);
- db.getDialect().prepareCreateView(stat, viewDef, fromWhere.toSQL());
- IciqlLogger.create(stat.toSQL());
- stat.execute();
- }
-
- public <X> void replaceView(Class<X> viewClass) {
- db.dropView(viewClass);
- createView(viewClass);
- }
-
- public String getSQL() {
- SQLStatement stat = getSelectStatement(false);
- stat.appendSQL("*");
- appendFromWhere(stat);
- return stat.getSQL().trim();
- }
-
- /**
- * toSQL returns a static string version of the query with runtime variables
- * properly encoded. This method is also useful when combined with the where
- * clause methods like isParameter() or atLeastParameter() which allows
- * iciql to generate re-usable parameterized string statements.
- *
- * @return the sql query as plain text
- */
- public String toSQL() {
- return toSQL(false);
- }
-
- /**
- * toSQL returns a static string version of the query with runtime variables
- * properly encoded. This method is also useful when combined with the where
- * clause methods like isParameter() or atLeastParameter() which allows
- * iciql to generate re-usable parameterized string statements.
- *
- * @param distinct
- * if true SELECT DISTINCT is used for the query
- * @return the sql query as plain text
- */
- public String toSQL(boolean distinct) {
- return toSQL(distinct, null);
- }
-
- /**
- * toSQL returns a static string version of the query with runtime variables
- * properly encoded. This method is also useful when combined with the where
- * clause methods like isParameter() or atLeastParameter() which allows
- * iciql to generate re-usable parameterized string statements.
- *
- * @param distinct
- * if true SELECT DISTINCT is used for the query
- * @param k
- * k is used to select only the columns of the specified alias
- * for an inner join statement. An example of a generated
- * statement is: SELECT DISTINCT t1.* FROM sometable AS t1 INNER
- * JOIN othertable AS t2 ON t1.id = t2.id WHERE t2.flag = true
- * without the alias parameter the statement would start with
- * SELECT DISTINCT * FROM...
- * @return the sql query as plain text
- */
- public <K> String toSQL(boolean distinct, K k) {
- SQLStatement stat = new SQLStatement(getDb());
- if (updateColumnDeclarations.size() > 0) {
- stat.appendSQL("UPDATE ");
- from.appendSQL(stat);
- stat.appendSQL(" SET ");
- int i = 0;
- for (UpdateColumn declaration : updateColumnDeclarations) {
- if (i++ > 0) {
- stat.appendSQL(", ");
- }
- declaration.appendSQL(stat);
- }
- appendWhere(stat);
- } else {
- stat.appendSQL("SELECT ");
- if (distinct) {
- stat.appendSQL("DISTINCT ");
- }
- if (k != null) {
- SelectTable<?> sel = getSelectTable(k);
- if (sel == null) {
- // unknown alias, use wildcard
- IciqlLogger.warn("Alias {0} is not defined in the statement!", k.getClass());
- stat.appendSQL("*");
- } else if (isJoin()) {
- // join query, use AS alias
- String as = sel.getAs();
- stat.appendSQL(as + ".*");
- } else {
- // schema.table.*
- String schema = sel.getAliasDefinition().schemaName;
- String table = sel.getAliasDefinition().tableName;
- String as = getDb().getDialect().prepareTableName(schema, table);
- stat.appendSQL(as + ".*");
- }
- } else {
- // alias unspecified, use wildcard
- stat.appendSQL("*");
- }
- appendFromWhere(stat);
- }
- return stat.toSQL().trim();
- }
-
- <Z> String toSubQuery(Z z) {
- SQLStatement stat = getSelectStatement(false);
- SelectColumn<T> col = aliasMap.get(z);
- String columnName = col.getFieldDefinition().columnName;
- stat.appendColumn(columnName);
- appendFromWhere(stat);
- return stat.toSQL();
- }
-
- private List<T> select(boolean distinct) {
- List<T> result = Utils.newArrayList();
- TableDefinition<T> def = from.getAliasDefinition();
- SQLStatement stat = getSelectStatement(distinct);
- def.appendSelectList(stat);
- appendFromWhere(stat);
- ResultSet rs = stat.executeQuery();
- try {
- int[] columns = def.mapColumns(false, rs);
- while (rs.next()) {
- T item = from.newObject();
- def.readRow(item, rs, columns);
- result.add(item);
- }
- } catch (SQLException e) {
- throw IciqlException.fromSQL(stat.getSQL(), e);
- } finally {
- JdbcUtils.closeSilently(rs, true);
- }
- return result;
- }
-
- public int delete() {
- SQLStatement stat = new SQLStatement(db);
- stat.appendSQL("DELETE FROM ");
- from.appendSQL(stat);
- appendWhere(stat);
- IciqlLogger.delete(stat.getSQL());
- return stat.executeUpdate();
- }
-
- public <A> UpdateColumnSet<T, A> set(A field) {
- from.getAliasDefinition().checkMultipleEnums(field);
- return new UpdateColumnSet<T, A>(this, field);
- }
-
- public UpdateColumnSet<T, Boolean> set(boolean field) {
- from.getAliasDefinition().checkMultipleBooleans();
- return setPrimitive(field);
- }
-
- public UpdateColumnSet<T, Byte> set(byte field) {
- return setPrimitive(field);
- }
-
- public UpdateColumnSet<T, Short> set(short field) {
- return setPrimitive(field);
- }
-
- public UpdateColumnSet<T, Integer> set(int field) {
- return setPrimitive(field);
- }
-
- public UpdateColumnSet<T, Long> set(long field) {
- return setPrimitive(field);
- }
-
- public UpdateColumnSet<T, Float> set(float field) {
- return setPrimitive(field);
- }
-
- public UpdateColumnSet<T, Double> set(double field) {
- return setPrimitive(field);
- }
-
- private <A> UpdateColumnSet<T, A> setPrimitive(A field) {
- A alias = getPrimitiveAliasByValue(field);
- if (alias == null) {
- // this will result in an unmapped field exception
- return set(field);
- }
- return set(alias);
- }
-
- public <A> UpdateColumnIncrement<T, A> increment(A field) {
- return new UpdateColumnIncrement<T, A>(this, field);
- }
-
- public UpdateColumnIncrement<T, Byte> increment(byte field) {
- return incrementPrimitive(field);
- }
-
- public UpdateColumnIncrement<T, Short> increment(short field) {
- return incrementPrimitive(field);
- }
-
- public UpdateColumnIncrement<T, Integer> increment(int field) {
- return incrementPrimitive(field);
- }
-
- public UpdateColumnIncrement<T, Long> increment(long field) {
- return incrementPrimitive(field);
- }
-
- public UpdateColumnIncrement<T, Float> increment(float field) {
- return incrementPrimitive(field);
- }
-
- public UpdateColumnIncrement<T, Double> increment(double field) {
- return incrementPrimitive(field);
- }
-
- private <A> UpdateColumnIncrement<T, A> incrementPrimitive(A field) {
- A alias = getPrimitiveAliasByValue(field);
- if (alias == null) {
- // this will result in an unmapped field exception
- return increment(field);
- }
- return increment(alias);
- }
-
- public int update() {
- if (updateColumnDeclarations.size() == 0) {
- throw new IciqlException("Missing set or increment call.");
- }
- SQLStatement stat = new SQLStatement(db);
- stat.appendSQL("UPDATE ");
- from.appendSQL(stat);
- stat.appendSQL(" SET ");
- int i = 0;
- for (UpdateColumn declaration : updateColumnDeclarations) {
- if (i++ > 0) {
- stat.appendSQL(", ");
- }
- declaration.appendSQL(stat);
- }
- appendWhere(stat);
- IciqlLogger.update(stat.getSQL());
- return stat.executeUpdate();
- }
-
- public <X, Z> List<X> selectDistinct(Z x) {
- return select(x, true);
- }
-
- public <X, Z> List<X> select(Z x) {
- return select(x, false);
- }
-
- @SuppressWarnings("unchecked")
- private <X, Z> List<X> select(Z x, boolean distinct) {
- Class<?> clazz = x.getClass();
- if (Utils.isSimpleType(clazz)) {
- return selectSimple((X) x, distinct);
- }
- Class<?> enclosingClass = clazz.getEnclosingClass();
- if (enclosingClass != null) {
- // anonymous inner class
- clazz = clazz.getSuperclass();
- }
- return select((Class<X>) clazz, (X) x, distinct);
- }
-
- private <X> List<X> select(Class<X> clazz, X x, boolean distinct) {
- List<X> result = Utils.newArrayList();
- TableDefinition<X> def = db.define(clazz);
- SQLStatement stat = getSelectStatement(distinct);
- def.appendSelectList(stat, this, x);
- appendFromWhere(stat);
- ResultSet rs = stat.executeQuery();
- try {
- int[] columns = def.mapColumns(false, rs);
- while (rs.next()) {
- X row = Utils.newObject(clazz);
- def.readRow(row, rs, columns);
- result.add(row);
- }
- } catch (SQLException e) {
- throw IciqlException.fromSQL(stat.getSQL(), e);
- } finally {
- JdbcUtils.closeSilently(rs, true);
- }
- return result;
- }
-
- @SuppressWarnings("unchecked")
- private <X> List<X> selectSimple(X x, boolean distinct) {
- SQLStatement stat = getSelectStatement(distinct);
- appendSQL(stat, null, x);
- appendFromWhere(stat);
- ResultSet rs = stat.executeQuery();
- List<X> result = Utils.newArrayList();
- try {
- while (rs.next()) {
- X value;
- Object o = rs.getObject(1);
- // Convert CLOB and BLOB now because we close the resultset
- if (Clob.class.isAssignableFrom(o.getClass())) {
- value = (X) Utils.convert(o, String.class);
- } else if (Blob.class.isAssignableFrom(o.getClass())) {
- value = (X) Utils.convert(o, byte[].class);
- } else {
- value = (X) o;
- }
- result.add(value);
- }
- } catch (Exception e) {
- throw IciqlException.fromSQL(stat.getSQL(), e);
- } finally {
- JdbcUtils.closeSilently(rs, true);
- }
- return result;
- }
-
- private SQLStatement getSelectStatement(boolean distinct) {
- SQLStatement stat = new SQLStatement(db);
- stat.appendSQL("SELECT ");
- if (distinct) {
- stat.appendSQL("DISTINCT ");
- }
- return stat;
- }
-
- /**
- * Begin a primitive boolean field condition clause.
- *
- * @param x
- * the primitive boolean field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Boolean> where(boolean x) {
- from.getAliasDefinition().checkMultipleBooleans();
- return wherePrimitive(x);
- }
-
- /**
- * Begin a primitive short field condition clause.
- *
- * @param x
- * the primitive short field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Byte> where(byte x) {
- return wherePrimitive(x);
- }
-
- /**
- * Begin a primitive short field condition clause.
- *
- * @param x
- * the primitive short field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Short> where(short x) {
- return wherePrimitive(x);
- }
-
- /**
- * Begin a primitive int field condition clause.
- *
- * @param x
- * the primitive int field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Integer> where(int x) {
- return wherePrimitive(x);
- }
-
- /**
- * Begin a primitive long field condition clause.
- *
- * @param x
- * the primitive long field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Long> where(long x) {
- return wherePrimitive(x);
- }
-
- /**
- * Begin a primitive float field condition clause.
- *
- * @param x
- * the primitive float field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Float> where(float x) {
- return wherePrimitive(x);
- }
-
- /**
- * Begin a primitive double field condition clause.
- *
- * @param x
- * the primitive double field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Double> where(double x) {
- return wherePrimitive(x);
- }
-
- /**
- * Begins a primitive field condition clause.
- *
- * @param value
- * @return a query condition to continue building the condition
- */
- private <A> QueryCondition<T, A> wherePrimitive(A value) {
- A alias = getPrimitiveAliasByValue(value);
- if (alias == null) {
- // this will result in an unmapped field exception
- return where(value);
- }
- return where(alias);
- }
-
- /**
- * Begin an Object field condition clause.
- *
- * @param x
- * the mapped object to query
- * @return a query condition to continue building the condition
- */
- public <A> QueryCondition<T, A> where(A x) {
- from.getAliasDefinition().checkMultipleEnums(x);
- return new QueryCondition<T, A>(this, x);
- }
-
- public <A> QueryWhere<T> where(Filter filter) {
- HashMap<String, Object> fieldMap = Utils.newHashMap();
- for (Field f : filter.getClass().getDeclaredFields()) {
- f.setAccessible(true);
- try {
- Object obj = f.get(filter);
- if (obj == from.getAlias()) {
- List<TableDefinition.FieldDefinition> fields = from.getAliasDefinition().getFields();
- String name = f.getName();
- for (TableDefinition.FieldDefinition field : fields) {
- String n = name + "." + field.field.getName();
- Object o = field.field.get(obj);
- fieldMap.put(n, o);
- }
- }
- fieldMap.put(f.getName(), f.get(filter));
- } catch (Exception e) {
- throw new IciqlException(e);
- }
- }
- Token filterCode = new ClassReader().decompile(filter, fieldMap, "where");
- // String filterQuery = filterCode.toString();
- conditions.add(filterCode);
- return new QueryWhere<T>(this);
- }
-
- public QueryWhere<T> where(String fragment, List<?> args) {
- return this.where(fragment, args.toArray());
- }
-
- public QueryWhere<T> where(String fragment, Object... args) {
- conditions.add(new RuntimeToken(fragment, args));
- return new QueryWhere<T>(this);
- }
-
- public QueryWhere<T> whereTrue(Boolean condition) {
- Token token = new Function("", condition);
- addConditionToken(token);
- return new QueryWhere<T>(this);
- }
-
- /**
- * Sets the Limit and Offset of a query.
- *
- * @return the query
- */
-
- public Query<T> limit(long limit) {
- this.limit = limit;
- return this;
- }
-
- public Query<T> offset(long offset) {
- this.offset = offset;
- return this;
- }
-
- public Query<T> orderBy(boolean field) {
- from.getAliasDefinition().checkMultipleBooleans();
- return orderByPrimitive(field);
- }
-
- public Query<T> orderBy(byte field) {
- return orderByPrimitive(field);
- }
-
- public Query<T> orderBy(short field) {
- return orderByPrimitive(field);
- }
-
- public Query<T> orderBy(int field) {
- return orderByPrimitive(field);
- }
-
- public Query<T> orderBy(long field) {
- return orderByPrimitive(field);
- }
-
- public Query<T> orderBy(float field) {
- return orderByPrimitive(field);
- }
-
- public Query<T> orderBy(double field) {
- return orderByPrimitive(field);
- }
-
- Query<T> orderByPrimitive(Object field) {
- Object alias = getPrimitiveAliasByValue(field);
- if (alias == null) {
- return orderBy(field);
- }
- return orderBy(alias);
- }
-
- public Query<T> orderBy(Object expr) {
- from.getAliasDefinition().checkMultipleEnums(expr);
- OrderExpression<T> e = new OrderExpression<T>(this, expr, false, false, false);
- addOrderBy(e);
- return this;
- }
-
- /**
- * Order by a number of columns.
- *
- * @param expressions
- * the columns
- * @return the query
- */
-
- public Query<T> orderBy(Object... expressions) {
- for (Object expr : expressions) {
- from.getAliasDefinition().checkMultipleEnums(expr);
- OrderExpression<T> e = new OrderExpression<T>(this, expr, false, false, false);
- addOrderBy(e);
- }
- return this;
- }
-
- public Query<T> orderByDesc(Object expr) {
- OrderExpression<T> e = new OrderExpression<T>(this, expr, true, false, false);
- addOrderBy(e);
- return this;
- }
-
- public Query<T> groupBy(boolean field) {
- from.getAliasDefinition().checkMultipleBooleans();
- return groupByPrimitive(field);
- }
-
- public Query<T> groupBy(byte field) {
- return groupByPrimitive(field);
- }
-
- public Query<T> groupBy(short field) {
- return groupByPrimitive(field);
- }
-
- public Query<T> groupBy(int field) {
- return groupByPrimitive(field);
- }
-
- public Query<T> groupBy(long field) {
- return groupByPrimitive(field);
- }
-
- public Query<T> groupBy(float field) {
- return groupByPrimitive(field);
- }
-
- public Query<T> groupBy(double field) {
- return groupByPrimitive(field);
- }
-
- Query<T> groupByPrimitive(Object field) {
- Object alias = getPrimitiveAliasByValue(field);
- if (alias == null) {
- return groupBy(field);
- }
- return groupBy(alias);
- }
-
- public Query<T> groupBy(Object expr) {
- from.getAliasDefinition().checkMultipleEnums(expr);
- groupByExpressions.add(expr);
- return this;
- }
-
- public Query<T> groupBy(Object... groupBy) {
- this.groupByExpressions.addAll(Arrays.asList(groupBy));
- return this;
- }
-
- /**
- * INTERNAL
- *
- * @param stat
- * the statement
- * @param alias
- * the alias object (can be null)
- * @param value
- * the value
- */
- public void appendSQL(SQLStatement stat, Object alias, Object value) {
- if (Function.count() == value) {
- stat.appendSQL("COUNT(*)");
- return;
- }
- if (RuntimeParameter.PARAMETER == value) {
- stat.appendSQL("?");
- addParameter(stat, alias, value);
- return;
- }
- Token token = Db.getToken(value);
- if (token != null) {
- token.appendSQL(stat, this);
- return;
- }
- if (alias != null && value.getClass().isEnum()) {
- // special case:
- // value is first enum constant which is also the alias object.
- // the first enum constant is used as the alias because we can not
- // instantiate an enum reflectively.
- stat.appendSQL("?");
- addParameter(stat, alias, value);
- return;
- }
- SelectColumn<T> col = getColumnByReference(value);
- if (col != null) {
- col.appendSQL(stat);
- return;
- }
- stat.appendSQL("?");
- addParameter(stat, alias, value);
- }
-
- /**
- * INTERNAL
- *
- * @param stat
- * the statement
- * @param alias
- * the alias object (can be null)
- * @param valueLeft
- * the value on the left of the compound clause
- * @param valueRight
- * the value on the right of the compound clause
- * @param compareType
- * the current compare type (e.g. BETWEEN)
- */
- public void appendSQL(SQLStatement stat, Object alias, Object valueLeft, Object valueRight,
- CompareType compareType) {
- stat.appendSQL("?");
- stat.appendSQL(" ");
- switch (compareType) {
- case BETWEEN:
- stat.appendSQL("AND");
- break;
- }
- stat.appendSQL(" ");
- stat.appendSQL("?");
- addParameter(stat, alias, valueLeft);
- addParameter(stat, alias, valueRight);
- }
-
- private void addParameter(SQLStatement stat, Object alias, Object value) {
- if (alias != null && value.getClass().isEnum()) {
- SelectColumn<T> col = getColumnByReference(alias);
- EnumType type = col.getFieldDefinition().enumType;
- Enum<?> anEnum = (Enum<?>) value;
- Object y = Utils.convertEnum(anEnum, type);
- stat.addParameter(y);
- } else {
- stat.addParameter(value);
- }
- }
-
- void addConditionToken(Token condition) {
- conditions.add(condition);
- }
-
- void addUpdateColumnDeclaration(UpdateColumn declaration) {
- updateColumnDeclarations.add(declaration);
- }
-
- void appendWhere(SQLStatement stat) {
- if (!conditions.isEmpty()) {
- stat.appendSQL(" WHERE ");
- for (Token token : conditions) {
- token.appendSQL(stat, this);
- stat.appendSQL(" ");
- }
- }
- }
-
- void appendFromWhere(SQLStatement stat) {
- appendFromWhere(stat, true);
- }
-
- void appendFromWhere(SQLStatement stat, boolean log) {
- stat.appendSQL(" FROM ");
- from.appendSQL(stat);
- for (SelectTable<T> join : joins) {
- join.appendSQLAsJoin(stat, this);
- }
- appendWhere(stat);
- if (!groupByExpressions.isEmpty()) {
- stat.appendSQL(" GROUP BY ");
- int i = 0;
- for (Object obj : groupByExpressions) {
- if (i++ > 0) {
- stat.appendSQL(", ");
- }
- appendSQL(stat, null, obj);
- stat.appendSQL(" ");
- }
- }
- if (!orderByList.isEmpty()) {
- stat.appendSQL(" ORDER BY ");
- int i = 0;
- for (OrderExpression<T> o : orderByList) {
- if (i++ > 0) {
- stat.appendSQL(", ");
- }
- o.appendSQL(stat);
- stat.appendSQL(" ");
- }
- }
- db.getDialect().appendLimitOffset(stat, limit, offset);
- if (log) {
- IciqlLogger.select(stat.getSQL());
- }
- }
-
- /**
- * Join another table.
- *
- * @param alias
- * an alias for the table to join
- * @return the joined query
- */
-
- public <A> QueryJoin<T> innerJoin(A alias) {
- return join(alias, false);
- }
-
- public <A> QueryJoin<T> leftJoin(A alias) {
- return join(alias, true);
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- private <A> QueryJoin<T> join(A alias, boolean outerJoin) {
- TableDefinition<T> def = (TableDefinition<T>) db.define(alias.getClass());
- SelectTable<T> join = new SelectTable(db, this, alias, outerJoin);
- def.initSelectObject(join, alias, aliasMap);
- joins.add(join);
- return new QueryJoin(this, join);
- }
-
- Db getDb() {
- return db;
- }
-
- SelectTable<T> getFrom() {
- return from;
- }
-
- boolean isJoin() {
- return !joins.isEmpty();
- }
-
- SelectTable<?> getSelectTable(Object alias) {
- if (from.getAlias() == alias) {
- return from;
- } else {
- for (SelectTable<?> join : joins) {
- if (join.getAlias() == alias) {
- return join;
- }
- }
- }
- return null;
- }
-
- /**
- * This method returns a mapped Object field by its reference.
- *
- * @param obj
- * @return
- */
- private SelectColumn<T> getColumnByReference(Object obj) {
- SelectColumn<T> col = aliasMap.get(obj);
- return col;
- }
-
- /**
- * This method returns the alias of a mapped primitive field by its value.
- *
- * @param obj
- * @return
- */
- @SuppressWarnings("unchecked")
- <A> A getPrimitiveAliasByValue(A obj) {
- for (Object alias : aliasMap.keySet()) {
- if (alias.equals(obj)) {
- SelectColumn<T> match = aliasMap.get(alias);
- if (match.getFieldDefinition().isPrimitive) {
- return (A) alias;
- }
- }
- }
- return null;
- }
-
- void addOrderBy(OrderExpression<T> expr) {
- orderByList.add(expr);
- }
-
-}
diff --git a/src/com/iciql/QueryBetween.java b/src/com/iciql/QueryBetween.java deleted file mode 100644 index 72d19dc..0000000 --- a/src/com/iciql/QueryBetween.java +++ /dev/null @@ -1,60 +0,0 @@ -/*
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-/**
- * This class represents a "between y and z" condition.
- *
- * @param <T>
- * the return type of the query
- * @param <A>
- * the incomplete condition data type
- */
-public class QueryBetween<T, A> {
-
- private Query<T> query;
- private A x;
- private A y;
-
- /**
- * Construct a between condition.
- *
- * @param query
- * the query
- * @param x
- * the alias
- * @param y
- * the lower bound of the between condition
- */
- public QueryBetween(Query<T> query, A x, A y) {
- this.query = query;
- this.x = x;
- this.y = y;
- }
-
- /**
- * Set the upper bound of the between condition.
- *
- * @param z
- * the upper bound of the between condition
- * @return the query
- */
- public QueryWhere<T> and(A z) {
- query.addConditionToken(new Condition<A>(x, y, z, CompareType.BETWEEN));
- return new QueryWhere<T>(query);
- }
-}
diff --git a/src/com/iciql/QueryCondition.java b/src/com/iciql/QueryCondition.java deleted file mode 100644 index 9613b1b..0000000 --- a/src/com/iciql/QueryCondition.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql; - -/** - * This class represents a query with an incomplete condition. - * - * @param <T> - * the return type of the query - * @param <A> - * the incomplete condition data type - */ - -public class QueryCondition<T, A> { - - private Query<T> query; - private A x; - - QueryCondition(Query<T> query, A x) { - this.query = query; - this.x = x; - } - - public <Q, Z> QueryWhere<T> in(SubQuery<Q, Z> q) { - query.addConditionToken(new SubQueryCondition<A, Q, Z>(x, q)); - return new QueryWhere<T>(query); - } - - public QueryWhere<T> is(A y) { - query.addConditionToken(new Condition<A>(x, y, CompareType.EQUAL)); - return new QueryWhere<T>(query); - } - - public QueryWhere<T> isNot(A y) { - query.addConditionToken(new Condition<A>(x, y, CompareType.NOT_EQUAL)); - return new QueryWhere<T>(query); - } - - public QueryWhere<T> isNull() { - query.addConditionToken(new Condition<A>(x, null, CompareType.IS_NULL)); - return new QueryWhere<T>(query); - } - - public QueryWhere<T> isNotNull() { - query.addConditionToken(new Condition<A>(x, null, CompareType.IS_NOT_NULL)); - return new QueryWhere<T>(query); - } - - public QueryWhere<T> exceeds(A y) { - query.addConditionToken(new Condition<A>(x, y, CompareType.EXCEEDS)); - return new QueryWhere<T>(query); - } - - public QueryWhere<T> atLeast(A y) { - query.addConditionToken(new Condition<A>(x, y, CompareType.AT_LEAST)); - return new QueryWhere<T>(query); - } - - public QueryWhere<T> lessThan(A y) { - query.addConditionToken(new Condition<A>(x, y, CompareType.LESS_THAN)); - return new QueryWhere<T>(query); - } - - public QueryWhere<T> atMost(A y) { - query.addConditionToken(new Condition<A>(x, y, CompareType.AT_MOST)); - return new QueryWhere<T>(query); - } - - public QueryBetween<T, A> between(A y) { - return new QueryBetween<T, A>(query, x, y); - } - - public QueryWhere<T> like(A pattern) { - query.addConditionToken(new Condition<A>(x, pattern, CompareType.LIKE)); - return new QueryWhere<T>(query); - } - - /* - * These method allows you to generate "x=?", "x!=?", etc where conditions. - * Parameter substitution must be done manually later with db.executeQuery. - * This allows for building re-usable SQL string statements from your model - * classes. - */ - public QueryWhere<T> isParameter() { - query.addConditionToken(new RuntimeParameter<A>(x, CompareType.EQUAL)); - return new QueryWhere<T>(query); - } - - public QueryWhere<T> isNotParameter() { - query.addConditionToken(new RuntimeParameter<A>(x, CompareType.NOT_EQUAL)); - return new QueryWhere<T>(query); - } - - public QueryWhere<T> exceedsParameter() { - query.addConditionToken(new RuntimeParameter<A>(x, CompareType.EXCEEDS)); - return new QueryWhere<T>(query); - } - - public QueryWhere<T> lessThanParameter() { - query.addConditionToken(new RuntimeParameter<A>(x, CompareType.LESS_THAN)); - return new QueryWhere<T>(query); - } - - public QueryWhere<T> atMostParameter() { - query.addConditionToken(new RuntimeParameter<A>(x, CompareType.AT_MOST)); - return new QueryWhere<T>(query); - } - - public QueryWhere<T> likeParameter() { - query.addConditionToken(new RuntimeParameter<A>(x, CompareType.LIKE)); - return new QueryWhere<T>(query); - } -} diff --git a/src/com/iciql/QueryJoin.java b/src/com/iciql/QueryJoin.java deleted file mode 100644 index 6d0484e..0000000 --- a/src/com/iciql/QueryJoin.java +++ /dev/null @@ -1,75 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-/**
- * This class represents a query with a join.
- */
-
-public class QueryJoin<T> {
-
- private Query<T> query;
- private SelectTable<T> join;
-
- QueryJoin(Query<T> query, SelectTable<T> join) {
- this.query = query;
- this.join = join;
- }
-
- public QueryJoinCondition<T, Boolean> on(boolean x) {
- query.getFrom().getAliasDefinition().checkMultipleBooleans();
- return addPrimitive(x);
- }
-
- public QueryJoinCondition<T, Byte> on(byte x) {
- return addPrimitive(x);
- }
-
- public QueryJoinCondition<T, Short> on(short x) {
- return addPrimitive(x);
- }
-
- public QueryJoinCondition<T, Integer> on(int x) {
- return addPrimitive(x);
- }
-
- public QueryJoinCondition<T, Long> on(long x) {
- return addPrimitive(x);
- }
-
- public QueryJoinCondition<T, Float> on(float x) {
- return addPrimitive(x);
- }
-
- public QueryJoinCondition<T, Double> on(double x) {
- return addPrimitive(x);
- }
-
- private <A> QueryJoinCondition<T, A> addPrimitive(A x) {
- A alias = query.getPrimitiveAliasByValue(x);
- if (alias == null) {
- // this will result in an unmapped field exception
- return new QueryJoinCondition<T, A>(query, join, x);
- }
- return new QueryJoinCondition<T, A>(query, join, alias);
- }
-
- public <A> QueryJoinCondition<T, A> on(A x) {
- return new QueryJoinCondition<T, A>(query, join, x);
- }
-}
diff --git a/src/com/iciql/QueryJoinCondition.java b/src/com/iciql/QueryJoinCondition.java deleted file mode 100644 index 6dfd218..0000000 --- a/src/com/iciql/QueryJoinCondition.java +++ /dev/null @@ -1,83 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-
-/**
- * This class represents a query with join and an incomplete condition.
- *
- * @param <A>
- * the incomplete condition data type
- */
-
-public class QueryJoinCondition<T, A> {
-
- private Query<T> query;
- private SelectTable<T> join;
- private A x;
-
- QueryJoinCondition(Query<T> query, SelectTable<T> join, A x) {
- this.query = query;
- this.join = join;
- this.x = x;
- }
-
- public Query<T> is(boolean y) {
- return addPrimitive(y);
- }
-
- public Query<T> is(byte y) {
- return addPrimitive(y);
- }
-
- public Query<T> is(short y) {
- return addPrimitive(y);
- }
-
- public Query<T> is(int y) {
- return addPrimitive(y);
- }
-
- public Query<T> is(long y) {
- return addPrimitive(y);
- }
-
- public Query<T> is(float y) {
- return addPrimitive(y);
- }
-
- public Query<T> is(double y) {
- return addPrimitive(y);
- }
-
- @SuppressWarnings("unchecked")
- private Query<T> addPrimitive(Object o) {
- A alias = query.getPrimitiveAliasByValue((A) o);
- if (alias == null) {
- join.addConditionToken(new Condition<A>(x, (A) o, CompareType.EQUAL));
- } else {
- join.addConditionToken(new Condition<A>(x, alias, CompareType.EQUAL));
- }
- return query;
- }
-
- public Query<T> is(A y) {
- join.addConditionToken(new Condition<A>(x, y, CompareType.EQUAL));
- return query;
- }
-}
diff --git a/src/com/iciql/QueryWhere.java b/src/com/iciql/QueryWhere.java deleted file mode 100644 index 5baa5ab..0000000 --- a/src/com/iciql/QueryWhere.java +++ /dev/null @@ -1,501 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import java.util.List;
-
-/**
- * This class represents a query with a condition.
- *
- * @param <T>
- * the return type
- */
-
-public class QueryWhere<T> {
-
- Query<T> query;
-
- QueryWhere(Query<T> query) {
- this.query = query;
- }
-
- /**
- * Specify an AND condition with a mapped primitive boolean.
- *
- * @param x
- * the primitive boolean field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Boolean> and(boolean x) {
- query.getFrom().getAliasDefinition().checkMultipleBooleans();
- return addPrimitive(ConditionAndOr.AND, x);
- }
-
- /**
- * Specify an AND condition with a mapped primitive byte.
- *
- * @param x
- * the primitive byte field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Byte> and(byte x) {
- return addPrimitive(ConditionAndOr.AND, x);
- }
-
- /**
- * Specify an AND condition with a mapped primitive short.
- *
- * @param x
- * the primitive short field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Short> and(short x) {
- return addPrimitive(ConditionAndOr.AND, x);
- }
-
- /**
- * Specify an AND condition with a mapped primitive int.
- *
- * @param x
- * the primitive int field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Integer> and(int x) {
- return addPrimitive(ConditionAndOr.AND, x);
- }
-
- /**
- * Specify an AND condition with a mapped primitive long.
- *
- * @param x
- * the primitive long field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Long> and(long x) {
- return addPrimitive(ConditionAndOr.AND, x);
- }
-
- /**
- * Specify an AND condition with a mapped primitive float.
- *
- * @param x
- * the primitive float field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Float> and(float x) {
- return addPrimitive(ConditionAndOr.AND, x);
- }
-
- /**
- * Specify an AND condition with a mapped primitive double.
- *
- * @param x
- * the primitive double field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Double> and(double x) {
- return addPrimitive(ConditionAndOr.AND, x);
- }
-
- private <A> QueryCondition<T, A> addPrimitive(ConditionAndOr condition, A x) {
- query.addConditionToken(condition);
- A alias = query.getPrimitiveAliasByValue(x);
- if (alias == null) {
- // this will result in an unmapped field exception
- return new QueryCondition<T, A>(query, x);
- }
- return new QueryCondition<T, A>(query, alias);
- }
-
- /**
- * Specify an AND condition with a mapped Object field.
- *
- * @param x
- * the Object field to query
- * @return a query condition to continue building the condition
- */
- public <A> QueryCondition<T, A> and(A x) {
- query.getFrom().getAliasDefinition().checkMultipleEnums(x);
- query.addConditionToken(ConditionAndOr.AND);
- return new QueryCondition<T, A>(query, x);
- }
-
- /**
- * Specify an OR condition with a mapped primitive boolean.
- *
- * @param x
- * the primitive boolean field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Boolean> or(boolean x) {
- query.getFrom().getAliasDefinition().checkMultipleBooleans();
- return addPrimitive(ConditionAndOr.OR, x);
- }
-
- /**
- * Specify an OR condition with a mapped primitive byte.
- *
- * @param x
- * the primitive byte field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Byte> or(byte x) {
- return addPrimitive(ConditionAndOr.OR, x);
- }
-
- /**
- * Specify an OR condition with a mapped primitive short.
- *
- * @param x
- * the primitive short field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Short> or(short x) {
- return addPrimitive(ConditionAndOr.OR, x);
- }
-
- /**
- * Specify an OR condition with a mapped primitive int.
- *
- * @param x
- * the primitive int field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Integer> or(int x) {
- return addPrimitive(ConditionAndOr.OR, x);
- }
-
- /**
- * Specify an OR condition with a mapped primitive long.
- *
- * @param x
- * the primitive long field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Long> or(long x) {
- return addPrimitive(ConditionAndOr.OR, x);
- }
-
- /**
- * Specify an OR condition with a mapped primitive float.
- *
- * @param x
- * the primitive float field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Float> or(float x) {
- return addPrimitive(ConditionAndOr.OR, x);
- }
-
- /**
- * Specify an OR condition with a mapped primitive double.
- *
- * @param x
- * the primitive double field to query
- * @return a query condition to continue building the condition
- */
- public QueryCondition<T, Double> or(double x) {
- return addPrimitive(ConditionAndOr.OR, x);
- }
-
- /**
- * Specify an OR condition with a mapped Object field.
- *
- * @param x
- * the Object field to query
- * @return a query condition to continue building the condition
- */
- public <A> QueryCondition<T, A> or(A x) {
- query.getFrom().getAliasDefinition().checkMultipleEnums(x);
- query.addConditionToken(ConditionAndOr.OR);
- return new QueryCondition<T, A>(query, x);
- }
-
- public QueryWhere<T> limit(long limit) {
- query.limit(limit);
- return this;
- }
-
- public QueryWhere<T> offset(long offset) {
- query.offset(offset);
- return this;
- }
-
- public String getSQL() {
- SQLStatement stat = new SQLStatement(query.getDb());
- stat.appendSQL("SELECT *");
- query.appendFromWhere(stat);
- return stat.getSQL().trim();
- }
-
- /**
- * toSQL returns a static string version of the query with runtime variables
- * properly encoded. This method is also useful when combined with the where
- * clause methods like isParameter() or atLeastParameter() which allows
- * iciql to generate re-usable parameterized string statements.
- *
- * @return the sql query as plain text
- */
- public String toSQL() {
- return query.toSQL(false);
- }
-
- /**
- * toSQL returns a static string version of the query with runtime variables
- * properly encoded. This method is also useful when combined with the where
- * clause methods like isParameter() or atLeastParameter() which allows
- * iciql to generate re-usable parameterized string statements.
- *
- * @param distinct
- * if true SELECT DISTINCT is used for the query
- * @return the sql query as plain text
- */
- public String toSQL(boolean distinct) {
- return query.toSQL(distinct);
- }
-
- /**
- * toSQL returns a static string version of the query with runtime variables
- * properly encoded. This method is also useful when combined with the where
- * clause methods like isParameter() or atLeastParameter() which allows
- * iciql to generate re-usable parameterized string statements.
- *
- * @param distinct
- * if true SELECT DISTINCT is used for the query
- * @param k
- * k is used to select only the columns of the specified alias
- * for an inner join statement. An example of a generated
- * statement is: SELECT DISTINCT t1.* FROM sometable AS t1 INNER
- * JOIN othertable AS t2 ON t1.id = t2.id WHERE t2.flag = true
- * without the alias parameter the statement would start with
- * SELECT DISTINCT * FROM...
- * @return the sql query as plain text
- */
- public <K> String toSQL(boolean distinct, K k) {
- return query.toSQL(distinct, k);
- }
-
- public <Z> SubQuery<T, Z> subQuery(Z x) {
- return new SubQuery<T, Z>(query, x);
- }
-
- public SubQuery<T, Boolean> subQuery(boolean x) {
- return subQuery(query.getPrimitiveAliasByValue(x));
- }
-
- public SubQuery<T, Byte> subQuery(byte x) {
- return subQuery(query.getPrimitiveAliasByValue(x));
- }
-
- public SubQuery<T, Short> subQuery(short x) {
- return subQuery(query.getPrimitiveAliasByValue(x));
- }
-
- public SubQuery<T, Integer> subQuery(int x) {
- return subQuery(query.getPrimitiveAliasByValue(x));
- }
-
- public SubQuery<T, Long> subQuery(long x) {
- return subQuery(query.getPrimitiveAliasByValue(x));
- }
-
- public SubQuery<T, Float> subQuery(float x) {
- return subQuery(query.getPrimitiveAliasByValue(x));
- }
-
- public SubQuery<T, Double> subQuery(double x) {
- return subQuery(query.getPrimitiveAliasByValue(x));
- }
-
- public <X, Z> List<X> select(Z x) {
- return query.select(x);
- }
-
- public <X, Z> List<X> selectDistinct(Z x) {
- return query.selectDistinct(x);
- }
-
- public <X, Z> X selectFirst(Z x) {
- List<X> list = query.select(x);
- return list.isEmpty() ? null : list.get(0);
- }
-
- public List<T> select() {
- return query.select();
- }
-
- public T selectFirst() {
- List<T> list = select();
- return list.isEmpty() ? null : list.get(0);
- }
-
- public List<T> selectDistinct() {
- return query.selectDistinct();
- }
-
- public void createView(Class<?> viewClass) {
- query.createView(viewClass);
- }
-
- public void replaceView(Class<?> viewClass) {
- query.replaceView(viewClass);
- }
-
- /**
- * Order by primitive boolean field
- *
- * @param field
- * a primitive boolean field
- * @return the query
- */
- public QueryWhere<T> orderBy(boolean field) {
- query.getFrom().getAliasDefinition().checkMultipleBooleans();
- return orderByPrimitive(field);
- }
-
- /**
- * Order by primitive byte field
- *
- * @param field
- * a primitive byte field
- * @return the query
- */
- public QueryWhere<T> orderBy(byte field) {
- return orderByPrimitive(field);
- }
-
- /**
- * Order by primitive short field
- *
- * @param field
- * a primitive short field
- * @return the query
- */
- public QueryWhere<T> orderBy(short field) {
- return orderByPrimitive(field);
- }
-
- public QueryWhere<T> orderBy(int field) {
- return orderByPrimitive(field);
- }
-
- /**
- * Order by primitive long field
- *
- * @param field
- * a primitive long field
- * @return the query
- */
- public QueryWhere<T> orderBy(long field) {
- return orderByPrimitive(field);
- }
-
- /**
- * Order by primitive float field
- *
- * @param field
- * a primitive float field
- * @return the query
- */
- public QueryWhere<T> orderBy(float field) {
- return orderByPrimitive(field);
- }
-
- /**
- * Order by primitive double field
- *
- * @param field
- * a primitive double field
- * @return the query
- */
- public QueryWhere<T> orderBy(double field) {
- return orderByPrimitive(field);
- }
-
- private QueryWhere<T> orderByPrimitive(Object field) {
- query.orderByPrimitive(field);
- return this;
- }
-
- public QueryWhere<T> orderBy(Object field) {
- query.getFrom().getAliasDefinition().checkMultipleEnums(field);
- query.orderBy(field);
- return this;
- }
-
- /**
- * Order by a number of Object columns.
- *
- * @param expressions
- * the order by expressions
- * @return the query
- */
-
- public QueryWhere<T> orderBy(Object... expressions) {
- query.orderBy(expressions);
- return this;
- }
-
- public QueryWhere<T> orderByNullsFirst(Object expr) {
- query.getFrom().getAliasDefinition().checkMultipleEnums(expr);
- OrderExpression<T> e = new OrderExpression<T>(query, expr, false, true, false);
- query.addOrderBy(e);
- return this;
- }
-
- public QueryWhere<T> orderByNullsLast(Object expr) {
- query.getFrom().getAliasDefinition().checkMultipleEnums(expr);
- OrderExpression<T> e = new OrderExpression<T>(query, expr, false, false, true);
- query.addOrderBy(e);
- return this;
- }
-
- public QueryWhere<T> orderByDesc(Object expr) {
- query.getFrom().getAliasDefinition().checkMultipleEnums(expr);
- OrderExpression<T> e = new OrderExpression<T>(query, expr, true, false, false);
- query.addOrderBy(e);
- return this;
- }
-
- public QueryWhere<T> orderByDescNullsFirst(Object expr) {
- query.getFrom().getAliasDefinition().checkMultipleEnums(expr);
- OrderExpression<T> e = new OrderExpression<T>(query, expr, true, true, false);
- query.addOrderBy(e);
- return this;
- }
-
- public QueryWhere<T> orderByDescNullsLast(Object expr) {
- query.getFrom().getAliasDefinition().checkMultipleEnums(expr);
- OrderExpression<T> e = new OrderExpression<T>(query, expr, true, false, true);
- query.addOrderBy(e);
- return this;
- }
-
- public int delete() {
- return query.delete();
- }
-
- public int update() {
- return query.update();
- }
-
- public long selectCount() {
- return query.selectCount();
- }
-
-}
diff --git a/src/com/iciql/RuntimeParameter.java b/src/com/iciql/RuntimeParameter.java deleted file mode 100644 index 0fbedba..0000000 --- a/src/com/iciql/RuntimeParameter.java +++ /dev/null @@ -1,49 +0,0 @@ -/*
- * Copyright 2012 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-/**
- * A runtime parameter is used to generate x=? conditions so that iciql can
- * build re-usable dynamic queries with parameter substitution done manually at
- * runtime.
- *
- * @param <A>
- * the operand type
- */
-
-class RuntimeParameter<A> implements Token {
-
- public final static String PARAMETER = "";
-
- A x;
- CompareType compareType;
-
- RuntimeParameter(A x, CompareType type) {
- this.x = x;
- this.compareType = type;
- }
-
- public <T> void appendSQL(SQLStatement stat, Query<T> query) {
- query.appendSQL(stat, null, x);
- stat.appendSQL(" ");
- stat.appendSQL(compareType.getString());
- if (compareType.hasRightExpression()) {
- stat.appendSQL(" ");
- query.appendSQL(stat, x, PARAMETER);
- }
- }
-}
diff --git a/src/com/iciql/RuntimeToken.java b/src/com/iciql/RuntimeToken.java deleted file mode 100644 index cbfd882..0000000 --- a/src/com/iciql/RuntimeToken.java +++ /dev/null @@ -1,57 +0,0 @@ -/*
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.iciql;
-
-import java.text.MessageFormat;
-
-import com.iciql.util.StringUtils;
-
-/**
- * Represents a traditional PreparedStatment fragment like "id=?, name=?".
- *
- */
-public class RuntimeToken implements Token {
-
- final String fragment;
- final Object[] args;
-
- public RuntimeToken(String fragment, Object... args) {
- this.fragment = fragment;
- this.args = args == null ? new Object[0] : args;
- }
-
- /**
- * Append the SQL to the given statement using the given query.
- *
- * @param stat
- * the statement to append the SQL to
- * @param query
- * the query to use
- */
- @Override
- public <T> void appendSQL(SQLStatement stat, Query<T> query) {
- int tokenCount = StringUtils.count('?', fragment);
- if (tokenCount != args.length) {
- throw new IciqlException(MessageFormat.format(
- "Fragment \"{0}\" specifies {1} tokens but you supplied {2} args", fragment, tokenCount,
- args.length));
- }
- stat.appendSQL(fragment);
- for (Object arg : args) {
- stat.addParameter(arg);
- }
- }
-}
diff --git a/src/com/iciql/SQLDialect.java b/src/com/iciql/SQLDialect.java deleted file mode 100644 index f62168e..0000000 --- a/src/com/iciql/SQLDialect.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * Copyright 2012 Frédéric Gaillard. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql; - -import java.sql.DatabaseMetaData; - -import com.iciql.TableDefinition.ConstraintForeignKeyDefinition; -import com.iciql.TableDefinition.ConstraintUniqueDefinition; -import com.iciql.TableDefinition.IndexDefinition; - -/** - * This interface defines points where iciql can build different statements - * depending on the database used. - */ -public interface SQLDialect { - - /** - * Configure the dialect from the database metadata. - * - * @param databaseName - * @param data - */ - void configureDialect(String databaseName, DatabaseMetaData data); - - /** - * Allows a dialect to substitute an SQL type. - * - * @param sqlType - * @return the dialect-safe type - */ - String convertSqlType(String sqlType); - - /** - * Returns a properly formatted table name for the dialect. - * - * @param schemaName - * the schema name, or null for no schema - * @param tableName - * the properly formatted table name - * @return the SQL snippet - */ - String prepareTableName(String schemaName, String tableName); - - /** - * Returns a properly formatted column name for the dialect. - * - * @param name - * the column name - * @return the properly formatted column name - */ - String prepareColumnName(String name); - - /** - * Get the CREATE TABLE statement. - * - * @param stat - * @param def - */ - <T> void prepareCreateTable(SQLStatement stat, TableDefinition<T> def); - - /** - * Get the DROP TABLE statement. - * - * @param stat - * @param def - */ - <T> void prepareDropTable(SQLStatement stat, TableDefinition<T> def); - - - /** - * Get the CREATE VIEW statement. - * - * @param stat - * return the SQL statement - * @param def - * table definition - */ - <T> void prepareCreateView(SQLStatement stat, TableDefinition<T> def); - - /** - * Get the CREATE VIEW statement. - * - * @param stat - * return the SQL statement - * @param def - * table definition - * @param fromWhere - */ - <T> void prepareCreateView(SQLStatement stat, TableDefinition<T> def, String fromWhere); - - /** - * Get the DROP VIEW statement. - * - * @param stat - * return the SQL statement - * @param def - * table definition - */ - <T> void prepareDropView(SQLStatement stat, TableDefinition<T> def); - - /** - * Get the CREATE INDEX statement. - * - * @param stat - * return the SQL statement - * @param schemaName - * the schema name - * @param tableName - * the table name - * @param index - * the index definition - */ - void prepareCreateIndex(SQLStatement stat, String schemaName, String tableName, IndexDefinition index); - - /** - * Get the ALTER statement. - * - * @param stat - * return the SQL statement - * @param schemaName - * the schema name - * @param tableName - * the table name - * @param constraint - * the constraint definition - */ - void prepareCreateConstraintForeignKey(SQLStatement stat, String schemaName, String tableName, ConstraintForeignKeyDefinition constraint); - - /** - * Get the ALTER statement. - * - * @param stat - * return the SQL statement - * @param schemaName - * the schema name - * @param tableName - * the table name - * @param constraint - * the constraint definition - * return the SQL statement - */ - void prepareCreateConstraintUnique(SQLStatement stat, String schemaName, String tableName, ConstraintUniqueDefinition constraint); - - /** - * Get a MERGE or REPLACE INTO statement. - * - * @param stat - * return the SQL statement - * @param schemaName - * the schema name - * @param tableName - * the table name - * @param def - * the table definition - * @param obj - * values - */ - <T> void prepareMerge(SQLStatement stat, String schemaName, String tableName, TableDefinition<T> def, - Object obj); - - /** - * Append "LIMIT limit OFFSET offset" to the SQL statement. - * - * @param stat - * the statement - * @param limit - * the limit - * @param offset - * the offset - */ - void appendLimitOffset(SQLStatement stat, long limit, long offset); - - /** - * Returns the preferred DATETIME class for the database. - * <p> - * Either java.util.Date or java.sql.Timestamp - * - * @return preferred DATETIME class - */ - Class<? extends java.util.Date> getDateTimeClass(); - - /** - * When building static string statements this method flattens an object to - * a string representation suitable for a static string statement. - * - * @param o - * @return the string equivalent of this object - */ - String prepareParameter(Object o); -} diff --git a/src/com/iciql/SQLDialectDefault.java b/src/com/iciql/SQLDialectDefault.java deleted file mode 100644 index 364db7b..0000000 --- a/src/com/iciql/SQLDialectDefault.java +++ /dev/null @@ -1,445 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- * Copyright 2012 Frédéric Gaillard.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import java.sql.DatabaseMetaData;
-import java.sql.SQLException;
-import java.text.MessageFormat;
-import java.text.SimpleDateFormat;
-
-import com.iciql.Iciql.ConstraintDeleteType;
-import com.iciql.Iciql.ConstraintUpdateType;
-import com.iciql.TableDefinition.ConstraintForeignKeyDefinition;
-import com.iciql.TableDefinition.ConstraintUniqueDefinition;
-import com.iciql.TableDefinition.FieldDefinition;
-import com.iciql.TableDefinition.IndexDefinition;
-import com.iciql.util.IciqlLogger;
-import com.iciql.util.StatementBuilder;
-import com.iciql.util.StringUtils;
-
-/**
- * Default implementation of an SQL dialect.
- */
-public class SQLDialectDefault implements SQLDialect {
-
- final String LITERAL = "'";
-
- float databaseVersion;
- String databaseName;
- String productVersion;
-
- @Override
- public String toString() {
- return getClass().getName() + ": " + databaseName + " " + productVersion;
- }
-
- @Override
- public void configureDialect(String databaseName, DatabaseMetaData data) {
- this.databaseName = databaseName;
- try {
- databaseVersion = Float.parseFloat(data.getDatabaseMajorVersion() + "."
- + data.getDatabaseMinorVersion());
- productVersion = data.getDatabaseProductVersion();
- } catch (SQLException e) {
- throw new IciqlException(e);
- }
- }
-
- /**
- * Allows subclasses to change the type of a column for a CREATE statement.
- *
- * @param sqlType
- * @return the SQL type or a preferred alternative
- */
- @Override
- public String convertSqlType(String sqlType) {
- return sqlType;
- }
-
- @Override
- public Class<? extends java.util.Date> getDateTimeClass() {
- return java.util.Date.class;
- }
-
- @Override
- public String prepareTableName(String schemaName, String tableName) {
- if (StringUtils.isNullOrEmpty(schemaName)) {
- return tableName;
- }
- return schemaName + "." + tableName;
- }
-
- @Override
- public String prepareColumnName(String name) {
- return name;
- }
-
- @Override
- public <T> void prepareDropTable(SQLStatement stat, TableDefinition<T> def) {
- StatementBuilder buff = new StatementBuilder("DROP TABLE IF EXISTS "
- + prepareTableName(def.schemaName, def.tableName));
- stat.setSQL(buff.toString());
- return;
- }
-
- protected <T> String prepareCreateTable(TableDefinition<T> def) {
- return "CREATE TABLE";
- }
-
- @Override
- public <T> void prepareCreateTable(SQLStatement stat, TableDefinition<T> def) {
- StatementBuilder buff = new StatementBuilder();
- buff.append(prepareCreateTable(def));
- buff.append(" ");
- buff.append(prepareTableName(def.schemaName, def.tableName)).append('(');
-
- boolean hasIdentityColumn = false;
- for (FieldDefinition field : def.fields) {
- buff.appendExceptFirst(", ");
- buff.append(prepareColumnName(field.columnName)).append(' ');
- String dataType = field.dataType;
- if (dataType.equals("VARCHAR")) {
- // check to see if we should use VARCHAR or CLOB
- if (field.length <= 0) {
- dataType = "CLOB";
- }
- buff.append(convertSqlType(dataType));
- if (field.length > 0) {
- buff.append('(').append(field.length).append(')');
- }
- } else if (dataType.equals("DECIMAL")) {
- // DECIMAL(precision,scale)
- buff.append(convertSqlType(dataType));
- if (field.length > 0) {
- buff.append('(').append(field.length);
- if (field.scale > 0) {
- buff.append(',').append(field.scale);
- }
- buff.append(')');
- }
- } else {
- // other
- hasIdentityColumn |= prepareColumnDefinition(buff, convertSqlType(dataType),
- field.isAutoIncrement, field.isPrimaryKey);
- }
-
- // default values
- if (!field.isAutoIncrement && !field.isPrimaryKey) {
- String dv = field.defaultValue;
- if (!StringUtils.isNullOrEmpty(dv)) {
- if (ModelUtils.isProperlyFormattedDefaultValue(dv)
- && ModelUtils.isValidDefaultValue(field.field.getType(), dv)) {
- buff.append(" DEFAULT " + dv);
- }
- }
- }
-
- if (!field.nullable) {
- buff.append(" NOT NULL");
- }
- }
-
- // if table does not have identity column then specify primary key
- if (!hasIdentityColumn) {
- if (def.primaryKeyColumnNames != null && def.primaryKeyColumnNames.size() > 0) {
- buff.append(", PRIMARY KEY(");
- buff.resetCount();
- for (String n : def.primaryKeyColumnNames) {
- buff.appendExceptFirst(", ");
- buff.append(prepareColumnName(n));
- }
- buff.append(')');
- }
- }
- buff.append(')');
- stat.setSQL(buff.toString());
- }
-
- @Override
- public <T> void prepareDropView(SQLStatement stat, TableDefinition<T> def) {
- StatementBuilder buff = new StatementBuilder("DROP VIEW "
- + prepareTableName(def.schemaName, def.tableName));
- stat.setSQL(buff.toString());
- return;
- }
-
- protected <T> String prepareCreateView(TableDefinition<T> def) {
- return "CREATE VIEW";
- }
-
- @Override
- public <T> void prepareCreateView(SQLStatement stat, TableDefinition<T> def) {
- StatementBuilder buff = new StatementBuilder();
- buff.append(" FROM ");
- buff.append(prepareTableName(def.schemaName, def.viewTableName));
-
- StatementBuilder where = new StatementBuilder();
- for (FieldDefinition field : def.fields) {
- if (!StringUtils.isNullOrEmpty(field.constraint)) {
- where.appendExceptFirst(", ");
- String col = prepareColumnName(field.columnName);
- String constraint = field.constraint.replace("{0}", col).replace("this", col);
- where.append(constraint);
- }
- }
- if (where.length() > 0) {
- buff.append(" WHERE ");
- buff.append(where.toString());
- }
-
- prepareCreateView(stat, def, buff.toString());
- }
-
- @Override
- public <T> void prepareCreateView(SQLStatement stat, TableDefinition<T> def, String fromWhere) {
- StatementBuilder buff = new StatementBuilder();
- buff.append(prepareCreateView(def));
- buff.append(" ");
- buff.append(prepareTableName(def.schemaName, def.tableName));
-
- buff.append(" AS SELECT ");
- for (FieldDefinition field : def.fields) {
- buff.appendExceptFirst(", ");
- buff.append(prepareColumnName(field.columnName));
- }
- buff.append(fromWhere);
- stat.setSQL(buff.toString());
- }
-
- protected boolean isIntegerType(String dataType) {
- if ("INT".equals(dataType)) {
- return true;
- } else if ("BIGINT".equals(dataType)) {
- return true;
- } else if ("TINYINT".equals(dataType)) {
- return true;
- } else if ("SMALLINT".equals(dataType)) {
- return true;
- }
- return false;
- }
-
- protected boolean prepareColumnDefinition(StatementBuilder buff, String dataType,
- boolean isAutoIncrement, boolean isPrimaryKey) {
- buff.append(dataType);
- if (isAutoIncrement) {
- buff.append(" AUTO_INCREMENT");
- }
- return false;
- }
-
- @Override
- public void prepareCreateIndex(SQLStatement stat, String schemaName, String tableName,
- IndexDefinition index) {
- StatementBuilder buff = new StatementBuilder();
- buff.append("CREATE ");
- switch (index.type) {
- case UNIQUE:
- buff.append("UNIQUE ");
- break;
- case UNIQUE_HASH:
- buff.append("UNIQUE ");
- break;
- default:
- IciqlLogger.warn("{0} does not support hash indexes", getClass().getSimpleName());
- }
- buff.append("INDEX ");
- buff.append(index.indexName);
- buff.append(" ON ");
- // FIXME maybe we can use schemaName ?
- // buff.append(prepareTableName(schemaName, tableName));
- buff.append(tableName);
- buff.append("(");
- for (String col : index.columnNames) {
- buff.appendExceptFirst(", ");
- buff.append(prepareColumnName(col));
- }
- buff.append(") ");
-
- stat.setSQL(buff.toString().trim());
- }
-
- /**
- * PostgreSQL and Derby do not support the SQL2003 MERGE syntax, but we can
- * use a trick to insert a row if it does not exist and call update() in
- * Db.merge() if the affected row count is 0.
- * <p>
- * Databases that do support a MERGE syntax should override this method.
- * <p>
- * http://stackoverflow.com/questions/407688
- */
- @Override
- public <T> void prepareMerge(SQLStatement stat, String schemaName, String tableName,
- TableDefinition<T> def, Object obj) {
- StatementBuilder buff = new StatementBuilder("INSERT INTO ");
- buff.append(prepareTableName(schemaName, tableName));
- buff.append(" (");
- buff.resetCount();
- for (FieldDefinition field : def.fields) {
- buff.appendExceptFirst(", ");
- buff.append(prepareColumnName(field.columnName));
- }
- buff.append(") (SELECT ");
- buff.resetCount();
- for (FieldDefinition field : def.fields) {
- buff.appendExceptFirst(", ");
- buff.append('?');
- Object value = def.getValue(obj, field);
- stat.addParameter(value);
- }
- buff.append(" FROM ");
- buff.append(prepareTableName(schemaName, tableName));
- buff.append(" WHERE ");
- buff.resetCount();
- for (FieldDefinition field : def.fields) {
- if (field.isPrimaryKey) {
- buff.appendExceptFirst(" AND ");
- buff.append(MessageFormat.format("{0} = ?", prepareColumnName(field.columnName)));
- Object value = def.getValue(obj, field);
- stat.addParameter(value);
- }
- }
- buff.append(" HAVING count(*)=0)");
- stat.setSQL(buff.toString());
- }
-
- @Override
- public void appendLimitOffset(SQLStatement stat, long limit, long offset) {
- if (limit > 0) {
- stat.appendSQL(" LIMIT " + limit);
- }
- if (offset > 0) {
- stat.appendSQL(" OFFSET " + offset);
- }
- }
-
- @Override
- public String prepareParameter(Object o) {
- if (o instanceof String) {
- return LITERAL + o.toString().replace(LITERAL, "''") + LITERAL;
- } else if (o instanceof Character) {
- return LITERAL + o.toString() + LITERAL;
- } else if (o instanceof java.sql.Time) {
- return LITERAL + new SimpleDateFormat("HH:mm:ss").format(o) + LITERAL;
- } else if (o instanceof java.sql.Date) {
- return LITERAL + new SimpleDateFormat("yyyy-MM-dd").format(o) + LITERAL;
- } else if (o instanceof java.util.Date) {
- return LITERAL + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(o) + LITERAL;
- }
- return o.toString();
- }
-
- @SuppressWarnings("incomplete-switch")
- @Override
- public void prepareCreateConstraintForeignKey(SQLStatement stat, String schemaName, String tableName, ConstraintForeignKeyDefinition constraint) {
- StatementBuilder buff = new StatementBuilder();
- buff.append("ALTER TABLE ");
- buff.append(prepareTableName(schemaName, tableName));
- buff.append(" ADD CONSTRAINT ");
- buff.append(constraint.constraintName);
- buff.append(" FOREIGN KEY ");
- buff.append(" (");
- for (String col : constraint.foreignColumns) {
- buff.appendExceptFirst(", ");
- buff.append(prepareColumnName(col));
- }
- buff.append(") ");
- buff.append(" REFERENCES ");
- buff.append(constraint.referenceTable);
- buff.append(" (");
- buff.resetCount();
- for (String col : constraint.referenceColumns) {
- buff.appendExceptFirst(", ");
- buff.append(prepareColumnName(col));
- }
- buff.append(") ");
- if (constraint.deleteType != ConstraintDeleteType.UNSET) {
- buff.append(" ON DELETE ");
- switch (constraint.deleteType) {
- case CASCADE:
- buff.append("CASCADE ");
- break;
- case RESTRICT:
- buff.append("RESTRICT ");
- break;
- case SET_NULL:
- buff.append("SET NULL ");
- break;
- case NO_ACTION:
- buff.append("NO ACTION ");
- break;
- case SET_DEFAULT:
- buff.append("SET DEFAULT ");
- break;
- }
- }
- if (constraint.updateType != ConstraintUpdateType.UNSET) {
- buff.append(" ON UPDATE ");
- switch (constraint.updateType) {
- case CASCADE:
- buff.append("CASCADE ");
- break;
- case RESTRICT:
- buff.append("RESTRICT ");
- break;
- case SET_NULL:
- buff.append("SET NULL ");
- break;
- case NO_ACTION:
- buff.append("NO ACTION ");
- break;
- case SET_DEFAULT:
- buff.append("SET DEFAULT ");
- break;
- }
- }
- switch (constraint.deferrabilityType) {
- case DEFERRABLE_INITIALLY_DEFERRED:
- buff.append("DEFERRABLE INITIALLY DEFERRED ");
- break;
- case DEFERRABLE_INITIALLY_IMMEDIATE:
- buff.append("DEFERRABLE INITIALLY IMMEDIATE ");
- break;
- case NOT_DEFERRABLE:
- buff.append("NOT DEFERRABLE ");
- break;
- case UNSET:
- break;
- }
- stat.setSQL(buff.toString().trim());
- }
-
- @Override
- public void prepareCreateConstraintUnique(SQLStatement stat, String schemaName, String tableName, ConstraintUniqueDefinition constraint) {
- StatementBuilder buff = new StatementBuilder();
- buff.append("ALTER TABLE ");
- buff.append(prepareTableName(schemaName, tableName));
- buff.append(" ADD CONSTRAINT ");
- buff.append(constraint.constraintName);
- buff.append(" UNIQUE ");
- buff.append(" (");
- for (String col : constraint.uniqueColumns) {
- buff.appendExceptFirst(", ");
- buff.append(prepareColumnName(col));
- }
- buff.append(") ");
- stat.setSQL(buff.toString().trim());
- }
-
-}
\ No newline at end of file diff --git a/src/com/iciql/SQLDialectDerby.java b/src/com/iciql/SQLDialectDerby.java deleted file mode 100644 index f954a7c..0000000 --- a/src/com/iciql/SQLDialectDerby.java +++ /dev/null @@ -1,71 +0,0 @@ -/*
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import com.iciql.util.StatementBuilder;
-
-/**
- * Derby database dialect.
- */
-public class SQLDialectDerby extends SQLDialectDefault {
-
- @Override
- public Class<? extends java.util.Date> getDateTimeClass() {
- return java.sql.Timestamp.class;
- }
-
- @Override
- public String convertSqlType(String sqlType) {
- if ("TINYINT".equals(sqlType)) {
- // Derby does not have a TINYINT/BYTE type
- return "SMALLINT";
- }
- return sqlType;
- }
-
- @Override
- public void appendLimitOffset(SQLStatement stat, long limit, long offset) {
- // FETCH/OFFSET added in 10.5
- if (databaseVersion >= 10.5f) {
- if (offset > 0) {
- stat.appendSQL(" OFFSET " + offset + (offset == 1 ? " ROW" : " ROWS"));
- }
- if (limit > 0) {
- stat.appendSQL(" FETCH NEXT " + limit + (limit == 1 ? " ROW" : " ROWS") + " ONLY");
- }
- }
- }
-
- @Override
- protected boolean prepareColumnDefinition(StatementBuilder buff, String dataType,
- boolean isAutoIncrement, boolean isPrimaryKey) {
- String convertedType = convertSqlType(dataType);
- buff.append(convertedType);
- if (isIntegerType(dataType) && isAutoIncrement) {
- buff.append(" GENERATED BY DEFAULT AS IDENTITY");
- }
- return false;
- }
-
- @Override
- public <T> void prepareDropTable(SQLStatement stat, TableDefinition<T> def) {
- StatementBuilder buff = new StatementBuilder("DROP TABLE "
- + prepareTableName(def.schemaName, def.tableName));
- stat.setSQL(buff.toString());
- return;
- }
-}
\ No newline at end of file diff --git a/src/com/iciql/SQLDialectH2.java b/src/com/iciql/SQLDialectH2.java deleted file mode 100644 index 6b3bab1..0000000 --- a/src/com/iciql/SQLDialectH2.java +++ /dev/null @@ -1,135 +0,0 @@ -/*
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import com.iciql.TableDefinition.FieldDefinition;
-import com.iciql.TableDefinition.IndexDefinition;
-import com.iciql.util.StatementBuilder;
-
-/**
- * H2 database dialect.
- */
-public class SQLDialectH2 extends SQLDialectDefault {
-
- /**
- * CACHED tables are created by default. MEMORY tables are created upon
- * request.
- */
- @Override
- protected <T> String prepareCreateTable(TableDefinition<T> def) {
- if (def.memoryTable) {
- return "CREATE MEMORY TABLE IF NOT EXISTS";
- } else {
- return "CREATE CACHED TABLE IF NOT EXISTS";
- }
- }
-
- @Override
- protected <T> String prepareCreateView(TableDefinition<T> def) {
- return "CREATE VIEW IF NOT EXISTS";
- }
-
- @Override
- public <T> void prepareDropView(SQLStatement stat, TableDefinition<T> def) {
- StatementBuilder buff = new StatementBuilder("DROP VIEW IF EXISTS "
- + prepareTableName(def.schemaName, def.tableName));
- stat.setSQL(buff.toString());
- return;
- }
-
- @Override
- protected boolean prepareColumnDefinition(StatementBuilder buff, String dataType,
- boolean isAutoIncrement, boolean isPrimaryKey) {
- String convertedType = convertSqlType(dataType);
- boolean isIdentity = false;
- if (isIntegerType(dataType)) {
- if (isAutoIncrement && isPrimaryKey) {
- buff.append("IDENTITY");
- isIdentity = true;
- } else if (isAutoIncrement) {
- buff.append(convertedType);
- buff.append(" AUTO_INCREMENT");
- } else {
- buff.append(convertedType);
- }
- } else {
- buff.append(convertedType);
- }
- return isIdentity;
- }
-
- @Override
- public void prepareCreateIndex(SQLStatement stat, String schema, String table, IndexDefinition index) {
- StatementBuilder buff = new StatementBuilder();
- buff.append("CREATE ");
- switch (index.type) {
- case STANDARD:
- break;
- case UNIQUE:
- buff.append("UNIQUE ");
- break;
- case HASH:
- buff.append("HASH ");
- break;
- case UNIQUE_HASH:
- buff.append("UNIQUE HASH ");
- break;
- }
- buff.append("INDEX IF NOT EXISTS ");
- buff.append(index.indexName);
- buff.append(" ON ");
- buff.append(table);
- buff.append("(");
- for (String col : index.columnNames) {
- buff.appendExceptFirst(", ");
- buff.append(col);
- }
- buff.append(")");
- stat.setSQL(buff.toString());
- }
-
- @Override
- public <T> void prepareMerge(SQLStatement stat, String schemaName, String tableName,
- TableDefinition<T> def, Object obj) {
- StatementBuilder buff = new StatementBuilder("MERGE INTO ");
- buff.append(prepareTableName(schemaName, tableName)).append(" (");
- buff.resetCount();
- for (FieldDefinition field : def.fields) {
- buff.appendExceptFirst(", ");
- buff.append(field.columnName);
- }
- buff.append(") KEY(");
- buff.resetCount();
- for (FieldDefinition field : def.fields) {
- if (field.isPrimaryKey) {
- buff.appendExceptFirst(", ");
- buff.append(field.columnName);
- }
- }
- buff.append(") ");
- buff.resetCount();
- buff.append("VALUES (");
- for (FieldDefinition field : def.fields) {
- buff.appendExceptFirst(", ");
- buff.append('?');
- Object value = def.getValue(obj, field);
- stat.addParameter(value);
- }
- buff.append(')');
- stat.setSQL(buff.toString());
- }
-}
\ No newline at end of file diff --git a/src/com/iciql/SQLDialectHSQL.java b/src/com/iciql/SQLDialectHSQL.java deleted file mode 100644 index 82e6833..0000000 --- a/src/com/iciql/SQLDialectHSQL.java +++ /dev/null @@ -1,149 +0,0 @@ -/*
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import java.text.MessageFormat;
-
-import com.iciql.TableDefinition.FieldDefinition;
-import com.iciql.util.StatementBuilder;
-
-/**
- * HyperSQL database dialect.
- */
-public class SQLDialectHSQL extends SQLDialectDefault {
-
- /**
- * CACHED tables are created by default. MEMORY tables are created upon
- * request.
- */
- @Override
- protected <T> String prepareCreateTable(TableDefinition<T> def) {
- if (def.memoryTable) {
- return "CREATE MEMORY TABLE IF NOT EXISTS";
- } else {
- return "CREATE CACHED TABLE IF NOT EXISTS";
- }
- }
-
- @Override
- public <T> void prepareDropView(SQLStatement stat, TableDefinition<T> def) {
- StatementBuilder buff = new StatementBuilder("DROP VIEW IF EXISTS "
- + prepareTableName(def.schemaName, def.tableName));
- stat.setSQL(buff.toString());
- return;
- }
-
- @Override
- protected boolean prepareColumnDefinition(StatementBuilder buff, String dataType,
- boolean isAutoIncrement, boolean isPrimaryKey) {
- boolean isIdentity = false;
- String convertedType = convertSqlType(dataType);
- buff.append(convertedType);
- if (isIntegerType(dataType) && isAutoIncrement && isPrimaryKey) {
- buff.append(" IDENTITY");
- isIdentity = true;
- }
- return isIdentity;
- }
-
- @Override
- public <T> void prepareMerge(SQLStatement stat, String schemaName, String tableName,
- TableDefinition<T> def, Object obj) {
- final String valuePrefix = "v";
- StatementBuilder buff = new StatementBuilder("MERGE INTO ");
- buff.append(prepareTableName(schemaName, tableName));
- // a, b, c....
- buff.append(" USING (VALUES(");
- for (FieldDefinition field : def.fields) {
- buff.appendExceptFirst(", ");
- buff.append("CAST(? AS ");
- String dataType = convertSqlType(field.dataType);
- buff.append(dataType);
- if ("VARCHAR".equals(dataType)) {
- if (field.length > 0) {
- // VARCHAR(x)
- buff.append(MessageFormat.format("({0})", field.length));
- }
- } else if ("DECIMAL".equals(dataType)) {
- if (field.length > 0) {
- if (field.scale > 0) {
- // DECIMAL(x,y)
- buff.append(MessageFormat.format("({0},{1})", field.length, field.scale));
- } else {
- // DECIMAL(x)
- buff.append(MessageFormat.format("({0})", field.length));
- }
- }
- }
- buff.append(')');
- Object value = def.getValue(obj, field);
- stat.addParameter(value);
- }
-
- // map to temporary table
- buff.resetCount();
- buff.append(")) AS vals (");
- for (FieldDefinition field : def.fields) {
- buff.appendExceptFirst(", ");
- buff.append(prepareColumnName(valuePrefix + field.columnName));
- }
-
- buff.append(") ON ");
-
- // create the ON condition
- // (va, vb) = (va,vb)
- String[] prefixes = { "", valuePrefix };
- for (int i = 0; i < prefixes.length; i++) {
- String prefix = prefixes[i];
- buff.resetCount();
- buff.append('(');
- for (FieldDefinition field : def.fields) {
- if (field.isPrimaryKey) {
- buff.appendExceptFirst(", ");
- buff.append(prepareColumnName(prefix + field.columnName));
- }
- }
- buff.append(")");
- if (i == 0) {
- buff.append('=');
- }
- }
-
- // UPDATE
- // set a=va
- buff.append(" WHEN MATCHED THEN UPDATE SET ");
- buff.resetCount();
- for (FieldDefinition field : def.fields) {
- buff.appendExceptFirst(", ");
- buff.append(prepareColumnName(field.columnName));
- buff.append('=');
- buff.append(prepareColumnName(valuePrefix + field.columnName));
- }
-
- // INSERT
- // insert va, vb, vc....
- buff.append(" WHEN NOT MATCHED THEN INSERT ");
- buff.resetCount();
- buff.append(" VALUES (");
- for (FieldDefinition field : def.fields) {
- buff.appendExceptFirst(", ");
- buff.append(prepareColumnName(valuePrefix + field.columnName));
- }
- buff.append(')');
- stat.setSQL(buff.toString());
- }
-}
\ No newline at end of file diff --git a/src/com/iciql/SQLDialectMSSQL.java b/src/com/iciql/SQLDialectMSSQL.java deleted file mode 100644 index 92b1297..0000000 --- a/src/com/iciql/SQLDialectMSSQL.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012 Alex Telepov. - * Copyright 2012 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql; - -/** - * MS SQL Server database dialect. - */ -public class SQLDialectMSSQL extends SQLDialectDefault { - - /** - * Append limit and offset rows - * - * @param stat Statement - * @param limit Limit rows - * @param offset Offset rows - */ - @Override - public void appendLimitOffset(SQLStatement stat, long limit, long offset) { - if (offset > 0) { - throw new IciqlException("iciql does not support offset for MSSQL dialect!"); - } - StringBuilder query = new StringBuilder(stat.getSQL()); - - // for databaseVersion >= 2012 need Offset - if (limit > 0) { - int indexSelect = query.indexOf("SELECT"); - - if (indexSelect >= 0) { - StringBuilder subPathQuery = new StringBuilder(" TOP "); - subPathQuery.append(Long.toString(limit)); - - query.insert(indexSelect + "SELECT".length(), subPathQuery); - - stat.setSQL(query.toString()); - } - } - } -} diff --git a/src/com/iciql/SQLDialectMySQL.java b/src/com/iciql/SQLDialectMySQL.java deleted file mode 100644 index 52676d4..0000000 --- a/src/com/iciql/SQLDialectMySQL.java +++ /dev/null @@ -1,93 +0,0 @@ -/*
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import com.iciql.TableDefinition.FieldDefinition;
-import com.iciql.util.StatementBuilder;
-
-/**
- * MySQL database dialect.
- */
-public class SQLDialectMySQL extends SQLDialectDefault {
-
- @Override
- public String convertSqlType(String sqlType) {
- if (sqlType.equals("CLOB")) {
- return "TEXT";
- }
- return sqlType;
- }
-
- @Override
- protected <T> String prepareCreateTable(TableDefinition<T> def) {
- return "CREATE TABLE IF NOT EXISTS";
- }
-
- @Override
- public <T> void prepareDropView(SQLStatement stat, TableDefinition<T> def) {
- StatementBuilder buff = new StatementBuilder("DROP VIEW IF EXISTS "
- + prepareTableName(def.schemaName, def.tableName));
- stat.setSQL(buff.toString());
- return;
- }
-
- @Override
- public String prepareColumnName(String name) {
- return "`" + name + "`";
- }
-
- @Override
- protected boolean prepareColumnDefinition(StatementBuilder buff, String dataType, boolean isAutoIncrement,
- boolean isPrimaryKey) {
- String convertedType = convertSqlType(dataType);
- buff.append(convertedType);
- if (isIntegerType(dataType) && isAutoIncrement) {
- buff.append(" AUTO_INCREMENT");
- }
- return false;
- }
-
- @Override
- public <T> void prepareMerge(SQLStatement stat, String schemaName, String tableName,
- TableDefinition<T> def, Object obj) {
- StatementBuilder buff = new StatementBuilder("INSERT INTO ");
- buff.append(prepareTableName(schemaName, tableName)).append(" (");
- buff.resetCount();
- for (FieldDefinition field : def.fields) {
- buff.appendExceptFirst(", ");
- buff.append(field.columnName);
- }
- buff.resetCount();
- buff.append(") VALUES (");
- for (FieldDefinition field : def.fields) {
- buff.appendExceptFirst(", ");
- buff.append('?');
- Object value = def.getValue(obj, field);
- stat.addParameter(value);
- }
- buff.append(") ON DUPLICATE KEY UPDATE ");
- buff.resetCount();
- for (FieldDefinition field : def.fields) {
- buff.appendExceptFirst(", ");
- buff.append(field.columnName);
- buff.append("=VALUES(");
- buff.append(field.columnName);
- buff.append(')');
- }
- stat.setSQL(buff.toString());
- }
-}
\ No newline at end of file diff --git a/src/com/iciql/SQLDialectPostgreSQL.java b/src/com/iciql/SQLDialectPostgreSQL.java deleted file mode 100644 index fc115ab..0000000 --- a/src/com/iciql/SQLDialectPostgreSQL.java +++ /dev/null @@ -1,103 +0,0 @@ -/*
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import com.iciql.TableDefinition.IndexDefinition;
-import com.iciql.util.StatementBuilder;
-
-/**
- * PostgreSQL database dialect.
- */
-public class SQLDialectPostgreSQL extends SQLDialectDefault {
-
- @Override
- public Class<? extends java.util.Date> getDateTimeClass() {
- return java.sql.Timestamp.class;
- }
-
- @Override
- public String convertSqlType(String sqlType) {
- if ("DOUBLE".equals(sqlType)) {
- return "DOUBLE PRECISION";
- } else if ("TINYINT".equals(sqlType)) {
- // PostgreSQL does not have a byte type
- return "SMALLINT";
- } else if ("CLOB".equals(sqlType)) {
- return "TEXT";
- } else if ("BLOB".equals(sqlType)) {
- return "BYTEA";
- }
- return sqlType;
- }
-
- @Override
- protected boolean prepareColumnDefinition(StatementBuilder buff, String dataType,
- boolean isAutoIncrement, boolean isPrimaryKey) {
- String convertedType = convertSqlType(dataType);
- if (isIntegerType(dataType)) {
- if (isAutoIncrement) {
- if ("BIGINT".equals(dataType)) {
- buff.append("BIGSERIAL");
- } else {
- buff.append("SERIAL");
- }
- } else {
- buff.append(convertedType);
- }
- } else {
- buff.append(convertedType);
- }
- return false;
- }
-
- @Override
- public void prepareCreateIndex(SQLStatement stat, String schemaName, String tableName,
- IndexDefinition index) {
- StatementBuilder buff = new StatementBuilder();
- buff.append("CREATE ");
- switch (index.type) {
- case UNIQUE:
- buff.append("UNIQUE ");
- break;
- case UNIQUE_HASH:
- buff.append("UNIQUE ");
- break;
- }
- buff.append("INDEX ");
- buff.append(index.indexName);
- buff.append(" ON ");
- buff.append(tableName);
-
- switch (index.type) {
- case HASH:
- buff.append(" USING HASH");
- break;
- case UNIQUE_HASH:
- buff.append(" USING HASH");
- break;
- }
-
- buff.append(" (");
- for (String col : index.columnNames) {
- buff.appendExceptFirst(", ");
- buff.append(prepareColumnName(col));
- }
- buff.append(") ");
-
- stat.setSQL(buff.toString().trim());
- }
-}
\ No newline at end of file diff --git a/src/com/iciql/SQLStatement.java b/src/com/iciql/SQLStatement.java deleted file mode 100644 index 394fc42..0000000 --- a/src/com/iciql/SQLStatement.java +++ /dev/null @@ -1,190 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.StringTokenizer;
-
-import com.iciql.util.JdbcUtils;
-
-/**
- * This class represents a parameterized SQL statement.
- */
-
-public class SQLStatement {
- private Db db;
- private StringBuilder buff = new StringBuilder();
- private String sql;
- private ArrayList<Object> params = new ArrayList<Object>();
-
- SQLStatement(Db db) {
- this.db = db;
- }
-
- public void setSQL(String sql) {
- this.sql = sql;
- buff = new StringBuilder(sql);
- }
-
- public SQLStatement appendSQL(String s) {
- buff.append(s);
- sql = null;
- return this;
- }
-
- public SQLStatement appendTable(String schema, String table) {
- return appendSQL(db.getDialect().prepareTableName(schema, table));
- }
-
- public SQLStatement appendColumn(String column) {
- return appendSQL(db.getDialect().prepareColumnName(column));
- }
-
- /**
- * getSQL returns a simple string representation of the parameterized
- * statement which will be used later, internally, with prepareStatement.
- *
- * @return a simple sql statement
- */
- String getSQL() {
- if (sql == null) {
- sql = buff.toString();
- }
- return sql;
- }
-
- /**
- * toSQL creates a static sql statement with the referenced parameters
- * encoded in the statement.
- *
- * @return a complete sql statement
- */
- String toSQL() {
- if (sql == null) {
- sql = buff.toString();
- }
- if (params.size() == 0) {
- return sql;
- }
- StringBuilder sb = new StringBuilder();
- // TODO this needs to me more sophisticated
- StringTokenizer st = new StringTokenizer(sql, "?", false);
- int i = 0;
- while (st.hasMoreTokens()) {
- sb.append(st.nextToken());
- if (i < params.size()) {
- Object o = params.get(i);
- if (RuntimeParameter.PARAMETER == o) {
- // dynamic parameter
- sb.append('?');
- } else {
- // static parameter
- sb.append(db.getDialect().prepareParameter(o));
- }
- i++;
- }
- }
- return sb.toString();
- }
-
- public SQLStatement addParameter(Object o) {
- // Automatically convert java.util.Date to java.sql.Timestamp
- // if the dialect requires java.sql.Timestamp objects (e.g. Derby)
- if (o != null && o.getClass().equals(java.util.Date.class)
- && db.getDialect().getDateTimeClass().equals(java.sql.Timestamp.class)) {
- o = new java.sql.Timestamp(((java.util.Date) o).getTime());
- }
- params.add(o);
- return this;
- }
-
- void execute() {
- PreparedStatement ps = null;
- try {
- ps = prepare(false);
- ps.execute();
- } catch (SQLException e) {
- throw IciqlException.fromSQL(getSQL(), e);
- } finally {
- JdbcUtils.closeSilently(ps);
- }
- }
-
- ResultSet executeQuery() {
- try {
- return prepare(false).executeQuery();
- } catch (SQLException e) {
- throw IciqlException.fromSQL(getSQL(), e);
- }
- }
-
- int executeUpdate() {
- PreparedStatement ps = null;
- try {
- ps = prepare(false);
- return ps.executeUpdate();
- } catch (SQLException e) {
- throw IciqlException.fromSQL(getSQL(), e);
- } finally {
- JdbcUtils.closeSilently(ps);
- }
- }
-
- long executeInsert() {
- PreparedStatement ps = null;
- try {
- ps = prepare(true);
- ps.executeUpdate();
- long identity = -1;
- ResultSet rs = ps.getGeneratedKeys();
- if (rs != null && rs.next()) {
- identity = rs.getLong(1);
- }
- JdbcUtils.closeSilently(rs);
- return identity;
- } catch (SQLException e) {
- throw IciqlException.fromSQL(getSQL(), e);
- } finally {
- JdbcUtils.closeSilently(ps);
- }
- }
-
- private void setValue(PreparedStatement prep, int parameterIndex, Object x) {
- try {
- prep.setObject(parameterIndex, x);
- } catch (SQLException e) {
- IciqlException ix = new IciqlException(e, "error setting parameter {0} as {1}", parameterIndex, x
- .getClass().getSimpleName());
- ix.setSQL(getSQL());
- throw ix;
- }
- }
-
- PreparedStatement prepare(boolean returnGeneratedKeys) {
- PreparedStatement prep = db.prepare(getSQL(), returnGeneratedKeys);
- for (int i = 0; i < params.size(); i++) {
- Object o = params.get(i);
- setValue(prep, i + 1, o);
- }
- return prep;
- }
-
-}
diff --git a/src/com/iciql/SelectColumn.java b/src/com/iciql/SelectColumn.java deleted file mode 100644 index 43a1a93..0000000 --- a/src/com/iciql/SelectColumn.java +++ /dev/null @@ -1,57 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import com.iciql.TableDefinition.FieldDefinition;
-
-/**
- * This class represents a column of a table in a query.
- *
- * @param <T>
- * the table data type
- */
-
-class SelectColumn<T> {
- private SelectTable<T> selectTable;
- private FieldDefinition fieldDef;
-
- SelectColumn(SelectTable<T> table, FieldDefinition fieldDef) {
- this.selectTable = table;
- this.fieldDef = fieldDef;
- }
-
- void appendSQL(SQLStatement stat) {
- if (selectTable.getQuery().isJoin()) {
- stat.appendSQL(selectTable.getAs() + "." + fieldDef.columnName);
- } else {
- stat.appendColumn(fieldDef.columnName);
- }
- }
-
- FieldDefinition getFieldDefinition() {
- return fieldDef;
- }
-
- SelectTable<T> getSelectTable() {
- return selectTable;
- }
-
- Object getCurrentValue() {
- return fieldDef.getValue(selectTable.getCurrent());
- }
-}
diff --git a/src/com/iciql/SelectTable.java b/src/com/iciql/SelectTable.java deleted file mode 100644 index 37b42c4..0000000 --- a/src/com/iciql/SelectTable.java +++ /dev/null @@ -1,112 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import java.util.ArrayList;
-
-import com.iciql.util.Utils;
-
-/**
- * This class represents a table in a query.
- *
- * @param <T>
- * the table class
- */
-
-class SelectTable<T> {
-
- private Query<T> query;
- private Class<T> clazz;
- private T current;
- private String as;
- private TableDefinition<T> aliasDef;
- private boolean outerJoin;
- private ArrayList<Token> joinConditions = Utils.newArrayList();
- private T alias;
-
- @SuppressWarnings("unchecked")
- SelectTable(Db db, Query<T> query, T alias, boolean outerJoin) {
- this.alias = alias;
- this.query = query;
- this.outerJoin = outerJoin;
- aliasDef = (TableDefinition<T>) db.getTableDefinition(alias.getClass());
- clazz = Utils.getClass(alias);
- as = "T" + Utils.nextAsCount();
- }
-
- T getAlias() {
- return alias;
- }
-
- T newObject() {
- return Utils.newObject(clazz);
- }
-
- TableDefinition<T> getAliasDefinition() {
- return aliasDef;
- }
-
- void appendSQL(SQLStatement stat) {
- if (query.isJoin()) {
- stat.appendTable(aliasDef.schemaName, aliasDef.tableName).appendSQL(" AS " + as);
- } else {
- stat.appendTable(aliasDef.schemaName, aliasDef.tableName);
- }
- }
-
- void appendSQLAsJoin(SQLStatement stat, Query<T> q) {
- if (outerJoin) {
- stat.appendSQL(" LEFT OUTER JOIN ");
- } else {
- stat.appendSQL(" INNER JOIN ");
- }
- appendSQL(stat);
- if (!joinConditions.isEmpty()) {
- stat.appendSQL(" ON ");
- for (Token token : joinConditions) {
- token.appendSQL(stat, q);
- stat.appendSQL(" ");
- }
- }
- }
-
- boolean getOuterJoin() {
- return outerJoin;
- }
-
- Query<T> getQuery() {
- return query;
- }
-
- String getAs() {
- return as;
- }
-
- void addConditionToken(Token condition) {
- joinConditions.add(condition);
- }
-
- T getCurrent() {
- return current;
- }
-
- void setCurrent(T current) {
- this.current = current;
- }
-
-}
diff --git a/src/com/iciql/SubQuery.java b/src/com/iciql/SubQuery.java deleted file mode 100644 index 398d214..0000000 --- a/src/com/iciql/SubQuery.java +++ /dev/null @@ -1,32 +0,0 @@ -/*
- * Copyright 2012 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-public class SubQuery<T, Z> {
-
- final Query<T> query;
- final Z z;
-
- public SubQuery(Query<T> query, Z x) {
- this.query = query;
- this.z = x;
- }
-
- public void appendSQL(SQLStatement stat) {
- stat.appendSQL(query.toSubQuery(z));
- }
-}
diff --git a/src/com/iciql/SubQueryCondition.java b/src/com/iciql/SubQueryCondition.java deleted file mode 100644 index effea3b..0000000 --- a/src/com/iciql/SubQueryCondition.java +++ /dev/null @@ -1,41 +0,0 @@ -/*
- * Copyright 2012 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-/**
- * A condition that contains a subquery.
- *
- * @param <A>
- * the operand type
- */
-
-class SubQueryCondition<A, Y, Z> implements Token {
- A x;
- SubQuery<Y, Z> subquery;
-
- SubQueryCondition(A x, SubQuery<Y, Z> subquery) {
- this.x = x;
- this.subquery = subquery;
- }
-
- public <T> void appendSQL(SQLStatement stat, Query<T> query) {
- query.appendSQL(stat, null, x);
- stat.appendSQL(" in (");
- subquery.appendSQL(stat);
- stat.appendSQL(")");
- }
-}
diff --git a/src/com/iciql/TableDefinition.java b/src/com/iciql/TableDefinition.java deleted file mode 100644 index 6d8cb6e..0000000 --- a/src/com/iciql/TableDefinition.java +++ /dev/null @@ -1,1233 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- * Copyright 2012 Frédéric Gaillard.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import java.lang.reflect.Field;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.IdentityHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import com.iciql.Iciql.ConstraintDeferrabilityType;
-import com.iciql.Iciql.ConstraintDeleteType;
-import com.iciql.Iciql.ConstraintUpdateType;
-import com.iciql.Iciql.EnumId;
-import com.iciql.Iciql.EnumType;
-import com.iciql.Iciql.IQColumn;
-import com.iciql.Iciql.IQConstraint;
-import com.iciql.Iciql.IQContraintUnique;
-import com.iciql.Iciql.IQContraintsUnique;
-import com.iciql.Iciql.IQEnum;
-import com.iciql.Iciql.IQContraintForeignKey;
-import com.iciql.Iciql.IQContraintsForeignKey;
-import com.iciql.Iciql.IQIgnore;
-import com.iciql.Iciql.IQIndex;
-import com.iciql.Iciql.IQIndexes;
-import com.iciql.Iciql.IQSchema;
-import com.iciql.Iciql.IQTable;
-import com.iciql.Iciql.IQVersion;
-import com.iciql.Iciql.IQView;
-import com.iciql.Iciql.IndexType;
-import com.iciql.util.IciqlLogger;
-import com.iciql.util.StatementBuilder;
-import com.iciql.util.StringUtils;
-import com.iciql.util.Utils;
-
-/**
- * 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
- */
-
-public class TableDefinition<T> {
-
- /**
- * The meta data of an index.
- */
-
- public static class IndexDefinition {
- public IndexType type;
- public String indexName;
-
- public List<String> columnNames;
- }
-
- /**
- * The meta data of a constraint on foreign key.
- */
-
- public static class ConstraintForeignKeyDefinition {
-
- public String constraintName;
- public List<String> foreignColumns;
- public String referenceTable;
- public List<String> referenceColumns;
- public ConstraintDeleteType deleteType = ConstraintDeleteType.UNSET;
- public ConstraintUpdateType updateType = ConstraintUpdateType.UNSET;
- public ConstraintDeferrabilityType deferrabilityType = ConstraintDeferrabilityType.UNSET;
- }
-
- /**
- * The meta data of a unique constraint.
- */
-
- public static class ConstraintUniqueDefinition {
-
- public String constraintName;
- public List<String> uniqueColumns;
- }
-
-
- /**
- * The meta data of a field.
- */
-
- static class FieldDefinition {
- String columnName;
- Field field;
- String dataType;
- int length;
- int scale;
- boolean isPrimaryKey;
- boolean isAutoIncrement;
- boolean trim;
- boolean nullable;
- String defaultValue;
- EnumType enumType;
- boolean isPrimitive;
- String constraint;
-
- Object getValue(Object obj) {
- try {
- return field.get(obj);
- } catch (Exception e) {
- throw new IciqlException(e);
- }
- }
-
- private Object initWithNewObject(Object obj) {
- Object o = Utils.newObject(field.getType());
- setValue(obj, o);
- return o;
- }
-
- private void setValue(Object obj, Object o) {
- try {
- if (!field.isAccessible()) {
- field.setAccessible(true);
- }
- Class<?> targetType = field.getType();
- if (targetType.isEnum()) {
- o = Utils.convertEnum(o, targetType, enumType);
- } else {
- o = Utils.convert(o, targetType);
- }
- field.set(obj, o);
- } catch (IciqlException e) {
- throw e;
- } catch (Exception e) {
- throw new IciqlException(e);
- }
- }
-
- private Object read(ResultSet rs, int columnIndex) {
- try {
- return rs.getObject(columnIndex);
- } catch (SQLException e) {
- throw new IciqlException(e);
- }
- }
-
- @Override
- public int hashCode() {
- return columnName.hashCode();
- }
-
- @Override
- public boolean equals(Object o) {
- if (o instanceof FieldDefinition) {
- return o.hashCode() == hashCode();
- }
- return false;
- }
- }
-
- public ArrayList<FieldDefinition> fields = Utils.newArrayList();
- String schemaName;
- String tableName;
- String viewTableName;
- int tableVersion;
- List<String> primaryKeyColumnNames;
- boolean memoryTable;
- boolean multiplePrimitiveBools;
-
- private boolean createIfRequired = true;
- private Class<T> clazz;
- private IdentityHashMap<Object, FieldDefinition> fieldMap = Utils.newIdentityHashMap();
- private ArrayList<IndexDefinition> indexes = Utils.newArrayList();
- private ArrayList<ConstraintForeignKeyDefinition> constraintsForeignKey = Utils.newArrayList();
- private ArrayList<ConstraintUniqueDefinition> constraintsUnique = Utils.newArrayList();
-
- TableDefinition(Class<T> clazz) {
- this.clazz = clazz;
- schemaName = null;
- tableName = clazz.getSimpleName();
- }
-
- Class<T> getModelClass() {
- return clazz;
- }
-
- List<FieldDefinition> getFields() {
- return fields;
- }
-
- void defineSchemaName(String schemaName) {
- this.schemaName = schemaName;
- }
-
- void defineTableName(String tableName) {
- this.tableName = tableName;
- }
-
- void defineViewTableName(String viewTableName) {
- this.viewTableName = viewTableName;
- }
-
- void defineMemoryTable() {
- this.memoryTable = true;
- }
-
- void defineSkipCreate() {
- this.createIfRequired = false;
- }
-
- /**
- * Define a primary key by the specified model fields.
- *
- * @param modelFields
- * the ordered list of model fields
- */
- void definePrimaryKey(Object[] modelFields) {
- List<String> columnNames = mapColumnNames(modelFields);
- setPrimaryKey(columnNames);
- }
-
- /**
- * Define a primary key by the specified column names.
- *
- * @param columnNames
- * the ordered list of column names
- */
- private void setPrimaryKey(List<String> columnNames) {
- primaryKeyColumnNames = Utils.newArrayList(columnNames);
- List<String> pkNames = Utils.newArrayList();
- for (String name : columnNames) {
- pkNames.add(name.toLowerCase());
- }
- // set isPrimaryKey flag for all field definitions
- for (FieldDefinition fieldDefinition : fieldMap.values()) {
- fieldDefinition.isPrimaryKey = pkNames.contains(fieldDefinition.columnName.toLowerCase());
- }
- }
-
- private <A> String getColumnName(A fieldObject) {
- FieldDefinition def = fieldMap.get(fieldObject);
- return def == null ? null : def.columnName;
- }
-
- private ArrayList<String> mapColumnNames(Object[] columns) {
- ArrayList<String> columnNames = Utils.newArrayList();
- for (Object column : columns) {
- columnNames.add(getColumnName(column));
- }
- return columnNames;
- }
-
- /**
- * Defines an index with the specified model fields.
- *
- * @param name
- * the index name (optional)
- * @param type
- * the index type (STANDARD, HASH, UNIQUE, UNIQUE_HASH)
- * @param modelFields
- * the ordered list of model fields
- */
- void defineIndex(String name, IndexType type, Object[] modelFields) {
- List<String> columnNames = mapColumnNames(modelFields);
- addIndex(name, type, columnNames);
- }
-
- /**
- * Defines an index with the specified column names.
- *
- * @param type
- * the index type (STANDARD, HASH, UNIQUE, UNIQUE_HASH)
- * @param columnNames
- * the ordered list of column names
- */
- private void addIndex(String name, IndexType type, List<String> columnNames) {
- IndexDefinition index = new IndexDefinition();
- if (StringUtils.isNullOrEmpty(name)) {
- index.indexName = tableName + "_idx_" + indexes.size();
- } else {
- index.indexName = name;
- }
- index.columnNames = Utils.newArrayList(columnNames);
- index.type = type;
- indexes.add(index);
- }
-
- /**
- * Defines an unique constraint with the specified model fields.
- *
- * @param name
- * the constraint name (optional)
- * @param modelFields
- * the ordered list of model fields
- */
- void defineConstraintUnique(String name, Object[] modelFields) {
- List<String> columnNames = mapColumnNames(modelFields);
- addConstraintUnique(name, columnNames);
- }
-
- /**
- * Defines an unique constraint.
- *
- * @param name
- * @param columnNames
- */
- private void addConstraintUnique(String name, List<String> columnNames) {
- ConstraintUniqueDefinition constraint = new ConstraintUniqueDefinition();
- if (StringUtils.isNullOrEmpty(name)) {
- constraint.constraintName = tableName + "_unique_" + constraintsUnique.size();
- } else {
- constraint.constraintName = name;
- }
- constraint.uniqueColumns = Utils.newArrayList(columnNames);
- constraintsUnique.add(constraint);
- }
-
- /**
- * Defines a foreign key constraint with the specified model fields.
- *
- * @param name
- * the constraint name (optional)
- * @param modelFields
- * the ordered list of model fields
- */
- void defineForeignKey(String name, Object[] modelFields, String refTableName, Object[] refModelFields,
- ConstraintDeleteType deleteType, ConstraintUpdateType updateType,
- ConstraintDeferrabilityType deferrabilityType) {
- List<String> columnNames = mapColumnNames(modelFields);
- List<String> referenceColumnNames = mapColumnNames(refModelFields);
- addConstraintForeignKey(name, columnNames, refTableName, referenceColumnNames,
- deleteType, updateType, deferrabilityType);
- }
-
- void defineColumnName(Object column, String columnName) {
- FieldDefinition def = fieldMap.get(column);
- if (def != null) {
- def.columnName = columnName;
- }
- }
-
- void defineAutoIncrement(Object column) {
- FieldDefinition def = fieldMap.get(column);
- if (def != null) {
- def.isAutoIncrement = true;
- }
- }
-
- void defineLength(Object column, int length) {
- FieldDefinition def = fieldMap.get(column);
- if (def != null) {
- def.length = length;
- }
- }
-
- void defineScale(Object column, int scale) {
- FieldDefinition def = fieldMap.get(column);
- if (def != null) {
- def.scale = scale;
- }
- }
-
- void defineTrim(Object column) {
- FieldDefinition def = fieldMap.get(column);
- if (def != null) {
- def.trim = true;
- }
- }
-
- void defineNullable(Object column, boolean isNullable) {
- FieldDefinition def = fieldMap.get(column);
- if (def != null) {
- def.nullable = isNullable;
- }
- }
-
- void defineDefaultValue(Object column, String defaultValue) {
- FieldDefinition def = fieldMap.get(column);
- if (def != null) {
- def.defaultValue = defaultValue;
- }
- }
-
- void defineConstraint(Object column, String constraint) {
- FieldDefinition def = fieldMap.get(column);
- if (def != null) {
- def.constraint = constraint;
- }
- }
-
- void mapFields() {
- boolean byAnnotationsOnly = false;
- boolean inheritColumns = false;
- if (clazz.isAnnotationPresent(IQTable.class)) {
- IQTable tableAnnotation = clazz.getAnnotation(IQTable.class);
- byAnnotationsOnly = tableAnnotation.annotationsOnly();
- inheritColumns = tableAnnotation.inheritColumns();
- }
-
- if (clazz.isAnnotationPresent(IQView.class)) {
- IQView viewAnnotation = clazz.getAnnotation(IQView.class);
- byAnnotationsOnly = viewAnnotation.annotationsOnly();
- inheritColumns = viewAnnotation.inheritColumns();
- }
-
- List<Field> classFields = Utils.newArrayList();
- classFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
- if (inheritColumns) {
- Class<?> superClass = clazz.getSuperclass();
- classFields.addAll(Arrays.asList(superClass.getDeclaredFields()));
-
- if (superClass.isAnnotationPresent(IQView.class)) {
- IQView superView = superClass.getAnnotation(IQView.class);
- if (superView.inheritColumns()) {
- // inherit columns from super.super.class
- Class<?> superSuperClass = superClass.getSuperclass();
- classFields.addAll(Arrays.asList(superSuperClass.getDeclaredFields()));
- }
- } else if (superClass.isAnnotationPresent(IQTable.class)) {
- IQTable superTable = superClass.getAnnotation(IQTable.class);
- if (superTable.inheritColumns()) {
- // inherit columns from super.super.class
- Class<?> superSuperClass = superClass.getSuperclass();
- classFields.addAll(Arrays.asList(superSuperClass.getDeclaredFields()));
- }
- }
- }
-
- Set<FieldDefinition> uniqueFields = new LinkedHashSet<FieldDefinition>();
- T defaultObject = Db.instance(clazz);
- for (Field f : classFields) {
- // check if we should skip this field
- if (f.isAnnotationPresent(IQIgnore.class)) {
- continue;
- }
-
- // default to field name
- String columnName = f.getName();
- boolean isAutoIncrement = false;
- boolean isPrimaryKey = false;
- int length = 0;
- int scale = 0;
- boolean trim = false;
- boolean nullable = !f.getType().isPrimitive();
- EnumType enumType = null;
- String defaultValue = "";
- String constraint = "";
- // configure Java -> SQL enum mapping
- if (f.getType().isEnum()) {
- enumType = EnumType.DEFAULT_TYPE;
- if (f.getType().isAnnotationPresent(IQEnum.class)) {
- // enum definition is annotated for all instances
- IQEnum iqenum = f.getType().getAnnotation(IQEnum.class);
- enumType = iqenum.value();
- }
- if (f.isAnnotationPresent(IQEnum.class)) {
- // this instance of the enum is annotated
- IQEnum iqenum = f.getAnnotation(IQEnum.class);
- enumType = iqenum.value();
- }
- }
-
- // try using default object
- try {
- f.setAccessible(true);
- Object value = f.get(defaultObject);
- if (value != null) {
- if (value.getClass().isEnum()) {
- // enum default, convert to target type
- Enum<?> anEnum = (Enum<?>) value;
- Object o = Utils.convertEnum(anEnum, enumType);
- defaultValue = ModelUtils.formatDefaultValue(o);
- } else {
- // object default
- defaultValue = ModelUtils.formatDefaultValue(value);
- }
- }
- } catch (IllegalAccessException e) {
- throw new IciqlException(e, "failed to get default object for {0}", columnName);
- }
-
- boolean hasAnnotation = f.isAnnotationPresent(IQColumn.class);
- if (hasAnnotation) {
- IQColumn col = f.getAnnotation(IQColumn.class);
- if (!StringUtils.isNullOrEmpty(col.name())) {
- columnName = col.name();
- }
- isAutoIncrement = col.autoIncrement();
- isPrimaryKey = col.primaryKey();
- length = col.length();
- scale = col.scale();
- trim = col.trim();
- nullable = col.nullable();
-
- // annotation overrides
- if (!StringUtils.isNullOrEmpty(col.defaultValue())) {
- defaultValue = col.defaultValue();
- }
- }
-
- boolean hasConstraint = f.isAnnotationPresent(IQConstraint.class);
- if (hasConstraint) {
- IQConstraint con = f.getAnnotation(IQConstraint.class);
- // annotation overrides
- if (!StringUtils.isNullOrEmpty(con.value())) {
- constraint = con.value();
- }
- }
-
- boolean reflectiveMatch = !byAnnotationsOnly;
- if (reflectiveMatch || hasAnnotation || hasConstraint) {
- FieldDefinition fieldDef = new FieldDefinition();
- fieldDef.isPrimitive = f.getType().isPrimitive();
- fieldDef.field = f;
- fieldDef.columnName = columnName;
- fieldDef.isAutoIncrement = isAutoIncrement;
- fieldDef.isPrimaryKey = isPrimaryKey;
- fieldDef.length = length;
- fieldDef.scale = scale;
- fieldDef.trim = trim;
- fieldDef.nullable = nullable;
- fieldDef.defaultValue = defaultValue;
- fieldDef.enumType = enumType;
- fieldDef.dataType = ModelUtils.getDataType(fieldDef);
- fieldDef.constraint = constraint;
- uniqueFields.add(fieldDef);
- }
- }
- fields.addAll(uniqueFields);
-
- List<String> primaryKey = Utils.newArrayList();
- int primitiveBoolean = 0;
- for (FieldDefinition fieldDef : fields) {
- if (fieldDef.isPrimaryKey) {
- primaryKey.add(fieldDef.columnName);
- }
- if (fieldDef.isPrimitive && fieldDef.field.getType().equals(boolean.class)) {
- primitiveBoolean++;
- }
- }
- if (primitiveBoolean > 1) {
- multiplePrimitiveBools = true;
- IciqlLogger
- .warn("Model {0} has multiple primitive booleans! Possible where,set,join clause problem!");
- }
- if (primaryKey.size() > 0) {
- setPrimaryKey(primaryKey);
- }
- }
-
- void checkMultipleBooleans() {
- if (multiplePrimitiveBools) {
- throw new IciqlException(
- "Can not explicitly reference a primitive boolean if there are multiple boolean fields in your model class!");
- }
- }
-
- void checkMultipleEnums(Object o) {
- if (o == null) {
- return;
- }
- Class<?> clazz = o.getClass();
- if (!clazz.isEnum()) {
- return;
- }
-
- int fieldCount = 0;
- for (FieldDefinition fieldDef : fields) {
- Class<?> targetType = fieldDef.field.getType();
- if (clazz.equals(targetType)) {
- fieldCount++;
- }
- }
-
- if (fieldCount > 1) {
- throw new IciqlException(
- "Can not explicitly reference {0} because there are {1} {0} fields in your model class!",
- clazz.getSimpleName(), fieldCount);
- }
- }
-
- /**
- * Optionally truncates strings to the maximum length and converts
- * java.lang.Enum types to Strings or Integers.
- */
- Object getValue(Object obj, FieldDefinition field) {
- Object value = field.getValue(obj);
- if (value == null) {
- return value;
- }
- if (field.enumType != null) {
- // convert enumeration to INT or STRING
- Enum<?> iqenum = (Enum<?>) value;
- switch (field.enumType) {
- case NAME:
- if (field.trim && field.length > 0) {
- if (iqenum.name().length() > field.length) {
- return iqenum.name().substring(0, field.length);
- }
- }
- return iqenum.name();
- case ORDINAL:
- return iqenum.ordinal();
- case ENUMID:
- if (!EnumId.class.isAssignableFrom(value.getClass())) {
- throw new IciqlException(field.field.getName() + " does not implement EnumId!");
- }
- EnumId enumid = (EnumId) value;
- return enumid.enumId();
- }
- }
-
- if (field.trim && field.length > 0) {
- if (value instanceof String) {
- // clip strings
- String s = (String) value;
- if (s.length() > field.length) {
- return s.substring(0, field.length);
- }
- return s;
- }
- return value;
- }
-
- // return the value unchanged
- return value;
- }
-
- PreparedStatement createInsertStatement(Db db, Object obj, boolean returnKey) {
- SQLStatement stat = new SQLStatement(db);
- StatementBuilder buff = new StatementBuilder("INSERT INTO ");
- buff.append(db.getDialect().prepareTableName(schemaName, tableName)).append('(');
- for (FieldDefinition field : fields) {
- if (skipInsertField(field, obj)) {
- continue;
- }
- buff.appendExceptFirst(", ");
- buff.append(db.getDialect().prepareColumnName(field.columnName));
- }
- buff.append(") VALUES(");
- buff.resetCount();
- for (FieldDefinition field : fields) {
- if (skipInsertField(field, obj)) {
- continue;
- }
- buff.appendExceptFirst(", ");
- buff.append('?');
- Object value = getValue(obj, field);
- if (value == null && !field.nullable) {
- // try to interpret and instantiate a default value
- value = ModelUtils.getDefaultValue(field, db.getDialect().getDateTimeClass());
- }
- stat.addParameter(value);
- }
- buff.append(')');
- stat.setSQL(buff.toString());
- IciqlLogger.insert(stat.getSQL());
- return stat.prepare(returnKey);
- }
-
- long insert(Db db, Object obj, boolean returnKey) {
- if (!StringUtils.isNullOrEmpty(viewTableName)) {
- throw new IciqlException("Iciql does not support inserting rows into views!");
- }
- SQLStatement stat = new SQLStatement(db);
- StatementBuilder buff = new StatementBuilder("INSERT INTO ");
- buff.append(db.getDialect().prepareTableName(schemaName, tableName)).append('(');
- for (FieldDefinition field : fields) {
- if (skipInsertField(field, obj)) {
- continue;
- }
- buff.appendExceptFirst(", ");
- buff.append(db.getDialect().prepareColumnName(field.columnName));
- }
- buff.append(") VALUES(");
- buff.resetCount();
- for (FieldDefinition field : fields) {
- if (skipInsertField(field, obj)) {
- continue;
- }
- buff.appendExceptFirst(", ");
- buff.append('?');
- Object value = getValue(obj, field);
- if (value == null && !field.nullable) {
- // try to interpret and instantiate a default value
- value = ModelUtils.getDefaultValue(field, db.getDialect().getDateTimeClass());
- }
- stat.addParameter(value);
- }
- buff.append(')');
- stat.setSQL(buff.toString());
- IciqlLogger.insert(stat.getSQL());
- if (returnKey) {
- return stat.executeInsert();
- }
- return stat.executeUpdate();
- }
-
- private boolean skipInsertField(FieldDefinition field, Object obj) {
- if (field.isAutoIncrement) {
- Object value = getValue(obj, field);
- if (field.isPrimitive) {
- // skip uninitialized primitive autoincrement values
- if (value.toString().equals("0")) {
- return true;
- }
- } else if (value == null) {
- // skip null object autoincrement values
- return true;
- }
- } else {
- // conditionally skip insert of null
- Object value = getValue(obj, field);
- if (value == null) {
- if (field.nullable) {
- // skip null assignment, field is nullable
- return true;
- } else if (StringUtils.isNullOrEmpty(field.defaultValue)) {
- IciqlLogger.warn("no default value, skipping null insert assignment for {0}.{1}",
- tableName, field.columnName);
- return true;
- }
- }
- }
- return false;
- }
-
- int merge(Db db, Object obj) {
- if (primaryKeyColumnNames == null || primaryKeyColumnNames.size() == 0) {
- throw new IllegalStateException("No primary key columns defined for table " + obj.getClass()
- + " - no update possible");
- }
- SQLStatement stat = new SQLStatement(db);
- db.getDialect().prepareMerge(stat, schemaName, tableName, this, obj);
- IciqlLogger.merge(stat.getSQL());
- return stat.executeUpdate();
- }
-
- int update(Db db, Object obj) {
- if (!StringUtils.isNullOrEmpty(viewTableName)) {
- throw new IciqlException("Iciql does not support updating rows in views!");
- }
- if (primaryKeyColumnNames == null || primaryKeyColumnNames.size() == 0) {
- throw new IllegalStateException("No primary key columns defined for table " + obj.getClass()
- + " - no update possible");
- }
- SQLStatement stat = new SQLStatement(db);
- StatementBuilder buff = new StatementBuilder("UPDATE ");
- buff.append(db.getDialect().prepareTableName(schemaName, tableName)).append(" SET ");
- buff.resetCount();
-
- for (FieldDefinition field : fields) {
- if (!field.isPrimaryKey) {
- Object value = getValue(obj, field);
- if (value == null && !field.nullable) {
- // try to interpret and instantiate a default value
- value = ModelUtils.getDefaultValue(field, db.getDialect().getDateTimeClass());
- }
- buff.appendExceptFirst(", ");
- buff.append(db.getDialect().prepareColumnName(field.columnName));
- buff.append(" = ?");
- stat.addParameter(value);
- }
- }
- Object alias = Utils.newObject(obj.getClass());
- Query<Object> query = Query.from(db, alias);
- boolean firstCondition = true;
- for (FieldDefinition field : fields) {
- if (field.isPrimaryKey) {
- Object fieldAlias = field.getValue(alias);
- Object value = field.getValue(obj);
- if (field.isPrimitive) {
- fieldAlias = query.getPrimitiveAliasByValue(fieldAlias);
- }
- if (!firstCondition) {
- query.addConditionToken(ConditionAndOr.AND);
- }
- firstCondition = false;
- query.addConditionToken(new Condition<Object>(fieldAlias, value, CompareType.EQUAL));
- }
- }
- stat.setSQL(buff.toString());
- query.appendWhere(stat);
- IciqlLogger.update(stat.getSQL());
- return stat.executeUpdate();
- }
-
- int delete(Db db, Object obj) {
- if (!StringUtils.isNullOrEmpty(viewTableName)) {
- throw new IciqlException("Iciql does not support deleting rows from views!");
- }
- if (primaryKeyColumnNames == null || primaryKeyColumnNames.size() == 0) {
- throw new IllegalStateException("No primary key columns defined for table " + obj.getClass()
- + " - no update possible");
- }
- SQLStatement stat = new SQLStatement(db);
- StatementBuilder buff = new StatementBuilder("DELETE FROM ");
- buff.append(db.getDialect().prepareTableName(schemaName, tableName));
- buff.resetCount();
- Object alias = Utils.newObject(obj.getClass());
- Query<Object> query = Query.from(db, alias);
- boolean firstCondition = true;
- for (FieldDefinition field : fields) {
- if (field.isPrimaryKey) {
- Object fieldAlias = field.getValue(alias);
- Object value = field.getValue(obj);
- if (field.isPrimitive) {
- fieldAlias = query.getPrimitiveAliasByValue(fieldAlias);
- }
- if (!firstCondition) {
- query.addConditionToken(ConditionAndOr.AND);
- }
- firstCondition = false;
- query.addConditionToken(new Condition<Object>(fieldAlias, value, CompareType.EQUAL));
- }
- }
- stat.setSQL(buff.toString());
- query.appendWhere(stat);
- IciqlLogger.delete(stat.getSQL());
- return stat.executeUpdate();
- }
-
- TableDefinition<T> createIfRequired(Db db) {
- // globally enable/disable check of create if required
- if (db.getSkipCreate()) {
- return this;
- }
- if (!createIfRequired) {
- // skip table and index creation
- // but still check for upgrades
- db.upgradeTable(this);
- return this;
- }
- if (db.hasCreated(clazz)) {
- return this;
- }
- SQLStatement stat = new SQLStatement(db);
- if (StringUtils.isNullOrEmpty(viewTableName)) {
- db.getDialect().prepareCreateTable(stat, this);
- } else {
- db.getDialect().prepareCreateView(stat, this);
- }
- IciqlLogger.create(stat.getSQL());
- try {
- stat.executeUpdate();
- } catch (IciqlException e) {
- if (e.getIciqlCode() != IciqlException.CODE_OBJECT_ALREADY_EXISTS) {
- throw e;
- }
- }
-
- // create indexes
- for (IndexDefinition index : indexes) {
- stat = new SQLStatement(db);
- db.getDialect().prepareCreateIndex(stat, schemaName, tableName, index);
- IciqlLogger.create(stat.getSQL());
- try {
- stat.executeUpdate();
- } catch (IciqlException e) {
- if (e.getIciqlCode() != IciqlException.CODE_OBJECT_ALREADY_EXISTS
- && e.getIciqlCode() != IciqlException.CODE_DUPLICATE_KEY) {
- throw e;
- }
- }
- }
-
- // create unique constraints
- for (ConstraintUniqueDefinition constraint : constraintsUnique) {
- stat = new SQLStatement(db);
- db.getDialect().prepareCreateConstraintUnique(stat, schemaName, tableName, constraint);
- IciqlLogger.create(stat.getSQL());
- try {
- stat.executeUpdate();
- } catch (IciqlException e) {
- if (e.getIciqlCode() != IciqlException.CODE_OBJECT_ALREADY_EXISTS
- && e.getIciqlCode() != IciqlException.CODE_DUPLICATE_KEY) {
- throw e;
- }
- }
- }
-
- // create foreign keys constraints
- for (ConstraintForeignKeyDefinition constraint : constraintsForeignKey) {
- stat = new SQLStatement(db);
- db.getDialect().prepareCreateConstraintForeignKey(stat, schemaName, tableName, constraint);
- IciqlLogger.create(stat.getSQL());
- try {
- stat.executeUpdate();
- } catch (IciqlException e) {
- if (e.getIciqlCode() != IciqlException.CODE_OBJECT_ALREADY_EXISTS
- && e.getIciqlCode() != IciqlException.CODE_DUPLICATE_KEY) {
- throw e;
- }
- }
- }
-
- // tables are created using IF NOT EXISTS
- // but we may still need to upgrade
- db.upgradeTable(this);
- return this;
- }
-
- void mapObject(Object obj) {
- fieldMap.clear();
- initObject(obj, fieldMap);
-
- if (clazz.isAnnotationPresent(IQSchema.class)) {
- IQSchema schemaAnnotation = clazz.getAnnotation(IQSchema.class);
- // setup schema name mapping, if properly annotated
- if (!StringUtils.isNullOrEmpty(schemaAnnotation.value())) {
- schemaName = schemaAnnotation.value();
- }
- }
-
- if (clazz.isAnnotationPresent(IQTable.class)) {
- IQTable tableAnnotation = clazz.getAnnotation(IQTable.class);
-
- // setup table name mapping, if properly annotated
- if (!StringUtils.isNullOrEmpty(tableAnnotation.name())) {
- tableName = tableAnnotation.name();
- }
-
- // allow control over createTableIfRequired()
- createIfRequired = tableAnnotation.create();
-
- // model version
- if (clazz.isAnnotationPresent(IQVersion.class)) {
- IQVersion versionAnnotation = clazz.getAnnotation(IQVersion.class);
- if (versionAnnotation.value() > 0) {
- tableVersion = versionAnnotation.value();
- }
- }
-
- // setup the primary index, if properly annotated
- if (tableAnnotation.primaryKey().length > 0) {
- List<String> primaryKey = Utils.newArrayList();
- primaryKey.addAll(Arrays.asList(tableAnnotation.primaryKey()));
- setPrimaryKey(primaryKey);
- }
- }
-
- if (clazz.isAnnotationPresent(IQView.class)) {
- IQView viewAnnotation = clazz.getAnnotation(IQView.class);
-
- // setup view name mapping, if properly annotated
- // set this as the table name so it fits in seemlessly with iciql
- if (!StringUtils.isNullOrEmpty(viewAnnotation.name())) {
- tableName = viewAnnotation.name();
- } else {
- tableName = clazz.getSimpleName();
- }
-
- // setup source table name mapping, if properly annotated
- if (!StringUtils.isNullOrEmpty(viewAnnotation.tableName())) {
- viewTableName = viewAnnotation.tableName();
- } else {
- // check for IQTable annotation on super class
- Class<?> superClass = clazz.getSuperclass();
- if (superClass.isAnnotationPresent(IQTable.class)) {
- IQTable table = superClass.getAnnotation(IQTable.class);
- if (StringUtils.isNullOrEmpty(table.name())) {
- // super.SimpleClassName
- viewTableName = superClass.getSimpleName();
- } else {
- // super.IQTable.name()
- viewTableName = table.name();
- }
- } else if (superClass.isAnnotationPresent(IQView.class)) {
- // super class is a view
- IQView parentView = superClass.getAnnotation(IQView.class);
- if (StringUtils.isNullOrEmpty(parentView.tableName())) {
- // parent view does not define a tableName, must be inherited
- Class<?> superParent = superClass.getSuperclass();
- if (superParent != null && superParent.isAnnotationPresent(IQTable.class)) {
- IQTable superParentTable = superParent.getAnnotation(IQTable.class);
- if (StringUtils.isNullOrEmpty(superParentTable.name())) {
- // super.super.SimpleClassName
- viewTableName = superParent.getSimpleName();
- } else {
- // super.super.IQTable.name()
- viewTableName = superParentTable.name();
- }
- }
- } else {
- // super.IQView.tableName()
- viewTableName = parentView.tableName();
- }
- }
-
- if (StringUtils.isNullOrEmpty(viewTableName)) {
- // still missing view table name
- throw new IciqlException("View model class \"{0}\" is missing a table name!", tableName);
- }
- }
-
- // allow control over createTableIfRequired()
- createIfRequired = viewAnnotation.create();
- }
-
- if (clazz.isAnnotationPresent(IQIndex.class)) {
- // single table index
- IQIndex index = clazz.getAnnotation(IQIndex.class);
- addIndex(index);
- }
-
- if (clazz.isAnnotationPresent(IQIndexes.class)) {
- // multiple table indexes
- IQIndexes indexes = clazz.getAnnotation(IQIndexes.class);
- for (IQIndex index : indexes.value()) {
- addIndex(index);
- }
- }
-
- if (clazz.isAnnotationPresent(IQContraintUnique.class)) {
- // single table unique constraint
- IQContraintUnique constraint = clazz.getAnnotation(IQContraintUnique.class);
- addConstraintUnique(constraint);
- }
-
- if (clazz.isAnnotationPresent(IQContraintsUnique.class)) {
- // multiple table unique constraints
- IQContraintsUnique constraints = clazz.getAnnotation(IQContraintsUnique.class);
- for (IQContraintUnique constraint : constraints.value()) {
- addConstraintUnique(constraint);
- }
- }
-
- if (clazz.isAnnotationPresent(IQContraintForeignKey.class)) {
- // single table constraint
- IQContraintForeignKey constraint = clazz.getAnnotation(IQContraintForeignKey.class);
- addConstraintForeignKey(constraint);
- }
-
- if (clazz.isAnnotationPresent(IQContraintsForeignKey.class)) {
- // multiple table constraints
- IQContraintsForeignKey constraints = clazz.getAnnotation(IQContraintsForeignKey.class);
- for (IQContraintForeignKey constraint : constraints.value()) {
- addConstraintForeignKey(constraint);
- }
- }
-
- }
-
- private void addConstraintForeignKey(IQContraintForeignKey constraint) {
- List<String> foreignColumns = Arrays.asList(constraint.foreignColumns());
- List<String> referenceColumns = Arrays.asList(constraint.referenceColumns());
- addConstraintForeignKey(constraint.name(), foreignColumns, constraint.referenceName(), referenceColumns, constraint.deleteType(), constraint.updateType(), constraint.deferrabilityType());
- }
-
- private void addConstraintUnique(IQContraintUnique constraint) {
- List<String> uniqueColumns = Arrays.asList(constraint.uniqueColumns());
- addConstraintUnique(constraint.name(), uniqueColumns);
- }
-
- /**
- * Defines a foreign key constraint with the specified parameters.
- *
- * @param name
- * name of the constraint
- * @param foreignColumns
- * list of columns declared as foreign
- * @param referenceName
- * reference table name
- * @param referenceColumns
- * list of columns used in reference table
- * @param deleteType
- * action on delete
- * @param updateType
- * action on update
- * @param deferrabilityType
- * deferrability mode
- */
- private void addConstraintForeignKey(String name,
- List<String> foreignColumns, String referenceName,
- List<String> referenceColumns, ConstraintDeleteType deleteType,
- ConstraintUpdateType updateType, ConstraintDeferrabilityType deferrabilityType) {
- ConstraintForeignKeyDefinition constraint = new ConstraintForeignKeyDefinition();
- if (StringUtils.isNullOrEmpty(name)) {
- constraint.constraintName = tableName + "_fkey_" + constraintsForeignKey.size();
- } else {
- constraint.constraintName = name;
- }
- constraint.foreignColumns = Utils.newArrayList(foreignColumns);
- constraint.referenceColumns = Utils.newArrayList(referenceColumns);
- constraint.referenceTable = referenceName;
- constraint.deleteType = deleteType;
- constraint.updateType = updateType;
- constraint.deferrabilityType = deferrabilityType;
- constraintsForeignKey.add(constraint);
- }
-
- private void addIndex(IQIndex index) {
- List<String> columns = Arrays.asList(index.value());
- addIndex(index.name(), index.type(), columns);
- }
-
- List<IndexDefinition> getIndexes() {
- return indexes;
- }
-
- List<ConstraintUniqueDefinition> getContraintsUnique() {
- return constraintsUnique;
- }
-
- List<ConstraintForeignKeyDefinition> getContraintsForeignKey() {
- return constraintsForeignKey;
- }
-
- private void initObject(Object obj, Map<Object, FieldDefinition> map) {
- for (FieldDefinition def : fields) {
- Object newValue = def.initWithNewObject(obj);
- map.put(newValue, def);
- }
- }
-
- void initSelectObject(SelectTable<T> table, Object obj, Map<Object, SelectColumn<T>> map) {
- for (FieldDefinition def : fields) {
- Object newValue = def.initWithNewObject(obj);
- SelectColumn<T> column = new SelectColumn<T>(table, def);
- map.put(newValue, column);
- }
- }
-
- /**
- * Most queries executed by iciql have named select lists (select alpha,
- * beta where...) but sometimes a wildcard select is executed (select *).
- * When a wildcard query is executed on a table that has more columns than
- * are mapped in your model object, this creates a column mapping issue.
- * JaQu assumed that you can always use the integer index of the
- * reflectively mapped field definition to determine position in the result
- * set.
- *
- * This is not always true.
- *
- * iciql identifies when a select * query is executed and maps column names
- * to a column index from the result set. If the select statement is
- * explicit, then the standard assumed column index is used instead.
- *
- * @param rs
- * @return
- */
- int[] mapColumns(boolean wildcardSelect, ResultSet rs) {
- int[] columns = new int[fields.size()];
- for (int i = 0; i < fields.size(); i++) {
- try {
- FieldDefinition def = fields.get(i);
- int columnIndex;
- if (wildcardSelect) {
- // select *
- // create column index by field name
- columnIndex = rs.findColumn(def.columnName);
- } else {
- // select alpha, beta, gamma, etc
- // explicit select order
- columnIndex = i + 1;
- }
- columns[i] = columnIndex;
- } catch (SQLException s) {
- throw new IciqlException(s);
- }
- }
- return columns;
- }
-
- void readRow(Object item, ResultSet rs, int[] columns) {
- for (int i = 0; i < fields.size(); i++) {
- FieldDefinition def = fields.get(i);
- int index = columns[i];
- Object o = def.read(rs, index);
- def.setValue(item, o);
- }
- }
-
- void appendSelectList(SQLStatement stat) {
- for (int i = 0; i < fields.size(); i++) {
- if (i > 0) {
- stat.appendSQL(", ");
- }
- FieldDefinition def = fields.get(i);
- stat.appendColumn(def.columnName);
- }
- }
-
- <Y, X> void appendSelectList(SQLStatement stat, Query<Y> query, X x) {
- // select t0.col1, t0.col2, t0.col3...
- // select table1.col1, table1.col2, table1.col3...
- String selectDot = "";
- SelectTable<?> sel = query.getSelectTable(x);
- if (sel != null) {
- if (query.isJoin()) {
- selectDot = sel.getAs() + ".";
- } else {
- String sn = sel.getAliasDefinition().schemaName;
- String tn = sel.getAliasDefinition().tableName;
- selectDot = query.getDb().getDialect().prepareTableName(sn, tn) + ".";
- }
- }
-
- for (int i = 0; i < fields.size(); i++) {
- if (i > 0) {
- stat.appendSQL(", ");
- }
- stat.appendSQL(selectDot);
- FieldDefinition def = fields.get(i);
- if (def.isPrimitive) {
- Object obj = def.getValue(x);
- Object alias = query.getPrimitiveAliasByValue(obj);
- query.appendSQL(stat, x, alias);
- } else {
- Object obj = def.getValue(x);
- query.appendSQL(stat, x, obj);
- }
- }
- }
-}
diff --git a/src/com/iciql/TableInspector.java b/src/com/iciql/TableInspector.java deleted file mode 100644 index b717203..0000000 --- a/src/com/iciql/TableInspector.java +++ /dev/null @@ -1,723 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * Copyright 2012 Frédéric Gaillard. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql; - -import static com.iciql.ValidationRemark.consider; -import static com.iciql.ValidationRemark.error; -import static com.iciql.ValidationRemark.warn; -import static com.iciql.util.JdbcUtils.closeSilently; -import static com.iciql.util.StringUtils.isNullOrEmpty; -import static java.text.MessageFormat.format; - -import java.io.Serializable; -import java.lang.reflect.Modifier; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.iciql.Iciql.IQColumn; -import com.iciql.Iciql.IQIndex; -import com.iciql.Iciql.IQIndexes; -import com.iciql.Iciql.IQSchema; -import com.iciql.Iciql.IQTable; -import com.iciql.Iciql.IndexType; -import com.iciql.TableDefinition.ConstraintForeignKeyDefinition; -import com.iciql.TableDefinition.ConstraintUniqueDefinition; -import com.iciql.TableDefinition.FieldDefinition; -import com.iciql.TableDefinition.IndexDefinition; -import com.iciql.util.StatementBuilder; -import com.iciql.util.StringUtils; -import com.iciql.util.Utils; - -/** - * Class to inspect the contents of a particular table including its indexes. - * This class does the bulk of the work in terms of model generation and model - * validation. - */ -public class TableInspector { - - private String schema; - private String table; - private Class<? extends java.util.Date> dateTimeClass; - private List<String> primaryKeys = Utils.newArrayList(); - private Map<String, IndexInspector> indexes; - private Map<String, ColumnInspector> columns; - private final String eol = "\n"; - - TableInspector(String schema, String table, Class<? extends java.util.Date> dateTimeClass) { - this.schema = schema; - this.table = table; - this.dateTimeClass = dateTimeClass; - } - - /** - * Tests to see if this TableInspector represents schema.table. - * <p> - * - * @param schema - * the schema name - * @param table - * the table name - * @return true if the table matches - */ - boolean matches(String schema, String table) { - if (isNullOrEmpty(schema)) { - // table name matching - return this.table.equalsIgnoreCase(table); - } else if (isNullOrEmpty(table)) { - // schema name matching - return this.schema.equalsIgnoreCase(schema); - } else { - // exact table matching - return this.schema.equalsIgnoreCase(schema) && this.table.equalsIgnoreCase(table); - } - } - - /** - * Reads the DatabaseMetaData for the details of this table including - * primary keys and indexes. - * - * @param metaData - * the database meta data - */ - void read(DatabaseMetaData metaData) throws SQLException { - ResultSet rs = null; - - // primary keys - try { - rs = metaData.getPrimaryKeys(null, schema, table); - while (rs.next()) { - String c = rs.getString("COLUMN_NAME"); - primaryKeys.add(c); - } - closeSilently(rs); - - // indexes - rs = metaData.getIndexInfo(null, schema, table, false, true); - indexes = Utils.newHashMap(); - while (rs.next()) { - IndexInspector info = new IndexInspector(rs); - if (info.type.equals(IndexType.UNIQUE)) { - String name = info.name.toLowerCase(); - if (name.startsWith("primary") || name.startsWith("sys_idx_sys_pk") - || name.startsWith("sql") || name.endsWith("_pkey")) { - // skip primary key indexes - continue; - } - } - if (indexes.containsKey(info.name)) { - indexes.get(info.name).addColumn(rs); - } else { - indexes.put(info.name, info); - } - } - closeSilently(rs); - - // columns - rs = metaData.getColumns(null, schema, table, null); - columns = Utils.newHashMap(); - while (rs.next()) { - ColumnInspector col = new ColumnInspector(); - col.name = rs.getString("COLUMN_NAME"); - col.type = rs.getString("TYPE_NAME"); - col.clazz = ModelUtils.getClassForSqlType(col.type, dateTimeClass); - col.size = rs.getInt("COLUMN_SIZE"); - col.nullable = rs.getInt("NULLABLE") == DatabaseMetaData.columnNullable; - try { - Object autoIncrement = rs.getObject("IS_AUTOINCREMENT"); - if (autoIncrement instanceof Boolean) { - col.isAutoIncrement = (Boolean) autoIncrement; - } else if (autoIncrement instanceof String) { - String val = autoIncrement.toString().toLowerCase(); - col.isAutoIncrement = val.equals("true") | val.equals("yes"); - } else if (autoIncrement instanceof Number) { - Number n = (Number) autoIncrement; - col.isAutoIncrement = n.intValue() > 0; - } - } catch (SQLException s) { -// throw s; - } - if (primaryKeys.size() == 1) { - if (col.name.equalsIgnoreCase(primaryKeys.get(0))) { - col.isPrimaryKey = true; - } - } - if (!col.isAutoIncrement) { - col.defaultValue = rs.getString("COLUMN_DEF"); - } - columns.put(col.name.toLowerCase(), col); - } - } finally { - closeSilently(rs); - } - } - - /** - * Generates a model (class definition) from this table. The model includes - * indexes, primary keys, default values, lengths, and nullables. - * information. - * <p> - * The caller may optionally set a destination package name, whether or not - * to include the schema name (setting schema can be a problem when using - * the model between databases), and if to automatically trim strings for - * those that have a maximum length. - * <p> - * - * @param packageName - * @param annotateSchema - * @param trimStrings - * @return a complete model (class definition) for this table as a string - */ - String generateModel(String packageName, boolean annotateSchema, boolean trimStrings) { - - // import statements - Set<String> imports = Utils.newHashSet(); - imports.add(Serializable.class.getCanonicalName()); - imports.add(IQSchema.class.getCanonicalName()); - imports.add(IQTable.class.getCanonicalName()); - imports.add(IQIndexes.class.getCanonicalName()); - imports.add(IQIndex.class.getCanonicalName()); - imports.add(IQColumn.class.getCanonicalName()); - imports.add(IndexType.class.getCanonicalName()); - - // fields - StringBuilder fields = new StringBuilder(); - List<ColumnInspector> sortedColumns = Utils.newArrayList(columns.values()); - Collections.sort(sortedColumns); - for (ColumnInspector col : sortedColumns) { - fields.append(generateColumn(imports, col, trimStrings)); - } - - // build complete class definition - StringBuilder model = new StringBuilder(); - if (!isNullOrEmpty(packageName)) { - // package - model.append("package " + packageName + ";"); - model.append(eol).append(eol); - } - - // imports - List<String> sortedImports = new ArrayList<String>(imports); - Collections.sort(sortedImports); - for (String imp : sortedImports) { - model.append("import ").append(imp).append(';').append(eol); - } - model.append(eol); - - // @IQSchema - if (annotateSchema && !isNullOrEmpty(schema)) { - model.append('@').append(IQSchema.class.getSimpleName()); - model.append('('); - AnnotationBuilder ap = new AnnotationBuilder(); - ap.addParameter(null, schema); - model.append(ap); - model.append(')').append(eol); - } - - // @IQTable - model.append('@').append(IQTable.class.getSimpleName()); - model.append('('); - - // IQTable annotation parameters - AnnotationBuilder ap = new AnnotationBuilder(); - ap.addParameter("name", table); - - if (primaryKeys.size() > 1) { - ap.addParameter("primaryKey", primaryKeys); - } - - // finish @IQTable annotation - model.append(ap); - model.append(')').append(eol); - - // @IQIndexes - // @IQIndex - String indexAnnotations = generateIndexAnnotations(); - if (!StringUtils.isNullOrEmpty(indexAnnotations)) { - model.append(indexAnnotations); - } - - // class declaration - String clazzName = ModelUtils.convertTableToClassName(table); - model.append(format("public class {0} implements Serializable '{'", clazzName)).append(eol); - model.append(eol); - model.append("\tprivate static final long serialVersionUID = 1L;").append(eol); - model.append(eol); - - // field declarations - model.append(fields); - - // default constructor - model.append("\t" + "public ").append(clazzName).append("() {").append(eol); - model.append("\t}").append(eol); - - // end of class body - model.append('}'); - model.trimToSize(); - return model.toString(); - } - - /** - * Generates the specified index annotation. - * - * @param ap - */ - String generateIndexAnnotations() { - if (indexes == null || indexes.size() == 0) { - // no matching indexes - return null; - } - AnnotationBuilder ap = new AnnotationBuilder(); - if (indexes.size() == 1) { - // single index - IndexInspector index = indexes.values().toArray(new IndexInspector[1])[0]; - ap.append(generateIndexAnnotation(index)); - ap.append(eol); - } else { - // multiple indexes - ap.append('@').append(IQIndexes.class.getSimpleName()); - ap.append("({"); - ap.resetCount(); - for (IndexInspector index : indexes.values()) { - ap.appendExceptFirst(", "); - ap.append(generateIndexAnnotation(index)); - } - ap.append("})").append(eol); - } - return ap.toString(); - } - - private String generateIndexAnnotation(IndexInspector index) { - AnnotationBuilder ap = new AnnotationBuilder(); - ap.append('@').append(IQIndex.class.getSimpleName()); - ap.append('('); - ap.resetCount(); - if (!StringUtils.isNullOrEmpty(index.name)) { - ap.addParameter("name", index.name); - } - if (!index.type.equals(IndexType.STANDARD)) { - ap.addEnum("type", index.type); - } - if (ap.getCount() > 0) { - // multiple fields specified - ap.addParameter("value", index.columns); - } else { - // default value - ap.addParameter(null, index.columns); - } - ap.append(')'); - return ap.toString(); - } - - private StatementBuilder generateColumn(Set<String> imports, ColumnInspector col, boolean trimStrings) { - StatementBuilder sb = new StatementBuilder(); - Class<?> clazz = col.clazz; - String column = ModelUtils.convertColumnToFieldName(col.name.toLowerCase()); - sb.append('\t'); - if (clazz == null) { - // unsupported type - clazz = Object.class; - sb.append("// unsupported type " + col.type); - } else { - // Imports - // don't import primitives, java.lang classes, or byte [] - if (clazz.getPackage() == null) { - } else if (clazz.getPackage().getName().equals("java.lang")) { - } else if (clazz.equals(byte[].class)) { - } else { - imports.add(clazz.getCanonicalName()); - } - // @IQColumn - sb.append('@').append(IQColumn.class.getSimpleName()); - - // IQColumn annotation parameters - AnnotationBuilder ap = new AnnotationBuilder(); - - // IQColumn.name - if (!col.name.equalsIgnoreCase(column)) { - ap.addParameter("name", col.name); - } - - // IQColumn.primaryKey - // composite primary keys are annotated on the table - if (col.isPrimaryKey && primaryKeys.size() == 1) { - ap.addParameter("primaryKey=true"); - } - - // IQColumn.length - if ((clazz == String.class) && (col.size > 0) && (col.size < Integer.MAX_VALUE)) { - ap.addParameter("length", col.size); - - // IQColumn.trim - if (trimStrings) { - ap.addParameter("trim=true"); - } - } else { - // IQColumn.AutoIncrement - if (col.isAutoIncrement) { - ap.addParameter("autoIncrement=true"); - } - } - - // IQColumn.nullable - if (!col.nullable) { - ap.addParameter("nullable=false"); - } - - // IQColumn.defaultValue - if (!isNullOrEmpty(col.defaultValue)) { - ap.addParameter("defaultValue=\"" + col.defaultValue + "\""); - } - - // add leading and trailing () - if (ap.length() > 0) { - ap.insert(0, '('); - ap.append(')'); - } - sb.append(ap); - } - sb.append(eol); - - // variable declaration - sb.append("\t" + "public "); - sb.append(clazz.getSimpleName()); - sb.append(' '); - sb.append(column); - sb.append(';'); - sb.append(eol).append(eol); - return sb; - } - - /** - * Validates that a table definition (annotated, interface, or both) matches - * the current state of the table and indexes in the database. Results are - * returned as a list of validation remarks which includes recommendations, - * warnings, and errors about the model. The caller may choose to have - * validate throw an exception on any validation ERROR. - * - * @param def - * the table definition - * @param throwError - * whether or not to throw an exception if an error was found - * @return a list if validation remarks - */ - <T> List<ValidationRemark> validate(TableDefinition<T> def, boolean throwError) { - List<ValidationRemark> remarks = Utils.newArrayList(); - - // model class definition validation - if (!Modifier.isPublic(def.getModelClass().getModifiers())) { - remarks.add(error(table, "SCHEMA", - format("Class {0} MUST BE PUBLIC!", def.getModelClass().getCanonicalName())).throwError( - throwError)); - } - - // Schema Validation - if (!isNullOrEmpty(schema)) { - if (isNullOrEmpty(def.schemaName)) { - remarks.add(consider(table, "SCHEMA", - format("@{0}(\"{1}\")", IQSchema.class.getSimpleName(), schema))); - } else if (!schema.equalsIgnoreCase(def.schemaName)) { - remarks.add(error( - table, - "SCHEMA", - format("@{0}(\"{1}\") != {2}", IQSchema.class.getSimpleName(), def.schemaName, schema)) - .throwError(throwError)); - } - } - - // index validation - for (IndexInspector index : indexes.values()) { - validate(remarks, def, index, throwError); - } - - // field column validation - for (FieldDefinition fieldDef : def.getFields()) { - validate(remarks, fieldDef, throwError); - } - return remarks; - } - - /** - * Validates an inspected index from the database against the - * IndexDefinition within the TableDefinition. - */ - private <T> void validate(List<ValidationRemark> remarks, TableDefinition<T> def, IndexInspector index, - boolean throwError) { - List<IndexDefinition> defIndexes = def.getIndexes(); - if (defIndexes.size() > indexes.size()) { - remarks.add(warn(table, IndexType.STANDARD.name(), "More model indexes than database indexes")); - } else if (defIndexes.size() < indexes.size()) { - remarks.add(warn(table, IndexType.STANDARD.name(), "Model class is missing indexes")); - } - // TODO complete index validation. - // need to actually compare index types and columns within each index. - - // TODO add constraints validation - List<ConstraintUniqueDefinition> defContraintsU = def.getContraintsUnique(); - List<ConstraintForeignKeyDefinition> defContraintsFK = def.getContraintsForeignKey(); - } - - /** - * Validates a column against the model's field definition. Checks for - * existence, supported type, type mapping, default value, defined lengths, - * primary key, autoincrement. - */ - private void validate(List<ValidationRemark> remarks, FieldDefinition fieldDef, boolean throwError) { - // unknown field - if (!columns.containsKey(fieldDef.columnName.toLowerCase())) { - // unknown column mapping - remarks.add(error(table, fieldDef, "Does not exist in database!").throwError(throwError)); - return; - } - ColumnInspector col = columns.get(fieldDef.columnName.toLowerCase()); - Class<?> fieldClass = fieldDef.field.getType(); - Class<?> jdbcClass = ModelUtils.getClassForSqlType(col.type, dateTimeClass); - - // supported type check - // iciql maps to VARCHAR for unsupported types. - if (fieldDef.dataType.equals("VARCHAR") && (fieldClass != String.class)) { - remarks.add(error(table, fieldDef, - "iciql does not currently implement support for " + fieldClass.getName()).throwError( - throwError)); - } - // number types - if (!fieldClass.equals(jdbcClass)) { - if (Number.class.isAssignableFrom(fieldClass)) { - remarks.add(warn( - table, - col, - format("Precision mismatch: ModelObject={0}, ColumnObject={1}", - fieldClass.getSimpleName(), jdbcClass.getSimpleName()))); - } else { - if (!Date.class.isAssignableFrom(jdbcClass)) { - remarks.add(warn( - table, - col, - format("Object Mismatch: ModelObject={0}, ColumnObject={1}", - fieldClass.getSimpleName(), jdbcClass.getSimpleName()))); - } - } - } - - // string types - if (fieldClass == String.class) { - if ((fieldDef.length != col.size) && (col.size < Integer.MAX_VALUE)) { - remarks.add(warn( - table, - col, - format("{0}.length={1}, ColumnMaxLength={2}", IQColumn.class.getSimpleName(), - fieldDef.length, col.size))); - } - if (fieldDef.length > 0 && !fieldDef.trim) { - remarks.add(consider(table, col, format("{0}.trim=true will prevent IciqlExceptions on" - + " INSERT or UPDATE, but will clip data!", IQColumn.class.getSimpleName()))); - } - } - - // numeric autoIncrement - if (fieldDef.isAutoIncrement != col.isAutoIncrement) { - remarks.add(warn( - table, - col, - format("{0}.autoIncrement={1}" + " while Column autoIncrement={2}", - IQColumn.class.getSimpleName(), fieldDef.isAutoIncrement, col.isAutoIncrement))); - } - // default value - if (!col.isAutoIncrement && !col.isPrimaryKey) { - String defaultValue = null; - if (fieldDef.defaultValue != null && fieldDef.defaultValue instanceof String) { - defaultValue = fieldDef.defaultValue.toString(); - } - // check Model.defaultValue format - if (!ModelUtils.isProperlyFormattedDefaultValue(defaultValue)) { - remarks.add(error( - table, - col, - format("{0}.defaultValue=\"{1}\"" + " is improperly formatted!", - IQColumn.class.getSimpleName(), defaultValue)).throwError(throwError)); - // next field - return; - } - // compare Model.defaultValue to Column.defaultValue - if (isNullOrEmpty(defaultValue) && !isNullOrEmpty(col.defaultValue)) { - // Model.defaultValue is NULL, Column.defaultValue is NOT NULL - remarks.add(warn( - table, - col, - format("{0}.defaultValue=\"\"" + " while column default=\"{1}\"", - IQColumn.class.getSimpleName(), col.defaultValue))); - } else if (!isNullOrEmpty(defaultValue) && isNullOrEmpty(col.defaultValue)) { - // Column.defaultValue is NULL, Model.defaultValue is NOT NULL - remarks.add(warn( - table, - col, - format("{0}.defaultValue=\"{1}\"" + " while column default=\"\"", - IQColumn.class.getSimpleName(), defaultValue))); - } else if (!isNullOrEmpty(defaultValue) && !isNullOrEmpty(col.defaultValue)) { - if (!defaultValue.equals(col.defaultValue)) { - // Model.defaultValue != Column.defaultValue - remarks.add(warn( - table, - col, - format("{0}.defaultValue=\"{1}\"" + " while column default=\"{2}\"", - IQColumn.class.getSimpleName(), defaultValue, col.defaultValue))); - } - } - - // sanity check Model.defaultValue literal value - if (!ModelUtils.isValidDefaultValue(fieldDef.field.getType(), defaultValue)) { - remarks.add(error( - table, - col, - format("{0}.defaultValue=\"{1}\" is invalid!", IQColumn.class.getSimpleName(), - defaultValue))); - } - } - } - - /** - * Represents an index as it exists in the database. - */ - private static class IndexInspector { - - String name; - IndexType type; - private List<String> columns = new ArrayList<String>(); - - public IndexInspector(ResultSet rs) throws SQLException { - name = rs.getString("INDEX_NAME"); - - // determine index type - boolean hash = rs.getInt("TYPE") == DatabaseMetaData.tableIndexHashed; - boolean unique = !rs.getBoolean("NON_UNIQUE"); - - if (!hash && !unique) { - type = IndexType.STANDARD; - } else if (hash && unique) { - type = IndexType.UNIQUE_HASH; - } else if (unique) { - type = IndexType.UNIQUE; - } else if (hash) { - type = IndexType.HASH; - } - columns.add(rs.getString("COLUMN_NAME")); - } - - public void addColumn(ResultSet rs) throws SQLException { - columns.add(rs.getString("COLUMN_NAME")); - } - } - - /** - * Represents a column as it exists in the database. - */ - static class ColumnInspector implements Comparable<ColumnInspector> { - String name; - String type; - int size; - boolean nullable; - Class<?> clazz; - boolean isPrimaryKey; - boolean isAutoIncrement; - String defaultValue; - - public int compareTo(ColumnInspector o) { - if (isPrimaryKey && o.isPrimaryKey) { - // both primary sort by name - return name.compareTo(o.name); - } else if (isPrimaryKey && !o.isPrimaryKey) { - // primary first - return -1; - } else if (!isPrimaryKey && o.isPrimaryKey) { - // primary first - return 1; - } else { - // neither primary, sort by name - return name.compareTo(o.name); - } - } - } - - /** - * Convenience class based on StatementBuilder for creating the annotation - * parameter list. - */ - private static class AnnotationBuilder extends StatementBuilder { - - AnnotationBuilder() { - super(); - } - - void addParameter(String parameter) { - - appendExceptFirst(", "); - append(parameter); - } - - <T> void addParameter(String parameter, T value) { - appendExceptFirst(", "); - if (!StringUtils.isNullOrEmpty(parameter)) { - append(parameter); - append('='); - } - if (value instanceof List) { - append("{ "); - List<?> list = (List<?>) value; - StatementBuilder flat = new StatementBuilder(); - for (Object o : list) { - flat.appendExceptFirst(", "); - if (o instanceof String) { - flat.append('\"'); - } - // TODO escape string - flat.append(o.toString().trim()); - if (o instanceof String) { - flat.append('\"'); - } - } - append(flat); - append(" }"); - } else { - if (value instanceof String) { - append('\"'); - } - // TODO escape - append(value.toString().trim()); - if (value instanceof String) { - append('\"'); - } - } - } - - void addEnum(String parameter, Enum<?> value) { - appendExceptFirst(", "); - if (!StringUtils.isNullOrEmpty(parameter)) { - append(parameter); - append('='); - } - append(value.getClass().getSimpleName() + "." + value.name()); - } - } -}
\ No newline at end of file diff --git a/src/com/iciql/TestCondition.java b/src/com/iciql/TestCondition.java deleted file mode 100644 index 010f5a1..0000000 --- a/src/com/iciql/TestCondition.java +++ /dev/null @@ -1,115 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-import com.iciql.util.Utils;
-
-/**
- * This class represents an incomplete condition.
- *
- * @param <A>
- * the incomplete condition data type
- */
-
-public class TestCondition<A> {
-
- private A x;
-
- public TestCondition(A x) {
- this.x = x;
- }
-
- public Boolean is(A y) {
- Boolean o = Utils.newObject(Boolean.class);
- return Db.registerToken(o, new Function("=", x, y) {
- public <T> void appendSQL(SQLStatement stat, Query<T> query) {
- stat.appendSQL("(");
- query.appendSQL(stat, null, x[0]);
- stat.appendSQL(" = ");
- query.appendSQL(stat, x[0], x[1]);
- stat.appendSQL(")");
- }
- });
- }
-
- public Boolean exceeds(A y) {
- Boolean o = Utils.newObject(Boolean.class);
- return Db.registerToken(o, new Function(">", x, y) {
- public <T> void appendSQL(SQLStatement stat, Query<T> query) {
- stat.appendSQL("(");
- query.appendSQL(stat, null, x[0]);
- stat.appendSQL(" > ");
- query.appendSQL(stat, x[0], x[1]);
- stat.appendSQL(")");
- }
- });
- }
-
- public Boolean atLeast(A y) {
- Boolean o = Utils.newObject(Boolean.class);
- return Db.registerToken(o, new Function(">=", x, y) {
- public <T> void appendSQL(SQLStatement stat, Query<T> query) {
- stat.appendSQL("(");
- query.appendSQL(stat, null, x[0]);
- stat.appendSQL(" >= ");
- query.appendSQL(stat, x[0], x[1]);
- stat.appendSQL(")");
- }
- });
- }
-
- public Boolean lessThan(A y) {
- Boolean o = Utils.newObject(Boolean.class);
- return Db.registerToken(o, new Function("<", x, y) {
- public <T> void appendSQL(SQLStatement stat, Query<T> query) {
- stat.appendSQL("(");
- query.appendSQL(stat, null, x[0]);
- stat.appendSQL(" < ");
- query.appendSQL(stat, x[0], x[1]);
- stat.appendSQL(")");
- }
- });
- }
-
- public Boolean atMost(A y) {
- Boolean o = Utils.newObject(Boolean.class);
- return Db.registerToken(o, new Function("<=", x, y) {
- public <T> void appendSQL(SQLStatement stat, Query<T> query) {
- stat.appendSQL("(");
- query.appendSQL(stat, null, x[0]);
- stat.appendSQL(" <= ");
- query.appendSQL(stat, x[0], x[1]);
- stat.appendSQL(")");
- }
- });
- }
-
- public Boolean like(A pattern) {
- Boolean o = Utils.newObject(Boolean.class);
- return Db.registerToken(o, new Function("LIKE", x, pattern) {
- public <T> void appendSQL(SQLStatement stat, Query<T> query) {
- stat.appendSQL("(");
- query.appendSQL(stat, null, x[0]);
- stat.appendSQL(" LIKE ");
- query.appendSQL(stat, x[0], x[1]);
- stat.appendSQL(")");
- }
- });
- }
-
-}
diff --git a/src/com/iciql/Token.java b/src/com/iciql/Token.java deleted file mode 100644 index cc2203c..0000000 --- a/src/com/iciql/Token.java +++ /dev/null @@ -1,35 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-/**
- * Classes implementing this interface can be used as a token in a statement.
- */
-public interface Token {
- /**
- * Append the SQL to the given statement using the given query.
- *
- * @param stat
- * the statement to append the SQL to
- * @param query
- * the query to use
- */
-
- <T> void appendSQL(SQLStatement stat, Query<T> query);
-
-}
diff --git a/src/com/iciql/UpdateColumn.java b/src/com/iciql/UpdateColumn.java deleted file mode 100644 index 1eaf14c..0000000 --- a/src/com/iciql/UpdateColumn.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql; - -/** - * Classes implementing this interface can be used as a declaration in an update - * statement. - */ -public interface UpdateColumn { - - /** - * Append the SQL to the given statement using the given query. - * - * @param stat - * the statement to append the SQL to - */ - - void appendSQL(SQLStatement stat); - -} diff --git a/src/com/iciql/UpdateColumnIncrement.java b/src/com/iciql/UpdateColumnIncrement.java deleted file mode 100644 index 143ce48..0000000 --- a/src/com/iciql/UpdateColumnIncrement.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql; - -/** - * This class represents "SET column = (column + x)" in an UPDATE statement. - * - * @param <T> - * the query type - * @param <A> - * the new value data type - */ - -public class UpdateColumnIncrement<T, A> implements UpdateColumn { - - private Query<T> query; - private A x; - private A y; - - UpdateColumnIncrement(Query<T> query, A x) { - this.query = query; - this.x = x; - } - - public Query<T> by(A y) { - query.addUpdateColumnDeclaration(this); - this.y = y; - return query; - } - - public void appendSQL(SQLStatement stat) { - query.appendSQL(stat, null, x); - stat.appendSQL("=("); - query.appendSQL(stat, null, x); - stat.appendSQL("+"); - query.appendSQL(stat, x, y); - stat.appendSQL(")"); - } - -} diff --git a/src/com/iciql/UpdateColumnSet.java b/src/com/iciql/UpdateColumnSet.java deleted file mode 100644 index a961480..0000000 --- a/src/com/iciql/UpdateColumnSet.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql; - -/** - * This class represents "SET column = value" in an UPDATE statement. - * - * @param <T> - * the query type - * @param <A> - * the new value data type - */ - -public class UpdateColumnSet<T, A> implements UpdateColumn { - - private Query<T> query; - private A x; - private A y; - private boolean isParameter; - - UpdateColumnSet(Query<T> query, A x) { - this.query = query; - this.x = x; - } - - public Query<T> to(A y) { - query.addUpdateColumnDeclaration(this); - this.y = y; - return query; - } - - public Query<T> toParameter() { - query.addUpdateColumnDeclaration(this); - isParameter = true; - return query; - } - - public void appendSQL(SQLStatement stat) { - query.appendSQL(stat, null, x); - stat.appendSQL(" = "); - if (isParameter) { - query.appendSQL(stat, x, RuntimeParameter.PARAMETER); - } else { - query.appendSQL(stat, x, y); - } - } - -} diff --git a/src/com/iciql/ValidationRemark.java b/src/com/iciql/ValidationRemark.java deleted file mode 100644 index 33320ab..0000000 --- a/src/com/iciql/ValidationRemark.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql; - -import com.iciql.TableDefinition.FieldDefinition; -import com.iciql.TableInspector.ColumnInspector; -import com.iciql.util.StringUtils; - -/** - * A validation remark is a result of running a model validation. Each remark - * has a level, associated component (schema, table, column, index), and a - * message. - */ -public class ValidationRemark { - - /** - * The validation message level. - */ - public static enum Level { - CONSIDER, WARN, ERROR; - } - - public final Level level; - public final String table; - public final String fieldType; - public final String fieldName; - public final String message; - - private ValidationRemark(Level level, String table, String type, String message) { - this.level = level; - this.table = table; - this.fieldType = type; - this.fieldName = ""; - this.message = message; - } - - private ValidationRemark(Level level, String table, FieldDefinition field, String message) { - this.level = level; - this.table = table; - this.fieldType = field.dataType; - this.fieldName = field.columnName; - this.message = message; - } - - private ValidationRemark(Level level, String table, ColumnInspector col, String message) { - this.level = level; - this.table = table; - this.fieldType = col.type; - this.fieldName = col.name; - this.message = message; - } - - public static ValidationRemark consider(String table, String type, String message) { - return new ValidationRemark(Level.CONSIDER, table, type, message); - } - - public static ValidationRemark consider(String table, ColumnInspector col, String message) { - return new ValidationRemark(Level.CONSIDER, table, col, message); - } - - public static ValidationRemark warn(String table, ColumnInspector col, String message) { - return new ValidationRemark(Level.WARN, table, col, message); - } - - public static ValidationRemark warn(String table, String type, String message) { - return new ValidationRemark(Level.WARN, table, type, message); - } - - public static ValidationRemark error(String table, ColumnInspector col, String message) { - return new ValidationRemark(Level.ERROR, table, col, message); - } - - public static ValidationRemark error(String table, String type, String message) { - return new ValidationRemark(Level.ERROR, table, type, message); - } - - public static ValidationRemark error(String table, FieldDefinition field, String message) { - return new ValidationRemark(Level.ERROR, table, field, message); - } - - public ValidationRemark throwError(boolean throwOnError) { - if (throwOnError && isError()) { - throw new IciqlException(toString()); - } - return this; - } - - public boolean isError() { - return level.equals(Level.ERROR); - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(StringUtils.pad(level.name(), 9, " ", true)); - sb.append(StringUtils.pad(table, 25, " ", true)); - sb.append(StringUtils.pad(fieldName, 20, " ", true)); - sb.append(' '); - sb.append(message); - return sb.toString(); - } - - public String toCSVString() { - StringBuilder sb = new StringBuilder(); - sb.append(level.name()).append(','); - sb.append(table).append(','); - sb.append(fieldType).append(','); - sb.append(fieldName).append(','); - sb.append(message); - return sb.toString(); - } - -} diff --git a/src/com/iciql/bytecode/And.java b/src/com/iciql/bytecode/And.java deleted file mode 100644 index 808a9c1..0000000 --- a/src/com/iciql/bytecode/And.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.bytecode; - -import com.iciql.Query; -import com.iciql.SQLStatement; -import com.iciql.Token; - -/** - * An AND expression. - */ -public class And implements Token { - - private final Token left, right; - - private And(Token left, Token right) { - this.left = left; - this.right = right; - } - - static And get(Token left, Token right) { - return new And(left, right); - } - - public <T> void appendSQL(SQLStatement stat, Query<T> query) { - left.appendSQL(stat, query); - stat.appendSQL(" AND "); - right.appendSQL(stat, query); - } - -} diff --git a/src/com/iciql/bytecode/ArrayGet.java b/src/com/iciql/bytecode/ArrayGet.java deleted file mode 100644 index 29516c2..0000000 --- a/src/com/iciql/bytecode/ArrayGet.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.bytecode; - -import com.iciql.Query; -import com.iciql.SQLStatement; -import com.iciql.Token; - -/** - * An array access operation. - */ -public class ArrayGet implements Token { - - private final Token variable; - private final Token index; - - private ArrayGet(Token variable, Token index) { - this.variable = variable; - this.index = index; - } - - static ArrayGet get(Token variable, Token index) { - return new ArrayGet(variable, index); - } - - public <T> void appendSQL(SQLStatement stat, Query<T> query) { - // untested - variable.appendSQL(stat, query); - stat.appendSQL("["); - index.appendSQL(stat, query); - stat.appendSQL("]"); - } - -} diff --git a/src/com/iciql/bytecode/CaseWhen.java b/src/com/iciql/bytecode/CaseWhen.java deleted file mode 100644 index 2a1d69e..0000000 --- a/src/com/iciql/bytecode/CaseWhen.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.bytecode; - -import com.iciql.Query; -import com.iciql.SQLStatement; -import com.iciql.Token; - -/** - * A conditional expression. - */ -public class CaseWhen implements Token { - - private final Token condition, ifTrue, ifFalse; - - private CaseWhen(Token condition, Token ifTrue, Token ifFalse) { - this.condition = condition; - this.ifTrue = ifTrue; - this.ifFalse = ifFalse; - } - - static Token get(Token condition, Token ifTrue, Token ifFalse) { - if ("0".equals(ifTrue.toString()) && "1".equals(ifFalse.toString())) { - return Not.get(condition); - } else if ("1".equals(ifTrue.toString()) && "0".equals(ifFalse.toString())) { - return condition; - } else if ("0".equals(ifTrue.toString())) { - return And.get(Not.get(condition), ifFalse); - } - return new CaseWhen(condition, ifTrue, ifFalse); - } - - public String toString() { - return "CASEWHEN(" + condition + ", " + ifTrue + ", " + ifFalse + ")"; - } - - public <T> void appendSQL(SQLStatement stat, Query<T> query) { - stat.appendSQL("CASEWHEN "); - condition.appendSQL(stat, query); - stat.appendSQL(" THEN "); - ifTrue.appendSQL(stat, query); - stat.appendSQL(" ELSE "); - ifFalse.appendSQL(stat, query); - stat.appendSQL(" END"); - } - -} diff --git a/src/com/iciql/bytecode/ClassReader.java b/src/com/iciql/bytecode/ClassReader.java deleted file mode 100644 index 38fd2f5..0000000 --- a/src/com/iciql/bytecode/ClassReader.java +++ /dev/null @@ -1,1457 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.bytecode; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.Stack; - -import com.iciql.IciqlException; -import com.iciql.Token; - -/** - * This class converts a method to a SQL Token by interpreting (decompiling) the - * bytecode of the class. - */ -public class ClassReader { - - private static final boolean DEBUG = false; - - private byte[] data; - private int pos; - private Constant[] constantPool; - private int startByteCode; - private String methodName; - - private String convertMethodName; - private Token result; - private Stack<Token> stack = new Stack<Token>(); - private ArrayList<Token> variables = new ArrayList<Token>(); - private boolean endOfMethod; - private boolean condition; - private int nextPc; - private Map<String, Object> fieldMap = new HashMap<String, Object>(); - - private static void debug(String s) { - if (DEBUG) { - System.out.println(s); - } - } - - public Token decompile(Object instance, Map<String, Object> fields, String method) { - this.fieldMap = fields; - this.convertMethodName = method; - Class<?> clazz = instance.getClass(); - String className = clazz.getName(); - debug("class name " + className); - ByteArrayOutputStream buff = new ByteArrayOutputStream(); - try { - InputStream in = clazz.getClassLoader().getResource(className.replace('.', '/') + ".class") - .openStream(); - while (true) { - int x = in.read(); - if (x < 0) { - break; - } - buff.write(x); - } - } catch (IOException e) { - throw new IciqlException("Could not read class bytecode", e); - } - data = buff.toByteArray(); - int header = readInt(); - debug("header: " + Integer.toHexString(header)); - int minorVersion = readShort(); - int majorVersion = readShort(); - debug("version: " + majorVersion + "." + minorVersion); - int constantPoolCount = readShort(); - constantPool = new Constant[constantPoolCount]; - for (int i = 1; i < constantPoolCount; i++) { - int type = readByte(); - switch (type) { - case 1: - constantPool[i] = ConstantString.get(readString()); - break; - case 3: { - int x = readInt(); - constantPool[i] = ConstantNumber.get(x); - break; - } - case 4: { - int x = readInt(); - constantPool[i] = ConstantNumber.get("" + Float.intBitsToFloat(x), x, Constant.Type.FLOAT); - break; - } - case 5: { - long x = readLong(); - constantPool[i] = ConstantNumber.get(x); - i++; - break; - } - case 6: { - long x = readLong(); - constantPool[i] = ConstantNumber - .get("" + Double.longBitsToDouble(x), x, Constant.Type.DOUBLE); - i++; - break; - } - case 7: { - int x = readShort(); - constantPool[i] = ConstantNumber.get(null, x, ConstantNumber.Type.CLASS_REF); - break; - } - case 8: { - int x = readShort(); - constantPool[i] = ConstantNumber.get(null, x, ConstantNumber.Type.STRING_REF); - break; - } - case 9: { - int x = readInt(); - constantPool[i] = ConstantNumber.get(null, x, ConstantNumber.Type.FIELD_REF); - break; - } - case 10: { - int x = readInt(); - constantPool[i] = ConstantNumber.get(null, x, ConstantNumber.Type.METHOD_REF); - break; - } - case 11: { - int x = readInt(); - constantPool[i] = ConstantNumber.get(null, x, ConstantNumber.Type.INTERFACE_METHOD_REF); - break; - } - case 12: { - int x = readInt(); - constantPool[i] = ConstantNumber.get(null, x, ConstantNumber.Type.NAME_AND_TYPE); - break; - } - default: - throw new IciqlException("Unsupported constant pool tag: " + type); - } - } - int accessFlags = readShort(); - debug("access flags: " + accessFlags); - int classRef = readShort(); - debug("class: " + constantPool[constantPool[classRef].intValue()]); - int superClassRef = readShort(); - debug(" extends " + constantPool[constantPool[superClassRef].intValue()]); - int interfaceCount = readShort(); - for (int i = 0; i < interfaceCount; i++) { - int interfaceRef = readShort(); - debug(" implements " + constantPool[constantPool[interfaceRef].intValue()]); - } - int fieldCount = readShort(); - for (int i = 0; i < fieldCount; i++) { - readField(); - } - int methodCount = readShort(); - for (int i = 0; i < methodCount; i++) { - readMethod(); - } - readAttributes(); - return result; - } - - private void readField() { - int accessFlags = readShort(); - int nameIndex = readShort(); - int descIndex = readShort(); - debug(" " + constantPool[descIndex] + " " + constantPool[nameIndex] + " " + accessFlags); - readAttributes(); - } - - private void readMethod() { - int accessFlags = readShort(); - int nameIndex = readShort(); - int descIndex = readShort(); - String desc = constantPool[descIndex].toString(); - methodName = constantPool[nameIndex].toString(); - debug(" " + desc + " " + methodName + " " + accessFlags); - readAttributes(); - } - - private void readAttributes() { - int attributeCount = readShort(); - for (int i = 0; i < attributeCount; i++) { - int attributeNameIndex = readShort(); - String attributeName = constantPool[attributeNameIndex].toString(); - debug(" attribute " + attributeName); - int attributeLength = readInt(); - int end = pos + attributeLength; - if ("Code".equals(attributeName)) { - readCode(); - } - pos = end; - } - } - - void decompile() { - int maxStack = readShort(); - int maxLocals = readShort(); - debug("stack: " + maxStack + " locals: " + maxLocals); - int codeLength = readInt(); - startByteCode = pos; - int end = pos + codeLength; - while (pos < end) { - readByteCode(); - } - debug(""); - pos = startByteCode + codeLength; - int exceptionTableLength = readShort(); - pos += 2 * exceptionTableLength; - readAttributes(); - } - - private void readCode() { - variables.clear(); - stack.clear(); - int maxStack = readShort(); - int maxLocals = readShort(); - debug("stack: " + maxStack + " locals: " + maxLocals); - int codeLength = readInt(); - startByteCode = pos; - if (methodName.startsWith(convertMethodName)) { - result = getResult(); - } - pos = startByteCode + codeLength; - int exceptionTableLength = readShort(); - pos += 2 * exceptionTableLength; - readAttributes(); - } - - private Token getResult() { - while (true) { - readByteCode(); - if (endOfMethod) { - return stack.pop(); - } - if (condition) { - Token c = stack.pop(); - Stack<Token> currentStack = new Stack<Token>(); - currentStack.addAll(stack); - ArrayList<Token> currentVariables = new ArrayList<Token>(); - currentVariables.addAll(variables); - int branch = nextPc; - Token a = getResult(); - stack = currentStack; - variables = currentVariables; - pos = branch + startByteCode; - Token b = getResult(); - if (a.equals("0") && b.equals("1")) { - return c; - } else if (a.equals("1") && b.equals("0")) { - return Not.get(c); - } else if (b.equals("0")) { - return And.get(Not.get(c), a); - } else if (a.equals("0")) { - return And.get(c, b); - } else if (b.equals("1")) { - return Or.get(c, a); - } else if (a.equals("1")) { - return And.get(Not.get(c), b); - } - return CaseWhen.get(c, b, a); - } - if (nextPc != 0) { - pos = nextPc + startByteCode; - } - } - } - - private void readByteCode() { - int startPos = pos - startByteCode; - int opCode = readByte(); - String op; - endOfMethod = false; - condition = false; - nextPc = 0; - switch (opCode) { - case 0: - op = "nop"; - break; - case 1: - op = "aconst_null"; - stack.push(Null.INSTANCE); - break; - case 2: - op = "iconst_m1"; - stack.push(ConstantNumber.get("-1")); - break; - case 3: - op = "iconst_0"; - stack.push(ConstantNumber.get("0")); - break; - case 4: - op = "iconst_1"; - stack.push(ConstantNumber.get("1")); - break; - case 5: - op = "iconst_2"; - stack.push(ConstantNumber.get("2")); - break; - case 6: - op = "iconst_3"; - stack.push(ConstantNumber.get("3")); - break; - case 7: - op = "iconst_4"; - stack.push(ConstantNumber.get("4")); - break; - case 8: - op = "iconst_5"; - stack.push(ConstantNumber.get("5")); - break; - case 9: - op = "lconst_0"; - stack.push(ConstantNumber.get("0")); - break; - case 10: - op = "lconst_1"; - stack.push(ConstantNumber.get("1")); - break; - case 11: - op = "fconst_0"; - stack.push(ConstantNumber.get("0.0")); - break; - case 12: - op = "fconst_1"; - stack.push(ConstantNumber.get("1.0")); - break; - case 13: - op = "fconst_2"; - stack.push(ConstantNumber.get("2.0")); - break; - case 14: - op = "dconst_0"; - stack.push(ConstantNumber.get("0.0")); - break; - case 15: - op = "dconst_1"; - stack.push(ConstantNumber.get("1.0")); - break; - case 16: { - int x = (byte) readByte(); - op = "bipush " + x; - stack.push(ConstantNumber.get(x)); - break; - } - case 17: { - int x = (short) readShort(); - op = "sipush " + x; - stack.push(ConstantNumber.get(x)); - break; - } - case 18: { - Token s = getConstant(readByte()); - op = "ldc " + s; - stack.push(s); - break; - } - case 19: { - Token s = getConstant(readShort()); - op = "ldc_w " + s; - stack.push(s); - break; - } - case 20: { - Token s = getConstant(readShort()); - op = "ldc2_w " + s; - stack.push(s); - break; - } - case 21: { - int x = readByte(); - op = "iload " + x; - stack.push(getVariable(x)); - break; - } - case 22: { - int x = readByte(); - op = "lload " + x; - stack.push(getVariable(x)); - break; - } - case 23: { - int x = readByte(); - op = "fload " + x; - stack.push(getVariable(x)); - break; - } - case 24: { - int x = readByte(); - op = "dload " + x; - stack.push(getVariable(x)); - break; - } - case 25: { - int x = readByte(); - op = "aload " + x; - stack.push(getVariable(x)); - break; - } - case 26: - op = "iload_0"; - stack.push(getVariable(0)); - break; - case 27: - op = "iload_1"; - stack.push(getVariable(1)); - break; - case 28: - op = "iload_2"; - stack.push(getVariable(2)); - break; - case 29: - op = "iload_3"; - stack.push(getVariable(3)); - break; - case 30: - op = "lload_0"; - stack.push(getVariable(0)); - break; - case 31: - op = "lload_1"; - stack.push(getVariable(1)); - break; - case 32: - op = "lload_2"; - stack.push(getVariable(2)); - break; - case 33: - op = "lload_3"; - stack.push(getVariable(3)); - break; - case 34: - op = "fload_0"; - stack.push(getVariable(0)); - break; - case 35: - op = "fload_1"; - stack.push(getVariable(1)); - break; - case 36: - op = "fload_2"; - stack.push(getVariable(2)); - break; - case 37: - op = "fload_3"; - stack.push(getVariable(3)); - break; - case 38: - op = "dload_0"; - stack.push(getVariable(0)); - break; - case 39: - op = "dload_1"; - stack.push(getVariable(1)); - break; - case 40: - op = "dload_2"; - stack.push(getVariable(2)); - break; - case 41: - op = "dload_3"; - stack.push(getVariable(3)); - break; - case 42: - op = "aload_0"; - stack.push(getVariable(0)); - break; - case 43: - op = "aload_1"; - stack.push(getVariable(1)); - break; - case 44: - op = "aload_2"; - stack.push(getVariable(2)); - break; - case 45: - op = "aload_3"; - stack.push(getVariable(3)); - break; - case 46: { - Token index = stack.pop(); - Token ref = stack.pop(); - op = "iaload"; - stack.push(ArrayGet.get(ref, index)); - break; - } - case 47: { - Token index = stack.pop(); - Token ref = stack.pop(); - op = "laload"; - stack.push(ArrayGet.get(ref, index)); - break; - } - case 48: { - Token index = stack.pop(); - Token ref = stack.pop(); - op = "faload"; - stack.push(ArrayGet.get(ref, index)); - break; - } - case 49: { - Token index = stack.pop(); - Token ref = stack.pop(); - op = "daload"; - stack.push(ArrayGet.get(ref, index)); - break; - } - case 50: { - Token index = stack.pop(); - Token ref = stack.pop(); - op = "aaload"; - stack.push(ArrayGet.get(ref, index)); - break; - } - case 51: { - Token index = stack.pop(); - Token ref = stack.pop(); - op = "baload"; - stack.push(ArrayGet.get(ref, index)); - break; - } - case 52: { - Token index = stack.pop(); - Token ref = stack.pop(); - op = "caload"; - stack.push(ArrayGet.get(ref, index)); - break; - } - case 53: { - Token index = stack.pop(); - Token ref = stack.pop(); - op = "saload"; - stack.push(ArrayGet.get(ref, index)); - break; - } - case 54: { - int var = readByte(); - op = "istore " + var; - setVariable(var, stack.pop()); - break; - } - case 55: { - int var = readByte(); - op = "lstore " + var; - setVariable(var, stack.pop()); - break; - } - case 56: { - int var = readByte(); - op = "fstore " + var; - setVariable(var, stack.pop()); - break; - } - case 57: { - int var = readByte(); - op = "dstore " + var; - setVariable(var, stack.pop()); - break; - } - case 58: { - int var = readByte(); - op = "astore " + var; - setVariable(var, stack.pop()); - break; - } - case 59: - op = "istore_0"; - setVariable(0, stack.pop()); - break; - case 60: - op = "istore_1"; - setVariable(1, stack.pop()); - break; - case 61: - op = "istore_2"; - setVariable(2, stack.pop()); - break; - case 62: - op = "istore_3"; - setVariable(3, stack.pop()); - break; - case 63: - op = "lstore_0"; - setVariable(0, stack.pop()); - break; - case 64: - op = "lstore_1"; - setVariable(1, stack.pop()); - break; - case 65: - op = "lstore_2"; - setVariable(2, stack.pop()); - break; - case 66: - op = "lstore_3"; - setVariable(3, stack.pop()); - break; - case 67: - op = "fstore_0"; - setVariable(0, stack.pop()); - break; - case 68: - op = "fstore_1"; - setVariable(1, stack.pop()); - break; - case 69: - op = "fstore_2"; - setVariable(2, stack.pop()); - break; - case 70: - op = "fstore_3"; - setVariable(3, stack.pop()); - break; - case 71: - op = "dstore_0"; - setVariable(0, stack.pop()); - break; - case 72: - op = "dstore_1"; - setVariable(1, stack.pop()); - break; - case 73: - op = "dstore_2"; - setVariable(2, stack.pop()); - break; - case 74: - op = "dstore_3"; - setVariable(3, stack.pop()); - break; - case 75: - op = "astore_0"; - setVariable(0, stack.pop()); - break; - case 76: - op = "astore_1"; - setVariable(1, stack.pop()); - break; - case 77: - op = "astore_2"; - setVariable(2, stack.pop()); - break; - case 78: - op = "astore_3"; - setVariable(3, stack.pop()); - break; - case 79: { - // String value = stack.pop(); - // String index = stack.pop(); - // String ref = stack.pop(); - op = "iastore"; - // TODO side effect - not supported - break; - } - case 80: - op = "lastore"; - // TODO side effect - not supported - break; - case 81: - op = "fastore"; - // TODO side effect - not supported - break; - case 82: - op = "dastore"; - // TODO side effect - not supported - break; - case 83: - op = "aastore"; - // TODO side effect - not supported - break; - case 84: - op = "bastore"; - // TODO side effect - not supported - break; - case 85: - op = "castore"; - // TODO side effect - not supported - break; - case 86: - op = "sastore"; - // TODO side effect - not supported - break; - case 87: - op = "pop"; - stack.pop(); - break; - case 88: - op = "pop2"; - // TODO currently we don't know the stack types - stack.pop(); - stack.pop(); - break; - case 89: { - op = "dup"; - Token x = stack.pop(); - stack.push(x); - stack.push(x); - break; - } - case 90: { - op = "dup_x1"; - Token a = stack.pop(); - Token b = stack.pop(); - stack.push(a); - stack.push(b); - stack.push(a); - break; - } - case 91: { - // TODO currently we don't know the stack types - op = "dup_x2"; - Token a = stack.pop(); - Token b = stack.pop(); - Token c = stack.pop(); - stack.push(a); - stack.push(c); - stack.push(b); - stack.push(a); - break; - } - case 92: { - // TODO currently we don't know the stack types - op = "dup2"; - Token a = stack.pop(); - Token b = stack.pop(); - stack.push(b); - stack.push(a); - stack.push(b); - stack.push(a); - break; - } - case 93: { - // TODO currently we don't know the stack types - op = "dup2_x1"; - Token a = stack.pop(); - Token b = stack.pop(); - Token c = stack.pop(); - stack.push(b); - stack.push(a); - stack.push(c); - stack.push(b); - stack.push(a); - break; - } - case 94: { - // TODO currently we don't know the stack types - op = "dup2_x2"; - Token a = stack.pop(); - Token b = stack.pop(); - Token c = stack.pop(); - Token d = stack.pop(); - stack.push(b); - stack.push(a); - stack.push(d); - stack.push(c); - stack.push(b); - stack.push(a); - break; - } - case 95: { - op = "swap"; - Token a = stack.pop(); - Token b = stack.pop(); - stack.push(a); - stack.push(b); - break; - } - case 96: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "iadd"; - stack.push(Operation.get(a, Operation.Type.ADD, b)); - break; - } - case 97: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "ladd"; - stack.push(Operation.get(a, Operation.Type.ADD, b)); - break; - } - case 98: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "fadd"; - stack.push(Operation.get(a, Operation.Type.ADD, b)); - break; - } - case 99: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "dadd"; - stack.push(Operation.get(a, Operation.Type.ADD, b)); - break; - } - case 100: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "isub"; - stack.push(Operation.get(a, Operation.Type.SUBTRACT, b)); - break; - } - case 101: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "lsub"; - stack.push(Operation.get(a, Operation.Type.SUBTRACT, b)); - break; - } - case 102: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "fsub"; - stack.push(Operation.get(a, Operation.Type.SUBTRACT, b)); - break; - } - case 103: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "dsub"; - stack.push(Operation.get(a, Operation.Type.SUBTRACT, b)); - break; - } - case 104: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "imul"; - stack.push(Operation.get(a, Operation.Type.MULTIPLY, b)); - break; - } - case 105: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "lmul"; - stack.push(Operation.get(a, Operation.Type.MULTIPLY, b)); - break; - } - case 106: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "fmul"; - stack.push(Operation.get(a, Operation.Type.MULTIPLY, b)); - break; - } - case 107: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "dmul"; - stack.push(Operation.get(a, Operation.Type.MULTIPLY, b)); - break; - } - case 108: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "idiv"; - stack.push(Operation.get(a, Operation.Type.DIVIDE, b)); - break; - } - case 109: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "ldiv"; - stack.push(Operation.get(a, Operation.Type.DIVIDE, b)); - break; - } - case 110: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "fdiv"; - stack.push(Operation.get(a, Operation.Type.DIVIDE, b)); - break; - } - case 111: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "ddiv"; - stack.push(Operation.get(a, Operation.Type.DIVIDE, b)); - break; - } - case 112: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "irem"; - stack.push(Operation.get(a, Operation.Type.MOD, b)); - break; - } - case 113: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "lrem"; - stack.push(Operation.get(a, Operation.Type.MOD, b)); - break; - } - case 114: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "frem"; - stack.push(Operation.get(a, Operation.Type.MOD, b)); - break; - } - case 115: { - Token b = stack.pop(); - Token a = stack.pop(); - op = "drem"; - stack.push(Operation.get(a, Operation.Type.MOD, b)); - break; - } - // case 116: - // op = "ineg"; - // break; - // case 117: - // op = "lneg"; - // break; - // case 118: - // op = "fneg"; - // break; - // case 119: - // op = "dneg"; - // break; - // case 120: - // op = "ishl"; - // break; - // case 121: - // op = "lshl"; - // break; - // case 122: - // op = "ishr"; - // break; - // case 123: - // op = "lshr"; - // break; - // case 124: - // op = "iushr"; - // break; - // case 125: - // op = "lushr"; - // break; - // case 126: - // op = "iand"; - // break; - // case 127: - // op = "land"; - // break; - // case 128: - // op = "ior"; - // break; - // case 129: - // op = "lor"; - // break; - // case 130: - // op = "ixor"; - // break; - // case 131: - // op = "lxor"; - // break; - // case 132: { - // int var = readByte(); - // int off = (byte) readByte(); - // op = "iinc " + var + " " + off; - // break; - // } - // case 133: - // op = "i2l"; - // break; - // case 134: - // op = "i2f"; - // break; - // case 135: - // op = "i2d"; - // break; - // case 136: - // op = "l2i"; - // break; - // case 137: - // op = "l2f"; - // break; - // case 138: - // op = "l2d"; - // break; - // case 139: - // op = "f2i"; - // break; - // case 140: - // op = "f2l"; - // break; - // case 141: - // op = "f2d"; - // break; - // case 142: - // op = "d2i"; - // break; - // case 143: - // op = "d2l"; - // break; - // case 144: - // op = "d2f"; - // break; - // case 145: - // op = "i2b"; - // break; - // case 146: - // op = "i2c"; - // break; - // case 147: - // op = "i2s"; - // break; - case 148: { - Token b = stack.pop(), a = stack.pop(); - stack.push(new Function("SIGN", Operation.get(a, Operation.Type.SUBTRACT, b))); - op = "lcmp"; - break; - } - // case 149: - // op = "fcmpl"; - // break; - // case 150: - // op = "fcmpg"; - // break; - // case 151: - // op = "dcmpl"; - // break; - // case 152: - // op = "dcmpg"; - // break; - case 153: - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - stack.push(Operation.get(stack.pop(), Operation.Type.EQUALS, ConstantNumber.get(0))); - op = "ifeq " + nextPc; - break; - case 154: - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - stack.push(Operation.get(stack.pop(), Operation.Type.NOT_EQUALS, ConstantNumber.get(0))); - op = "ifne " + nextPc; - break; - case 155: - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - stack.push(Operation.get(stack.pop(), Operation.Type.SMALLER, ConstantNumber.get(0))); - op = "iflt " + nextPc; - break; - case 156: - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - stack.push(Operation.get(stack.pop(), Operation.Type.BIGGER_EQUALS, ConstantNumber.get(0))); - op = "ifge " + nextPc; - break; - case 157: - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - stack.push(Operation.get(stack.pop(), Operation.Type.BIGGER, ConstantNumber.get(0))); - op = "ifgt " + nextPc; - break; - case 158: - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - stack.push(Operation.get(stack.pop(), Operation.Type.SMALLER_EQUALS, ConstantNumber.get(0))); - op = "ifle " + nextPc; - break; - case 159: { - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - Token b = stack.pop(), a = stack.pop(); - stack.push(Operation.get(a, Operation.Type.EQUALS, b)); - op = "if_icmpeq " + nextPc; - break; - } - case 160: { - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - Token b = stack.pop(), a = stack.pop(); - stack.push(Operation.get(a, Operation.Type.NOT_EQUALS, b)); - op = "if_icmpne " + nextPc; - break; - } - case 161: { - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - Token b = stack.pop(), a = stack.pop(); - stack.push(Operation.get(a, Operation.Type.SMALLER, b)); - op = "if_icmplt " + nextPc; - break; - } - case 162: { - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - Token b = stack.pop(), a = stack.pop(); - stack.push(Operation.get(a, Operation.Type.BIGGER_EQUALS, b)); - op = "if_icmpge " + nextPc; - break; - } - case 163: { - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - Token b = stack.pop(), a = stack.pop(); - stack.push(Operation.get(a, Operation.Type.BIGGER, b)); - op = "if_icmpgt " + nextPc; - break; - } - case 164: { - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - Token b = stack.pop(), a = stack.pop(); - stack.push(Operation.get(a, Operation.Type.SMALLER_EQUALS, b)); - op = "if_icmple " + nextPc; - break; - } - case 165: { - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - Token b = stack.pop(), a = stack.pop(); - stack.push(Operation.get(a, Operation.Type.EQUALS, b)); - op = "if_acmpeq " + nextPc; - break; - } - case 166: { - condition = true; - nextPc = getAbsolutePos(pos, readShort()); - Token b = stack.pop(), a = stack.pop(); - stack.push(Operation.get(a, Operation.Type.NOT_EQUALS, b)); - op = "if_acmpne " + nextPc; - break; - } - case 167: - nextPc = getAbsolutePos(pos, readShort()); - op = "goto " + nextPc; - break; - // case 168: - // // TODO not supported yet - // op = "jsr " + getAbsolutePos(pos, readShort()); - // break; - // case 169: - // // TODO not supported yet - // op = "ret " + readByte(); - // break; - // case 170: { - // int start = pos; - // pos += 4 - ((pos - startByteCode) & 3); - // int def = readInt(); - // int low = readInt(), high = readInt(); - // int n = high - low + 1; - // op = "tableswitch default:" + getAbsolutePos(start, def); - // StringBuilder buff = new StringBuilder(); - // for (int i = 0; i < n; i++) { - // buff.append(' ').append(low++). - // append(":"). - // append(getAbsolutePos(start, readInt())); - // } - // op += buff.toString(); - // // pos += n * 4; - // break; - // } - // case 171: { - // int start = pos; - // pos += 4 - ((pos - startByteCode) & 3); - // int def = readInt(); - // int n = readInt(); - // op = "lookupswitch default:" + getAbsolutePos(start, def); - // StringBuilder buff = new StringBuilder(); - // for (int i = 0; i < n; i++) { - // buff.append(' '). - // append(readInt()). - // append(":"). - // append(getAbsolutePos(start, readInt())); - // } - // op += buff.toString(); - // // pos += n * 8; - // break; - // } - case 172: - op = "ireturn"; - endOfMethod = true; - break; - case 173: - op = "lreturn"; - endOfMethod = true; - break; - case 174: - op = "freturn"; - endOfMethod = true; - break; - case 175: - op = "dreturn"; - endOfMethod = true; - break; - case 176: - op = "areturn"; - endOfMethod = true; - break; - case 177: - op = "return"; - // no value returned - stack.push(null); - endOfMethod = true; - break; - // case 178: - // op = "getstatic " + getField(readShort()); - // break; - // case 179: - // op = "putstatic " + getField(readShort()); - // break; - case 180: { - String field = getField(readShort()); - Token p = stack.pop(); - String s = p + "." + field.substring(field.lastIndexOf('.') + 1, field.indexOf(' ')); - if (s.startsWith("this.")) { - s = s.substring(5); - } - stack.push(Variable.get(s, fieldMap.get(s))); - op = "getfield " + field; - break; - } - // case 181: - // op = "putfield " + getField(readShort()); - // break; - case 182: { - String method = getMethod(readShort()); - op = "invokevirtual " + method; - if (method.equals("java/lang/String.equals (Ljava/lang/Object;)Z")) { - Token a = stack.pop(); - Token b = stack.pop(); - stack.push(Operation.get(a, Operation.Type.EQUALS, b)); - } else if (method.equals("java/lang/Integer.intValue ()I")) { - // ignore - } else if (method.equals("java/lang/Long.longValue ()J")) { - // ignore - } - break; - } - case 183: { - String method = getMethod(readShort()); - op = "invokespecial " + method; - break; - } - case 184: - op = "invokestatic " + getMethod(readShort()); - break; - // case 185: { - // int methodRef = readShort(); - // readByte(); - // readByte(); - // op = "invokeinterface " + getMethod(methodRef); - // break; - // } - case 187: { - String className = constantPool[constantPool[readShort()].intValue()].toString(); - op = "new " + className; - break; - } - // case 188: - // op = "newarray " + readByte(); - // break; - // case 189: - // op = "anewarray " + cpString[readShort()]; - // break; - // case 190: - // op = "arraylength"; - // break; - // case 191: - // op = "athrow"; - // break; - // case 192: - // op = "checkcast " + cpString[readShort()]; - // break; - // case 193: - // op = "instanceof " + cpString[readShort()]; - // break; - // case 194: - // op = "monitorenter"; - // break; - // case 195: - // op = "monitorexit"; - // break; - // case 196: { - // opCode = readByte(); - // switch (opCode) { - // case 21: - // op = "wide iload " + readShort(); - // break; - // case 22: - // op = "wide lload " + readShort(); - // break; - // case 23: - // op = "wide fload " + readShort(); - // break; - // case 24: - // op = "wide dload " + readShort(); - // break; - // case 25: - // op = "wide aload " + readShort(); - // break; - // case 54: - // op = "wide istore " + readShort(); - // break; - // case 55: - // op = "wide lstore " + readShort(); - // break; - // case 56: - // op = "wide fstore " + readShort(); - // break; - // case 57: - // op = "wide dstore " + readShort(); - // break; - // case 58: - // op = "wide astore " + readShort(); - // break; - // case 132: { - // int var = readShort(); - // int off = (short) readShort(); - // op = "wide iinc " + var + " " + off; - // break; - // } - // case 169: - // op = "wide ret " + readShort(); - // break; - // default: - // throw new IciqlException( - // "Unsupported wide opCode " + opCode); - // } - // break; - // } - // case 197: - // op = "multianewarray " + cpString[readShort()] + " " + readByte(); - // break; - // case 198: { - // condition = true; - // nextPc = getAbsolutePos(pos, readShort()); - // Token a = stack.pop(); - // stack.push("(" + a + " IS NULL)"); - // op = "ifnull " + nextPc; - // break; - // } - // case 199: { - // condition = true; - // nextPc = getAbsolutePos(pos, readShort()); - // Token a = stack.pop(); - // stack.push("(" + a + " IS NOT NULL)"); - // op = "ifnonnull " + nextPc; - // break; - // } - case 200: - op = "goto_w " + getAbsolutePos(pos, readInt()); - break; - case 201: - op = "jsr_w " + getAbsolutePos(pos, readInt()); - break; - default: - throw new IciqlException("Unsupported opCode " + opCode); - } - debug(" " + startPos + ": " + op); - } - - private void setVariable(int x, Token value) { - while (x >= variables.size()) { - variables.add(Variable.get("p" + variables.size(), null)); - } - variables.set(x, value); - } - - private Token getVariable(int x) { - if (x == 0) { - return Variable.THIS; - } - while (x >= variables.size()) { - variables.add(Variable.get("p" + variables.size(), null)); - } - return variables.get(x); - } - - private String getField(int fieldRef) { - int field = constantPool[fieldRef].intValue(); - int classIndex = field >>> 16; - int nameAndType = constantPool[field & 0xffff].intValue(); - String className = constantPool[constantPool[classIndex].intValue()] + "." - + constantPool[nameAndType >>> 16] + " " + constantPool[nameAndType & 0xffff]; - return className; - } - - private String getMethod(int methodRef) { - int method = constantPool[methodRef].intValue(); - int classIndex = method >>> 16; - int nameAndType = constantPool[method & 0xffff].intValue(); - String className = constantPool[constantPool[classIndex].intValue()] + "." - + constantPool[nameAndType >>> 16] + " " + constantPool[nameAndType & 0xffff]; - return className; - } - - private Constant getConstant(int constantRef) { - Constant c = constantPool[constantRef]; - switch (c.getType()) { - case INT: - case FLOAT: - case DOUBLE: - case LONG: - return c; - case STRING_REF: - return constantPool[c.intValue()]; - default: - throw new IciqlException("Not a constant: " + constantRef); - } - } - - private String readString() { - int size = readShort(); - byte[] buff = data; - int p = pos, end = p + size; - char[] chars = new char[size]; - int j = 0; - for (; p < end; j++) { - int x = buff[p++] & 0xff; - if (x < 0x80) { - chars[j] = (char) x; - } else if (x >= 0xe0) { - chars[j] = (char) (((x & 0xf) << 12) + ((buff[p++] & 0x3f) << 6) + (buff[p++] & 0x3f)); - } else { - chars[j] = (char) (((x & 0x1f) << 6) + (buff[p++] & 0x3f)); - } - } - pos = p; - return new String(chars, 0, j); - } - - private int getAbsolutePos(int start, int offset) { - return start - startByteCode - 1 + (short) offset; - } - - private int readByte() { - return data[pos++] & 0xff; - } - - private int readShort() { - byte[] buff = data; - return ((buff[pos++] & 0xff) << 8) + (buff[pos++] & 0xff); - } - - private int readInt() { - byte[] buff = data; - return (buff[pos++] << 24) + ((buff[pos++] & 0xff) << 16) + ((buff[pos++] & 0xff) << 8) - + (buff[pos++] & 0xff); - } - - private long readLong() { - return ((long) (readInt()) << 32) + (readInt() & 0xffffffffL); - } - -} diff --git a/src/com/iciql/bytecode/Constant.java b/src/com/iciql/bytecode/Constant.java deleted file mode 100644 index 65cd66b..0000000 --- a/src/com/iciql/bytecode/Constant.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.bytecode; - -import com.iciql.Token; - -/** - * An expression in the constant pool. - */ -public interface Constant extends Token { - - /** - * The constant pool type. - */ - enum Type { - STRING, INT, FLOAT, DOUBLE, LONG, CLASS_REF, STRING_REF, FIELD_REF, METHOD_REF, INTERFACE_METHOD_REF, NAME_AND_TYPE - } - - Constant.Type getType(); - - int intValue(); - -} diff --git a/src/com/iciql/bytecode/ConstantNumber.java b/src/com/iciql/bytecode/ConstantNumber.java deleted file mode 100644 index 934de3d..0000000 --- a/src/com/iciql/bytecode/ConstantNumber.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.bytecode; - -import com.iciql.Query; -import com.iciql.SQLStatement; - -/** - * A literal number. - */ -public class ConstantNumber implements Constant { - - private final String value; - private final Type type; - private final long longValue; - - private ConstantNumber(String value, long longValue, Type type) { - this.value = value; - this.longValue = longValue; - this.type = type; - } - - static ConstantNumber get(String v) { - return new ConstantNumber(v, 0, Type.STRING); - } - - static ConstantNumber get(int v) { - return new ConstantNumber("" + v, v, Type.INT); - } - - static ConstantNumber get(long v) { - return new ConstantNumber("" + v, v, Type.LONG); - } - - static ConstantNumber get(String s, long x, Type type) { - return new ConstantNumber(s, x, type); - } - - public int intValue() { - return (int) longValue; - } - - public String toString() { - return value; - } - - public <T> void appendSQL(SQLStatement stat, Query<T> query) { - stat.appendSQL(toString()); - } - - public Constant.Type getType() { - return type; - } - -} diff --git a/src/com/iciql/bytecode/ConstantString.java b/src/com/iciql/bytecode/ConstantString.java deleted file mode 100644 index 985f97d..0000000 --- a/src/com/iciql/bytecode/ConstantString.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.bytecode; - -import com.iciql.Query; -import com.iciql.SQLStatement; -import com.iciql.util.StringUtils; - -/** - * A string constant. - */ -public class ConstantString implements Constant { - - private final String value; - - private ConstantString(String value) { - this.value = value; - } - - static ConstantString get(String v) { - return new ConstantString(v); - } - - public String toString() { - return value; - } - - public int intValue() { - return 0; - } - - public <T> void appendSQL(SQLStatement stat, Query<T> query) { - stat.appendSQL(StringUtils.quoteStringSQL(value)); - } - - public Constant.Type getType() { - return Constant.Type.STRING; - } - -} diff --git a/src/com/iciql/bytecode/Function.java b/src/com/iciql/bytecode/Function.java deleted file mode 100644 index 56a55ea..0000000 --- a/src/com/iciql/bytecode/Function.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.bytecode; - -import com.iciql.Query; -import com.iciql.SQLStatement; -import com.iciql.Token; - -/** - * A method call. - */ -class Function implements Token { - - private final String name; - private final Token expr; - - Function(String name, Token expr) { - this.name = name; - this.expr = expr; - } - - public String toString() { - return name + "(" + expr + ")"; - } - - public <T> void appendSQL(SQLStatement stat, Query<T> query) { - // untested - stat.appendSQL(name + "("); - expr.appendSQL(stat, query); - stat.appendSQL(")"); - } -} diff --git a/src/com/iciql/bytecode/Not.java b/src/com/iciql/bytecode/Not.java deleted file mode 100644 index ab5ab84..0000000 --- a/src/com/iciql/bytecode/Not.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.bytecode; - -import com.iciql.Query; -import com.iciql.SQLStatement; -import com.iciql.Token; - -/** - * A NOT condition. - */ -public class Not implements Token { - - private Token expr; - - private Not(Token expr) { - this.expr = expr; - } - - static Token get(Token expr) { - if (expr instanceof Not) { - return ((Not) expr).expr; - } else if (expr instanceof Operation) { - return ((Operation) expr).reverse(); - } - return new Not(expr); - } - - Token not() { - return expr; - } - - public <T> void appendSQL(SQLStatement stat, Query<T> query) { - // untested - stat.appendSQL("NOT("); - expr.appendSQL(stat, query); - stat.appendSQL(")"); - } - -} diff --git a/src/com/iciql/bytecode/Null.java b/src/com/iciql/bytecode/Null.java deleted file mode 100644 index a28de56..0000000 --- a/src/com/iciql/bytecode/Null.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.bytecode; - -import com.iciql.Query; -import com.iciql.SQLStatement; -import com.iciql.Token; - -/** - * The Java 'null'. - */ -public class Null implements Token { - - static final Null INSTANCE = new Null(); - - private Null() { - // don't allow to create new instances - } - - public String toString() { - return "null"; - } - - public <T> void appendSQL(SQLStatement stat, Query<T> query) { - // untested - stat.appendSQL("NULL"); - } - -} diff --git a/src/com/iciql/bytecode/Operation.java b/src/com/iciql/bytecode/Operation.java deleted file mode 100644 index 7cd42d9..0000000 --- a/src/com/iciql/bytecode/Operation.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.bytecode; - -import com.iciql.Query; -import com.iciql.SQLStatement; -import com.iciql.Token; - -/** - * A mathematical or comparison operation. - */ -class Operation implements Token { - - /** - * The operation type. - */ - enum Type { - EQUALS("=") { - Type reverse() { - return NOT_EQUALS; - } - }, - NOT_EQUALS("<>") { - Type reverse() { - return EQUALS; - } - }, - BIGGER(">") { - Type reverse() { - return SMALLER_EQUALS; - } - }, - BIGGER_EQUALS(">=") { - Type reverse() { - return SMALLER; - } - }, - SMALLER_EQUALS("<=") { - Type reverse() { - return BIGGER; - } - }, - SMALLER("<") { - Type reverse() { - return BIGGER_EQUALS; - } - }, - ADD("+"), SUBTRACT("-"), MULTIPLY("*"), DIVIDE("/"), MOD("%"); - - private String name; - - Type(String name) { - this.name = name; - } - - public String toString() { - return name; - } - - Type reverse() { - return null; - } - - } - - private final Token left, right; - private final Type op; - - private Operation(Token left, Type op, Token right) { - this.left = left; - this.op = op; - this.right = right; - } - - static Token get(Token left, Type op, Token right) { - if (op == Type.NOT_EQUALS && "0".equals(right.toString())) { - return left; - } - return new Operation(left, op, right); - } - - public String toString() { - return left + " " + op + " " + right; - } - - public Token reverse() { - return get(left, op.reverse(), right); - } - - public <T> void appendSQL(SQLStatement stat, Query<T> query) { - left.appendSQL(stat, query); - stat.appendSQL(op.toString()); - right.appendSQL(stat, query); - } - -} diff --git a/src/com/iciql/bytecode/Or.java b/src/com/iciql/bytecode/Or.java deleted file mode 100644 index 37da2a6..0000000 --- a/src/com/iciql/bytecode/Or.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.bytecode; - -import com.iciql.Query; -import com.iciql.SQLStatement; -import com.iciql.Token; - -/** - * An OR expression. - */ -public class Or implements Token { - - private final Token left, right; - - private Or(Token left, Token right) { - this.left = left; - this.right = right; - } - - static Or get(Token left, Token right) { - return new Or(left, right); - } - - public <T> void appendSQL(SQLStatement stat, Query<T> query) { - // untested - left.appendSQL(stat, query); - stat.appendSQL(" OR "); - right.appendSQL(stat, query); - } - -} diff --git a/src/com/iciql/bytecode/Variable.java b/src/com/iciql/bytecode/Variable.java deleted file mode 100644 index f3dbc01..0000000 --- a/src/com/iciql/bytecode/Variable.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.bytecode; - -import com.iciql.Query; -import com.iciql.SQLStatement; -import com.iciql.Token; - -/** - * A variable. - */ -public class Variable implements Token { - - static final Variable THIS = new Variable("this", null); - - private final String name; - private final Object obj; - - private Variable(String name, Object obj) { - this.name = name; - this.obj = obj; - } - - static Variable get(String name, Object obj) { - return new Variable(name, obj); - } - - public String toString() { - return name; - } - - public <T> void appendSQL(SQLStatement stat, Query<T> query) { - query.appendSQL(stat, null, obj); - } - -} diff --git a/src/com/iciql/bytecode/package.html b/src/com/iciql/bytecode/package.html deleted file mode 100644 index 5107481..0000000 --- a/src/com/iciql/bytecode/package.html +++ /dev/null @@ -1,25 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<!-- - Copyright 2004-2011 H2 Group. - Copyright 2011 James Moger. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<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> -The class decompiler for natural syntax iciql clauses. -</body> -</html>
\ No newline at end of file diff --git a/src/com/iciql/package.html b/src/com/iciql/package.html deleted file mode 100644 index 769837b..0000000 --- a/src/com/iciql/package.html +++ /dev/null @@ -1,25 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<!--
- Copyright 2004-2011 H2 Group.
- Copyright 2011 James Moger.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<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>
-<i>iciql</i> (pronounced "icicle") is a Java JDBC SQL statement generator and simple object mapper
-</body>
-</html>
\ No newline at end of file diff --git a/src/com/iciql/util/GenerateModels.java b/src/com/iciql/util/GenerateModels.java deleted file mode 100644 index eac9f6c..0000000 --- a/src/com/iciql/util/GenerateModels.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.util; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.io.Writer; -import java.sql.SQLException; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.iciql.Db; -import com.iciql.DbInspector; - -/** - * Generates iciql models. - */ -public class GenerateModels { - - /** - * The output stream where this tool writes to. - */ - protected PrintStream out = System.out; - - public static void main(String... args) { - GenerateModels tool = new GenerateModels(); - try { - tool.runTool(args); - } catch (SQLException e) { - tool.out.print("Error: "); - tool.out.println(e.getMessage()); - tool.out.println(); - tool.showUsage(); - } - } - - public void runTool(String... args) throws SQLException { - String url = null; - String user = "sa"; - String password = ""; - String schema = null; - String table = null; - String packageName = ""; - String folder = null; - boolean annotateSchema = true; - boolean trimStrings = false; - for (int i = 0; args != null && i < args.length; i++) { - String arg = args[i]; - if (arg.equals("-url")) { - url = args[++i]; - } else if (arg.equals("-user")) { - user = args[++i]; - } else if (arg.equals("-password")) { - password = args[++i]; - } else if (arg.equals("-schema")) { - schema = args[++i]; - } else if (arg.equals("-table")) { - table = args[++i]; - } else if (arg.equals("-package")) { - packageName = args[++i]; - } else if (arg.equals("-folder")) { - folder = args[++i]; - } else if (arg.equals("-annotateSchema")) { - try { - annotateSchema = Boolean.parseBoolean(args[++i]); - } catch (Throwable t) { - throw new SQLException("Can not parse -annotateSchema value"); - } - } else if (arg.equals("-trimStrings")) { - try { - trimStrings = Boolean.parseBoolean(args[++i]); - } catch (Throwable t) { - throw new SQLException("Can not parse -trimStrings value"); - } - } else { - throwUnsupportedOption(arg); - } - } - if (url == null) { - throw new SQLException("URL not set"); - } - execute(url, user, password, schema, table, packageName, folder, annotateSchema, trimStrings); - } - - /** - * Generates models from the database. - * - * @param url - * the database URL - * @param user - * the user name - * @param password - * the password - * @param schema - * the schema to read from. null for all schemas. - * @param table - * the table to model. null for all tables within schema. - * @param packageName - * the package name of the model classes. - * @param folder - * destination folder for model classes (package path not - * included) - * @param annotateSchema - * includes the schema in the table model annotations - * @param trimStrings - * automatically trim strings that exceed maxLength - */ - public static void execute(String url, String user, String password, String schema, String table, - String packageName, String folder, boolean annotateSchema, boolean trimStrings) - throws SQLException { - try { - Db db; - if (password == null) { - db = Db.open(url, user, (String) null); - } else { - db = Db.open(url, user, password); - } - DbInspector inspector = new DbInspector(db); - List<String> models = inspector.generateModel(schema, table, packageName, annotateSchema, - trimStrings); - File parentFile; - if (StringUtils.isNullOrEmpty(folder)) { - parentFile = new File(System.getProperty("user.dir")); - } else { - parentFile = new File(folder); - } - parentFile.mkdirs(); - Pattern p = Pattern.compile("class ([a-zA-Z0-9]+)"); - for (String model : models) { - Matcher m = p.matcher(model); - if (m.find()) { - String className = m.group().substring("class".length()).trim(); - File classFile = new File(parentFile, className + ".java"); - Writer o = new FileWriter(classFile, false); - PrintWriter writer = new PrintWriter(new BufferedWriter(o)); - writer.write(model); - writer.close(); - System.out.println("Generated " + classFile.getAbsolutePath()); - } - } - } catch (IOException io) { - throw new SQLException("could not generate model", io); - } - } - - /** - * Throw a SQLException saying this command line option is not supported. - * - * @param option - * the unsupported option - * @return this method never returns normally - */ - protected SQLException throwUnsupportedOption(String option) throws SQLException { - showUsage(); - throw new SQLException("Unsupported option: " + option); - } - - protected void showUsage() { - out.println("GenerateModels"); - out.println("Usage:"); - out.println(); - out.println("(*) -url jdbc:h2:~test"); - out.println(" -user <string>"); - out.println(" -password <string>"); - out.println(" -schema <string>"); - out.println(" -table <string>"); - out.println(" -package <string>"); - out.println(" -folder <string>"); - out.println(" -annotateSchema <boolean>"); - out.println(" -trimStrings <boolean>"); - } - -} diff --git a/src/com/iciql/util/IciqlLogger.java b/src/com/iciql/util/IciqlLogger.java deleted file mode 100644 index d8005bb..0000000 --- a/src/com/iciql/util/IciqlLogger.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.util; - -import java.text.DecimalFormat; -import java.text.MessageFormat; -import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.atomic.AtomicLong; - -import com.iciql.IciqlException; - -/** - * Utility class to optionally log generated statements to IciqlListeners.<br> - * Statement logging is disabled by default. - * <p> - * This class also tracks the counts for generated statements by major type. - * - */ -public class IciqlLogger { - - /** - * Enumeration of the different statement types that are logged. - */ - public enum StatementType { - STAT, TOTAL, CREATE, INSERT, UPDATE, MERGE, DELETE, SELECT, DROP, WARN; - } - - /** - * Interface that defines an iciql listener. - */ - public interface IciqlListener { - void logIciql(StatementType type, String statement); - } - - private static final ExecutorService EXEC = Executors.newSingleThreadExecutor(); - private static final Set<IciqlListener> LISTENERS = Utils.newHashSet(); - private static final IciqlListener CONSOLE = new IciqlListener() { - - @Override - public void logIciql(StatementType type, String message) { - System.out.println(message); - } - }; - - private static final AtomicLong SELECT_COUNT = new AtomicLong(); - private static final AtomicLong CREATE_COUNT = new AtomicLong(); - private static final AtomicLong INSERT_COUNT = new AtomicLong(); - private static final AtomicLong UPDATE_COUNT = new AtomicLong(); - private static final AtomicLong MERGE_COUNT = new AtomicLong(); - private static final AtomicLong DELETE_COUNT = new AtomicLong(); - private static final AtomicLong DROP_COUNT = new AtomicLong(); - private static final AtomicLong WARN_COUNT = new AtomicLong(); - - /** - * Activates the Console Logger. - */ - public static void activateConsoleLogger() { - registerListener(CONSOLE); - } - - /** - * Deactivates the Console Logger. - */ - public static void deactivateConsoleLogger() { - unregisterListener(CONSOLE); - } - - /** - * Registers a listener with the relay. - * - * @param listener - */ - public static void registerListener(IciqlListener listener) { - LISTENERS.add(listener); - } - - /** - * Unregisters a listener with the relay. - * - * @param listener - */ - public static void unregisterListener(IciqlListener listener) { - if (!LISTENERS.remove(listener)) { - throw new IciqlException("Failed to remove iciql listener {0}", listener); - } - } - - public static void create(String statement) { - CREATE_COUNT.incrementAndGet(); - logStatement(StatementType.CREATE, statement); - } - - public static void insert(String statement) { - INSERT_COUNT.incrementAndGet(); - logStatement(StatementType.INSERT, statement); - } - - public static void update(String statement) { - UPDATE_COUNT.incrementAndGet(); - logStatement(StatementType.UPDATE, statement); - } - - public static void merge(String statement) { - MERGE_COUNT.incrementAndGet(); - logStatement(StatementType.MERGE, statement); - } - - public static void delete(String statement) { - DELETE_COUNT.incrementAndGet(); - logStatement(StatementType.DELETE, statement); - } - - public static void select(String statement) { - SELECT_COUNT.incrementAndGet(); - logStatement(StatementType.SELECT, statement); - } - - public static void drop(String statement) { - DROP_COUNT.incrementAndGet(); - logStatement(StatementType.DROP, statement); - } - - public static void warn(String message, Object... args) { - WARN_COUNT.incrementAndGet(); - logStatement(StatementType.WARN, args.length > 0 ? MessageFormat.format(message, args) : message); - } - - private static void logStatement(final StatementType type, final String statement) { - for (final IciqlListener listener : LISTENERS) { - EXEC.execute(new Runnable() { - public void run() { - listener.logIciql(type, statement); - } - }); - } - } - - public static long getCreateCount() { - return CREATE_COUNT.longValue(); - } - - public static long getInsertCount() { - return INSERT_COUNT.longValue(); - } - - public static long getUpdateCount() { - return UPDATE_COUNT.longValue(); - } - - public static long getMergeCount() { - return MERGE_COUNT.longValue(); - } - - public static long getDeleteCount() { - return DELETE_COUNT.longValue(); - } - - public static long getSelectCount() { - return SELECT_COUNT.longValue(); - } - - public static long getDropCount() { - return DROP_COUNT.longValue(); - } - - public static long getWarnCount() { - return WARN_COUNT.longValue(); - } - - public static long getTotalCount() { - return getCreateCount() + getInsertCount() + getUpdateCount() + getDeleteCount() + getMergeCount() - + getSelectCount() + getDropCount(); - } - - public static void logStats() { - logStatement(StatementType.STAT, "iciql Runtime Statistics"); - logStatement(StatementType.STAT, "========================"); - logStat(StatementType.WARN, getWarnCount()); - logStatement(StatementType.STAT, "========================"); - logStat(StatementType.CREATE, getCreateCount()); - logStat(StatementType.INSERT, getInsertCount()); - logStat(StatementType.UPDATE, getUpdateCount()); - logStat(StatementType.MERGE, getMergeCount()); - logStat(StatementType.DELETE, getDeleteCount()); - logStat(StatementType.SELECT, getSelectCount()); - logStat(StatementType.DROP, getDropCount()); - logStatement(StatementType.STAT, "========================"); - logStat(StatementType.TOTAL, getTotalCount()); - } - - private static void logStat(StatementType type, long value) { - if (value > 0) { - DecimalFormat df = new DecimalFormat("###,###,###,###"); - logStatement(StatementType.STAT, - StringUtils.pad(type.name(), 6, " ", true) + " = " + df.format(value)); - } - } -}
\ No newline at end of file diff --git a/src/com/iciql/util/JdbcUtils.java b/src/com/iciql/util/JdbcUtils.java deleted file mode 100644 index 4a4a2b6..0000000 --- a/src/com/iciql/util/JdbcUtils.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.util; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Properties; - -import javax.naming.Context; -import javax.sql.DataSource; -import javax.sql.XAConnection; - -/** - * This is a utility class with JDBC helper functions. - */ -public class JdbcUtils { - - private static final String[] DRIVERS = { "h2:", "org.h2.Driver", "Cache:", - "com.intersys.jdbc.CacheDriver", "daffodilDB://", "in.co.daffodil.db.rmi.RmiDaffodilDBDriver", - "daffodil", "in.co.daffodil.db.jdbc.DaffodilDBDriver", "db2:", "COM.ibm.db2.jdbc.net.DB2Driver", - "derby:net:", "org.apache.derby.jdbc.ClientDriver", "derby://", - "org.apache.derby.jdbc.ClientDriver", "derby:", "org.apache.derby.jdbc.EmbeddedDriver", - "FrontBase:", "com.frontbase.jdbc.FBJDriver", "firebirdsql:", "org.firebirdsql.jdbc.FBDriver", - "hsqldb:", "org.hsqldb.jdbcDriver", "informix-sqli:", "com.informix.jdbc.IfxDriver", "jtds:", - "net.sourceforge.jtds.jdbc.Driver", "microsoft:", "com.microsoft.jdbc.sqlserver.SQLServerDriver", - "mimer:", "com.mimer.jdbc.Driver", "mysql:", "com.mysql.jdbc.Driver", "odbc:", - "sun.jdbc.odbc.JdbcOdbcDriver", "oracle:", "oracle.jdbc.driver.OracleDriver", "pervasive:", - "com.pervasive.jdbc.v2.Driver", "pointbase:micro:", "com.pointbase.me.jdbc.jdbcDriver", - "pointbase:", "com.pointbase.jdbc.jdbcUniversalDriver", "postgresql:", "org.postgresql.Driver", - "sybase:", "com.sybase.jdbc3.jdbc.SybDriver", "sqlserver:", - "com.microsoft.sqlserver.jdbc.SQLServerDriver", "teradata:", "com.ncr.teradata.TeraDriver", }; - - private JdbcUtils() { - // utility class - } - - /** - * Close a statement without throwing an exception. - * - * @param stat - * the statement or null - */ - public static void closeSilently(Statement stat) { - if (stat != null) { - try { - stat.close(); - } catch (SQLException e) { - // ignore - } - } - } - - /** - * Close a connection without throwing an exception. - * - * @param conn - * the connection or null - */ - public static void closeSilently(Connection conn) { - if (conn != null) { - try { - conn.close(); - } catch (SQLException e) { - // ignore - } - } - } - - /** - * Close a result set without throwing an exception. - * - * @param rs - * the result set or null - */ - public static void closeSilently(ResultSet rs) { - closeSilently(rs, false); - } - - /** - * Close a result set, and optionally its statement without throwing an - * exception. - * - * @param rs - * the result set or null - */ - public static void closeSilently(ResultSet rs, boolean closeStatement) { - if (rs != null) { - Statement stat = null; - if (closeStatement) { - try { - stat = rs.getStatement(); - } catch (SQLException e) { - // ignore - } - } - try { - rs.close(); - } catch (SQLException e) { - // ignore - } - closeSilently(stat); - } - } - - /** - * Close an XA connection set without throwing an exception. - * - * @param conn - * the XA connection or null - */ - public static void closeSilently(XAConnection conn) { - if (conn != null) { - try { - conn.close(); - } catch (SQLException e) { - // ignore - } - } - } - - /** - * Open a new database connection with the given settings. - * - * @param driver - * the driver class name - * @param url - * the database URL - * @param user - * the user name - * @param password - * the password - * @return the database connection - */ - public static Connection getConnection(String driver, String url, String user, String password) - throws SQLException { - Properties prop = new Properties(); - if (user != null) { - prop.setProperty("user", user); - } - if (password != null) { - prop.setProperty("password", password); - } - return getConnection(driver, url, prop); - } - - /** - * Escape table or schema patterns used for DatabaseMetaData functions. - * - * @param pattern - * the pattern - * @return the escaped pattern - */ - public static String escapeMetaDataPattern(String pattern) { - if (pattern == null || pattern.length() == 0) { - return pattern; - } - return StringUtils.replaceAll(pattern, "\\", "\\\\"); - } - - /** - * Open a new database connection with the given settings. - * - * @param driver - * the driver class name - * @param url - * the database URL - * @param prop - * the properties containing at least the user name and password - * @return the database connection - */ - public static Connection getConnection(String driver, String url, Properties prop) throws SQLException { - if (StringUtils.isNullOrEmpty(driver)) { - JdbcUtils.load(url); - } else { - Class<?> d = Utils.loadClass(driver); - if (java.sql.Driver.class.isAssignableFrom(d)) { - return DriverManager.getConnection(url, prop); - } else if (javax.naming.Context.class.isAssignableFrom(d)) { - // JNDI context - try { - Context context = (Context) d.newInstance(); - DataSource ds = (DataSource) context.lookup(url); - String user = prop.getProperty("user"); - String password = prop.getProperty("password"); - if (StringUtils.isNullOrEmpty(user) && StringUtils.isNullOrEmpty(password)) { - return ds.getConnection(); - } - return ds.getConnection(user, password); - } catch (SQLException e) { - throw e; - } catch (Exception e) { - throw new SQLException("Failed to get connection for " + url, e); - } - } else { - // Don't know, but maybe it loaded a JDBC Driver - return DriverManager.getConnection(url, prop); - } - } - return DriverManager.getConnection(url, prop); - } - - /** - * Get the driver class name for the given URL, or null if the URL is - * unknown. - * - * @param url - * the database URL - * @return the driver class name - */ - public static String getDriver(String url) { - if (url.startsWith("jdbc:")) { - url = url.substring("jdbc:".length()); - for (int i = 0; i < DRIVERS.length; i += 2) { - String prefix = DRIVERS[i]; - if (url.startsWith(prefix)) { - return DRIVERS[i + 1]; - } - } - } - return null; - } - - /** - * Load the driver class for the given URL, if the database URL is known. - * - * @param url - * the database URL - */ - public static void load(String url) { - String driver = getDriver(url); - if (driver != null) { - Utils.loadClass(driver); - } - } - -} diff --git a/src/com/iciql/util/Slf4jIciqlListener.java b/src/com/iciql/util/Slf4jIciqlListener.java deleted file mode 100644 index ded393f..0000000 --- a/src/com/iciql/util/Slf4jIciqlListener.java +++ /dev/null @@ -1,92 +0,0 @@ -/*
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql.util;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.iciql.Iciql;
-import com.iciql.util.IciqlLogger.IciqlListener;
-import com.iciql.util.IciqlLogger.StatementType;
-
-/**
- * Slf4jIciqlListener interfaces the IciqlLogger to the SLF4J logging framework.
- */
-public class Slf4jIciqlListener implements IciqlListener {
-
- private Logger logger = LoggerFactory.getLogger(Iciql.class);
-
- /**
- * Enumeration representing the SLF4J log levels.
- */
- public enum Level {
- ERROR, WARN, INFO, DEBUG, TRACE, OFF;
- }
-
- private final Level defaultLevel;
-
- private final Map<StatementType, Level> levels;
-
- public Slf4jIciqlListener() {
- this(Level.TRACE);
- }
-
- public Slf4jIciqlListener(Level defaultLevel) {
- this.defaultLevel = defaultLevel;
- levels = new HashMap<StatementType, Level>();
- for (StatementType type : StatementType.values()) {
- levels.put(type, defaultLevel);
- }
- }
-
- /**
- * Sets the logging level for a particular statement type.
- *
- * @param type
- * @param level
- */
- public void setLevel(StatementType type, Level level) {
- levels.put(type, defaultLevel);
- }
-
- @Override
- public void logIciql(StatementType type, String statement) {
- Level level = levels.get(type);
- switch (level) {
- case ERROR:
- logger.error(statement);
- break;
- case WARN:
- logger.warn(statement);
- break;
- case INFO:
- logger.info(statement);
- break;
- case DEBUG:
- logger.debug(statement);
- break;
- case TRACE:
- logger.trace(statement);
- break;
- case OFF:
- break;
- }
- }
-}
diff --git a/src/com/iciql/util/StatementBuilder.java b/src/com/iciql/util/StatementBuilder.java deleted file mode 100644 index 47e8054..0000000 --- a/src/com/iciql/util/StatementBuilder.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.util; - -/** - * A utility class to build a statement. In addition to the methods supported by - * StringBuilder, it allows to add a text only in the second iteration. This - * simplified constructs such as: - * - * <pre> - * StringBuilder buff = new StringBuilder(); - * for (int i = 0; i < args.length; i++) { - * if (i > 0) { - * buff.append(", "); - * } - * buff.append(args[i]); - * } - * </pre> - * - * to - * - * <pre> - * StatementBuilder buff = new StatementBuilder(); - * for (String s : args) { - * buff.appendExceptFirst(", "); - * buff.append(a); - * } - * </pre> - */ -public class StatementBuilder { - - private final StringBuilder builder = new StringBuilder(); - private int index; - - /** - * Create a new builder. - */ - public StatementBuilder() { - // nothing to do - } - - /** - * Create a new builder. - * - * @param string - * the initial string - */ - public StatementBuilder(String string) { - builder.append(string); - } - - /** - * Append a text. - * - * @param s - * the text to append - * @return itself - */ - public StatementBuilder append(String s) { - builder.append(s); - return this; - } - - /** - * Append a character. - * - * @param c - * the character to append - * @return itself - */ - public StatementBuilder append(char c) { - builder.append(c); - return this; - } - - /** - * Append a number. - * - * @param x - * the number to append - * @return itself - */ - public StatementBuilder append(long x) { - builder.append(x); - return this; - } - - /** - * Returns the current value of the loop counter. - * - * @return the loop counter - */ - public int getCount() { - return index; - } - - /** - * Reset the loop counter. - * - * @return itself - */ - public StatementBuilder resetCount() { - index = 0; - return this; - } - - /** - * Append a text, but only if appendExceptFirst was never called. - * - * @param s - * the text to append - */ - public void appendOnlyFirst(String s) { - if (index == 0) { - builder.append(s); - } - } - - /** - * Append a text, except when this method is called the first time. - * - * @param s - * the text to append - */ - public void appendExceptFirst(String s) { - if (index++ > 0) { - builder.append(s); - } - } - - public void append(StatementBuilder sb) { - builder.append(sb); - } - - public void insert(int offset, char c) { - builder.insert(offset, c); - } - - public String toString() { - return builder.toString(); - } - - /** - * Get the length. - * - * @return the length - */ - public int length() { - return builder.length(); - } -} diff --git a/src/com/iciql/util/StringUtils.java b/src/com/iciql/util/StringUtils.java deleted file mode 100644 index dd3f180..0000000 --- a/src/com/iciql/util/StringUtils.java +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. - * Copyright 2011 James Moger. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.iciql.util; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; - -/** - * Common string utilities. - * - */ -public class StringUtils { - - /** - * Replace all occurrences of the before string with the after string. - * - * @param s - * the string - * @param before - * the old text - * @param after - * the new text - * @return the string with the before string replaced - */ - public static String replaceAll(String s, String before, String after) { - int next = s.indexOf(before); - if (next < 0) { - return s; - } - StringBuilder buff = new StringBuilder(s.length() - before.length() + after.length()); - int index = 0; - while (true) { - buff.append(s.substring(index, next)).append(after); - index = next + before.length(); - next = s.indexOf(before, index); - if (next < 0) { - buff.append(s.substring(index)); - break; - } - } - return buff.toString(); - } - - /** - * Check if a String is null or empty (the length is null). - * - * @param s - * the string to check - * @return true if it is null or empty - */ - public static boolean isNullOrEmpty(String s) { - return s == null || s.length() == 0; - } - - /** - * Convert a string to a Java literal using the correct escape sequences. - * The literal is not enclosed in double quotes. The result can be used in - * properties files or in Java source code. - * - * @param s - * the text to convert - * @return the Java representation - */ - public static String javaEncode(String s) { - int length = s.length(); - StringBuilder buff = new StringBuilder(length); - for (int i = 0; i < length; i++) { - char c = s.charAt(i); - switch (c) { - // case '\b': - // // BS backspace - // // not supported in properties files - // buff.append("\\b"); - // break; - case '\t': - // HT horizontal tab - buff.append("\\t"); - break; - case '\n': - // LF linefeed - buff.append("\\n"); - break; - case '\f': - // FF form feed - buff.append("\\f"); - break; - case '\r': - // CR carriage return - buff.append("\\r"); - break; - case '"': - // double quote - buff.append("\\\""); - break; - case '\\': - // backslash - buff.append("\\\\"); - break; - default: - int ch = c & 0xffff; - if (ch >= ' ' && (ch < 0x80)) { - buff.append(c); - // not supported in properties files - // } else if(ch < 0xff) { - // buff.append("\\"); - // // make sure it's three characters (0x200 is octal 1000) - // buff.append(Integer.toOctalString(0x200 | - // ch).substring(1)); - } else { - buff.append("\\u"); - // make sure it's four characters - buff.append(Integer.toHexString(0x10000 | ch).substring(1)); - } - } - } - return buff.toString(); - } - - /** - * Pad a string. This method is used for the SQL function RPAD and LPAD. - * - * @param string - * the original string - * @param n - * the target length - * @param padding - * the padding string - * @param right - * true if the padding should be appended at the end - * @return the padded string - */ - public static String pad(String string, int n, String padding, boolean right) { - if (n < 0) { - n = 0; - } - if (n < string.length()) { - return string.substring(0, n); - } else if (n == string.length()) { - return string; - } - char paddingChar; - if (padding == null || padding.length() == 0) { - paddingChar = ' '; - } else { - paddingChar = padding.charAt(0); - } - StringBuilder buff = new StringBuilder(n); - n -= string.length(); - if (right) { - buff.append(string); - } - for (int i = 0; i < n; i++) { - buff.append(paddingChar); - } - if (!right) { - buff.append(string); - } - return buff.toString(); - } - - /** - * Convert a string to a SQL literal. Null is converted to NULL. The text is - * enclosed in single quotes. If there are any special characters, the - * method STRINGDECODE is used. - * - * @param s - * the text to convert. - * @return the SQL literal - */ - public static String quoteStringSQL(String s) { - if (s == null) { - return "NULL"; - } - int length = s.length(); - StringBuilder buff = new StringBuilder(length + 2); - buff.append('\''); - for (int i = 0; i < length; i++) { - char c = s.charAt(i); - if (c == '\'') { - buff.append(c); - } else if (c < ' ' || c > 127) { - // need to start from the beginning because maybe there was a \ - // that was not quoted - return "STRINGDECODE(" + quoteStringSQL(javaEncode(s)) + ")"; - } - buff.append(c); - } - buff.append('\''); - return buff.toString(); - } - - /** - * Split a string into an array of strings using the given separator. A null - * string will result in a null array, and an empty string in a zero element - * array. - * - * @param s - * the string to split - * @param separatorChar - * the separator character - * @param trim - * whether each element should be trimmed - * @return the array list - */ - public static String[] arraySplit(String s, char separatorChar, boolean trim) { - if (s == null) { - return null; - } - int length = s.length(); - if (length == 0) { - return new String[0]; - } - ArrayList<String> list = Utils.newArrayList(); - StringBuilder buff = new StringBuilder(length); - for (int i = 0; i < length; i++) { - char c = s.charAt(i); - if (c == separatorChar) { - String e = buff.toString(); - list.add(trim ? e.trim() : e); - buff.setLength(0); - } else if (c == '\\' && i < length - 1) { - buff.append(s.charAt(++i)); - } else { - buff.append(c); - } - } - String e = buff.toString(); - list.add(trim ? e.trim() : e); - String[] array = new String[list.size()]; - list.toArray(array); - return array; - } - - /** - * Calculates the SHA1 of the string. - * - * @param text - * @return sha1 of the string - */ - public static String calculateSHA1(String text) { - try { - byte[] bytes = text.getBytes("iso-8859-1"); - return calculateSHA1(bytes); - } catch (UnsupportedEncodingException u) { - throw new RuntimeException(u); - } - } - - /** - * Calculates the SHA1 of the byte array. - * - * @param bytes - * @return sha1 of the byte array - */ - public static String calculateSHA1(byte[] bytes) { - try { - MessageDigest md = MessageDigest.getInstance("SHA-1"); - md.update(bytes, 0, bytes.length); - byte[] digest = md.digest(); - StringBuilder sb = new StringBuilder(digest.length * 2); - for (int i = 0; i < digest.length; i++) { - if (((int) digest[i] & 0xff) < 0x10) { - sb.append('0'); - } - sb.append(Integer.toHexString((int) digest[i] & 0xff)); - } - return sb.toString(); - } catch (NoSuchAlgorithmException t) { - throw new RuntimeException(t); - } - } - - /** - * Counts the occurrences of char c in the given string. - * - * @param c - * the character to count - * @param value - * the source string - * @return the count of c in value - */ - public static int count(char c, String value) { - int count = 0; - for (char cv : value.toCharArray()) { - if (cv == c) { - count++; - } - } - return count; - } - - /** - * Prepare text for html presentation. Replace sensitive characters with - * html entities. - * - * @param inStr - * @param changeSpace - * @return plain text escaped for html - */ - public static String escapeForHtml(String inStr, boolean changeSpace) { - StringBuffer retStr = new StringBuffer(); - int i = 0; - while (i < inStr.length()) { - if (inStr.charAt(i) == '&') { - retStr.append("&"); - } else if (inStr.charAt(i) == '<') { - retStr.append("<"); - } else if (inStr.charAt(i) == '>') { - retStr.append(">"); - } else if (inStr.charAt(i) == '\"') { - retStr.append("""); - } else if (changeSpace && inStr.charAt(i) == ' ') { - retStr.append(" "); - } else if (changeSpace && inStr.charAt(i) == '\t') { - retStr.append(" "); - } else { - retStr.append(inStr.charAt(i)); - } - i++; - } - return retStr.toString(); - } - - /** - * Replaces carriage returns and line feeds with html line breaks. - * - * @param string - * @return plain text with html line breaks - */ - public static String breakLinesForHtml(String string) { - return string.replace("\r\n", "<br/>").replace("\r", "<br/>").replace("\n", "<br/>"); - } - - /** - * Returns the string content of the specified file. - * - * @param file - * @param lineEnding - * @return the string content of the file - */ - public static String readContent(File file, String lineEnding) { - StringBuilder sb = new StringBuilder(); - try { - InputStreamReader is = new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")); - BufferedReader reader = new BufferedReader(is); - String line = null; - while ((line = reader.readLine()) != null) { - sb.append(line); - if (lineEnding != null) { - sb.append(lineEnding); - } - } - reader.close(); - } catch (Throwable t) { - System.err.println("Failed to read content of " + file.getAbsolutePath()); - t.printStackTrace(); - } - return sb.toString(); - } -} diff --git a/src/com/iciql/util/Utils.java b/src/com/iciql/util/Utils.java deleted file mode 100644 index 77110b8..0000000 --- a/src/com/iciql/util/Utils.java +++ /dev/null @@ -1,459 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql.util;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.lang.reflect.Constructor;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-
-import com.iciql.Iciql.EnumId;
-import com.iciql.Iciql.EnumType;
-import com.iciql.IciqlException;
-
-/**
- * Generic utility methods.
- */
-public class Utils {
-
- public static final AtomicLong COUNTER = new AtomicLong(0);
-
- public static final AtomicInteger AS_COUNTER = new AtomicInteger(0);
-
- private static final boolean MAKE_ACCESSIBLE = true;
-
- private static final int BUFFER_BLOCK_SIZE = 4 * 1024;
-
- public static synchronized int nextAsCount() {
- // prevent negative values and use a threadsafe counter
- int count = AS_COUNTER.incrementAndGet();
- if (count == Integer.MAX_VALUE) {
- count = 0;
- AS_COUNTER.set(count);
- }
- return count;
- }
-
- @SuppressWarnings("unchecked")
- public static <X> Class<X> getClass(X x) {
- return (Class<X>) x.getClass();
- }
-
- public static Class<?> loadClass(String className) {
- try {
- return Class.forName(className);
- } catch (Exception e) {
- throw new IciqlException(e);
- }
- }
-
- public static <T> ArrayList<T> newArrayList() {
- return new ArrayList<T>();
- }
-
- public static <T> ArrayList<T> newArrayList(Collection<T> c) {
- return new ArrayList<T>(c);
- }
-
- public static <T> HashSet<T> newHashSet() {
- return new HashSet<T>();
- }
-
- public static <T> HashSet<T> newHashSet(Collection<T> list) {
- return new HashSet<T>(list);
- }
-
- 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> IdentityHashMap<A, B> newIdentityHashMap() {
- return new IdentityHashMap<A, B>();
- }
-
- public static <T> ThreadLocal<T> newThreadLocal(final Class<? extends T> clazz) {
- return new ThreadLocal<T>() {
- @SuppressWarnings("rawtypes")
- @Override
- protected T initialValue() {
- 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
- }
- }
- }
- }
- throw new IciqlException(e,
- "Missing default constructor? Exception trying to instantiate {0}: {1}",
- clazz.getName(), e.getMessage());
- }
- }
- };
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public static <T> T newObject(Class<T> clazz) {
- // must create new instances
- if (clazz == int.class || clazz == Integer.class) {
- return (T) new Integer((int) COUNTER.getAndIncrement());
- } else if (clazz == String.class) {
- return (T) ("" + COUNTER.getAndIncrement());
- } else if (clazz == long.class || clazz == Long.class) {
- return (T) new Long(COUNTER.getAndIncrement());
- } else if (clazz == short.class || clazz == Short.class) {
- return (T) new Short((short) COUNTER.getAndIncrement());
- } else if (clazz == byte.class || clazz == Byte.class) {
- return (T) new Byte((byte) COUNTER.getAndIncrement());
- } else if (clazz == float.class || clazz == Float.class) {
- return (T) new Float(COUNTER.getAndIncrement());
- } else if (clazz == double.class || clazz == Double.class) {
- return (T) new Double(COUNTER.getAndIncrement());
- } else if (clazz == boolean.class || clazz == Boolean.class) {
- COUNTER.getAndIncrement();
- return (T) new Boolean(false);
- } else if (clazz == BigDecimal.class) {
- return (T) new BigDecimal(COUNTER.getAndIncrement());
- } else if (clazz == BigInteger.class) {
- return (T) new BigInteger("" + COUNTER.getAndIncrement());
- } else if (clazz == java.sql.Date.class) {
- return (T) new java.sql.Date(COUNTER.getAndIncrement());
- } else if (clazz == java.sql.Time.class) {
- return (T) new java.sql.Time(COUNTER.getAndIncrement());
- } else if (clazz == java.sql.Timestamp.class) {
- return (T) new java.sql.Timestamp(COUNTER.getAndIncrement());
- } else if (clazz == java.util.Date.class) {
- return (T) new java.util.Date(COUNTER.getAndIncrement());
- } else if (clazz == byte[].class) {
- COUNTER.getAndIncrement();
- return (T) new byte[0];
- } else if (clazz.isEnum()) {
- COUNTER.getAndIncrement();
- // enums can not be instantiated reflectively
- // return first constant as reference
- return clazz.getEnumConstants()[0];
- } else if (clazz == java.util.UUID.class) {
- COUNTER.getAndIncrement();
- return (T) UUID.randomUUID();
- }
- 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 IciqlException(e,
- "Missing default constructor?! Exception trying to instantiate {0}: {1}",
- clazz.getName(), e.getMessage());
- }
- }
-
- public static <T> boolean isSimpleType(Class<T> clazz) {
- if (Number.class.isAssignableFrom(clazz)) {
- return true;
- } else if (clazz == String.class) {
- return true;
- }
- return false;
- }
-
- public static Object convert(Object o, Class<?> targetType) {
- if (o == null) {
- return null;
- }
- Class<?> currentType = o.getClass();
- if (targetType.isAssignableFrom(currentType)) {
- return o;
- }
-
- // convert from CLOB/TEXT/VARCHAR to String
- if (targetType == String.class) {
- if (Clob.class.isAssignableFrom(currentType)) {
- Clob c = (Clob) o;
- try {
- Reader r = c.getCharacterStream();
- return readStringAndClose(r, -1);
- } catch (Exception e) {
- throw new IciqlException(e, "error converting CLOB to String: ", e.toString());
- }
- }
- return o.toString();
- }
-
- if (Boolean.class.isAssignableFrom(targetType) || boolean.class.isAssignableFrom(targetType)) {
- // convert from number to boolean
- if (Number.class.isAssignableFrom(currentType)) {
- Number n = (Number) o;
- return n.intValue() > 0;
- }
- // convert from string to boolean
- if (String.class.isAssignableFrom(currentType)) {
- String s = o.toString().toLowerCase();
- float f = 0f;
- try {
- f = Float.parseFloat(s);
- } catch (Exception e) {
- }
- return f > 0 || s.equals("true") || s.equals("yes") || s.equals("y") || s.equals("on");
- }
- }
-
- // convert from boolean to number
- if (Boolean.class.isAssignableFrom(currentType)) {
- Boolean b = (Boolean) o;
- if (Number.class.isAssignableFrom(targetType)) {
- return b ? 1 : 0;
- }
- if (boolean.class.isAssignableFrom(targetType)) {
- return b.booleanValue();
- }
- }
-
- // convert from number to number
- if (Number.class.isAssignableFrom(currentType)) {
- Number n = (Number) o;
- if (targetType == byte.class || targetType == Byte.class) {
- return n.byteValue();
- } else if (targetType == short.class || targetType == Short.class) {
- return n.shortValue();
- } else if (targetType == int.class || targetType == Integer.class) {
- return n.intValue();
- } else if (targetType == long.class || targetType == Long.class) {
- return n.longValue();
- } else if (targetType == double.class || targetType == Double.class) {
- return n.doubleValue();
- } else if (targetType == float.class || targetType == Float.class) {
- return n.floatValue();
- }
- }
-
- // convert from BLOB
- if (targetType == byte[].class) {
- if (Blob.class.isAssignableFrom(currentType)) {
- Blob b = (Blob) o;
- try {
- InputStream is = b.getBinaryStream();
- return readBlobAndClose(is, -1);
- } catch (Exception e) {
- throw new IciqlException(e, "error converting BLOB to byte[]: ", e.toString());
- }
- }
- }
- throw new IciqlException("Can not convert the value {0} from {1} to {2}", o, currentType, targetType);
- }
-
- public static Object convertEnum(Enum<?> o, EnumType type) {
- if (o == null) {
- return null;
- }
- switch (type) {
- case ORDINAL:
- return o.ordinal();
- case ENUMID:
- if (!EnumId.class.isAssignableFrom(o.getClass())) {
- throw new IciqlException("Can not convert the enum {0} using ENUMID", o);
- }
- EnumId enumid = (EnumId) o;
- return enumid.enumId();
- case NAME:
- default:
- return o.name();
- }
- }
-
- public static Object convertEnum(Object o, Class<?> targetType, EnumType type) {
- if (o == null) {
- return null;
- }
- Class<?> currentType = o.getClass();
- if (targetType.isAssignableFrom(currentType)) {
- return o;
- }
- // convert from VARCHAR/TEXT/INT to Enum
- Enum<?>[] values = (Enum[]) targetType.getEnumConstants();
- if (Clob.class.isAssignableFrom(currentType)) {
- // TEXT/CLOB field
- Clob c = (Clob) o;
- String name = null;
- try {
- Reader r = c.getCharacterStream();
- name = readStringAndClose(r, -1);
- } catch (Exception e) {
- throw new IciqlException(e, "error converting CLOB to String: ", e.toString());
- }
-
- // find name match
- for (Enum<?> value : values) {
- if (value.name().equalsIgnoreCase(name)) {
- return value;
- }
- }
- } else if (String.class.isAssignableFrom(currentType)) {
- // VARCHAR field
- String name = (String) o;
- for (Enum<?> value : values) {
- if (value.name().equalsIgnoreCase(name)) {
- return value;
- }
- }
- } else if (Number.class.isAssignableFrom(currentType)) {
- // INT field
- int n = ((Number) o).intValue();
- if (type.equals(EnumType.ORDINAL)) {
- // ORDINAL mapping
- for (Enum<?> value : values) {
- if (value.ordinal() == n) {
- return value;
- }
- }
- } else if (type.equals(EnumType.ENUMID)) {
- if (!EnumId.class.isAssignableFrom(targetType)) {
- throw new IciqlException("Can not convert the value {0} from {1} to {2} using ENUMID", o,
- currentType, targetType);
- }
- // ENUMID mapping
- for (Enum<?> value : values) {
- EnumId enumid = (EnumId) value;
- if (enumid.enumId() == n) {
- return value;
- }
- }
- }
- }
- throw new IciqlException("Can not convert the value {0} from {1} to {2}", o, currentType, targetType);
- }
-
- /**
- * Read a number of characters from a reader and close it.
- *
- * @param in
- * the reader
- * @param length
- * the maximum number of characters to read, or -1 to read until
- * the end of file
- * @return the string read
- */
- public static String readStringAndClose(Reader in, int length) throws IOException {
- try {
- if (length <= 0) {
- length = Integer.MAX_VALUE;
- }
- int block = Math.min(BUFFER_BLOCK_SIZE, length);
- StringWriter out = new StringWriter(length == Integer.MAX_VALUE ? block : length);
- char[] buff = new char[block];
- while (length > 0) {
- int len = Math.min(block, length);
- len = in.read(buff, 0, len);
- if (len < 0) {
- break;
- }
- out.write(buff, 0, len);
- length -= len;
- }
- return out.toString();
- } finally {
- in.close();
- }
- }
-
- /**
- * Read a number of bytes from a stream and close it.
- *
- * @param in
- * the stream
- * @param length
- * the maximum number of bytes to read, or -1 to read until the
- * end of file
- * @return the string read
- */
- public static byte[] readBlobAndClose(InputStream in, int length) throws IOException {
- try {
- if (length <= 0) {
- length = Integer.MAX_VALUE;
- }
- int block = Math.min(BUFFER_BLOCK_SIZE, length);
- ByteArrayOutputStream out = new ByteArrayOutputStream(length == Integer.MAX_VALUE ? block
- : length);
- byte[] buff = new byte[block];
- while (length > 0) {
- int len = Math.min(block, length);
- len = in.read(buff, 0, len);
- if (len < 0) {
- break;
- }
- out.write(buff, 0, len);
- length -= len;
- }
- return out.toByteArray();
- } finally {
- in.close();
- }
- }
-}
diff --git a/src/com/iciql/util/WeakIdentityHashMap.java b/src/com/iciql/util/WeakIdentityHashMap.java deleted file mode 100644 index bc03cd0..0000000 --- a/src/com/iciql/util/WeakIdentityHashMap.java +++ /dev/null @@ -1,243 +0,0 @@ -/*
- * Copyright 2004-2011 H2 Group.
- * Copyright 2011 James Moger.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql.util;
-
-import java.lang.ref.WeakReference;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-
-import com.iciql.IciqlException;
-
-/**
- * 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. The garbage collection happens when trying to add new data,
- * or when resizing.
- *
- * @param <K>
- * the keys
- * @param <V>
- * the value
- */
-
-public class WeakIdentityHashMap<K, V> implements Map<K, V> {
-
- private static final int MAX_LOAD = 90;
- private static final WeakReference<Object> DELETED_KEY = new WeakReference<Object>(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;
- }
-
- @SuppressWarnings("unchecked")
- 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 IciqlException("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;
- }
-
- @SuppressWarnings("unchecked")
- private void delete(int index) {
- keys[index] = (WeakReference<K>) 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();
- }
-
-}
diff --git a/src/com/iciql/util/package.html b/src/com/iciql/util/package.html deleted file mode 100644 index 3d24dee..0000000 --- a/src/com/iciql/util/package.html +++ /dev/null @@ -1,25 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<!--
- Copyright 2004-2011 H2 Group.
- Copyright 2011 James Moger.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<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>
-Utility classes for iciql.
-</body>
-</html>
\ No newline at end of file |