diff options
author | James Moger <james.moger@gmail.com> | 2011-08-16 15:32:56 -0400 |
---|---|---|
committer | James Moger <james.moger@gmail.com> | 2011-08-16 15:32:56 -0400 |
commit | d95e16170d063c0b74d04e6636e8fddbfa120689 (patch) | |
tree | a8157992ef14cb8f4392b847fbc8892cb30245d5 | |
parent | 8193609af00aa9529ed7b3090b5739c4e95b12c4 (diff) | |
download | iciql-d95e16170d063c0b74d04e6636e8fddbfa120689.tar.gz iciql-d95e16170d063c0b74d04e6636e8fddbfa120689.zip |
Finished MySQL dialect; v5.0.51b 100% tested. Added Db.dropTable(T)
25 files changed, 477 insertions, 192 deletions
@@ -26,6 +26,7 @@ </classpathentry>
<classpathentry kind="lib" path="ext/hsqldb-2.2.4.jar"/>
<classpathentry kind="lib" path="ext/derby-10.8.1.2.jar"/>
+ <classpathentry kind="lib" path="ext/mysql-connector-java-5.1.15.jar"/>
<classpathentry kind="lib" path="ext/h2-1.3.159.jar" sourcepath="ext/h2-1.3.159-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/iciql/ext/h2-1.3.159-javadoc.jar!/"/>
diff --git a/README.markdown b/README.markdown index 6c4f5e2..28aa424 100644 --- a/README.markdown +++ b/README.markdown @@ -20,12 +20,9 @@ Supported Databases (Unit-Tested) - [H2](http://h2database.com) 1.3.159
- [HSQLDB](http://hsqldb.org) 2.2.4
- [Derby](http://db.apache.org/derby) 10.7.1.1 & 10.8.1.2
+- [MySQL](http://mysql.com) 5.0.51b
-Partially Supported Databases (not Unit-Tested)
--------
-- [MySQL](http://mysql.com)
-
-Support for others is planned and may only require creating a simple "dialect" class.
+Support for others is possible and may only require creating a simple "dialect" class.
License
-------
diff --git a/docs/00_index.mkd b/docs/00_index.mkd index b3e8cbf..daf9c42 100644 --- a/docs/00_index.mkd +++ b/docs/00_index.mkd @@ -39,11 +39,9 @@ select * from products - [H2](http://h2database.com) 1.3.159
- [HSQLDB](http://hsqldb.org) 2.2.4
- [Derby](http://db.apache.org/derby) 10.7.1.1 & 10.8.1.2
+- [MySQL](http://mysql.com) 5.0.51b
-### Partially Supported Databases (not Unit-Tested)
-- [MySQL](http://mysql.com)
-
-Support for others is planned and may only require creating a simple "dialect" class.
+Support for others is possible and may only require creating a simple "dialect" class.
### Java Runtime Requirement
diff --git a/docs/03_performance.mkd b/docs/03_performance.mkd index a8922b7..7df050a 100644 --- a/docs/03_performance.mkd +++ b/docs/03_performance.mkd @@ -9,7 +9,7 @@ Performance of iciql statement generation is not currently benchmarked. ### iciql+database performance comparison
-The following data was generated by running the iciql test suite. The suite is almost completely single-threaded. All databases are run in embedded *memory-only* mode through a JDBC connection. Since the suite is running in memory-only mode, disk IO bottlenecks should be removed from the equation and the results should be measuring raw statement processing.
+The following data was generated by running the iciql test suite. The suite is almost completely single-threaded. All Java databases are run in embedded *memory-only* mode through a JDBC connection.
<pre>
%DBPERFORMANCE%
diff --git a/docs/05_releases.mkd b/docs/05_releases.mkd index 91ef18f..8e0dfd6 100644 --- a/docs/05_releases.mkd +++ b/docs/05_releases.mkd @@ -6,13 +6,18 @@ **%VERSION%** ([zip](http://code.google.com/p/iciql/downloads/detail?name=%ZIP%)|[jar](http://code.google.com/p/iciql/downloads/detail?name=%JAR%)) *released %BUILDDATE%*
-- Disabled 2 concurrency unit tests since I believe they are flawed and do not yield reproducible results
+- Finished MySQL dialect implementation. MySQL 5.0.51b passes 100% of tests.
+- Added Db.dropTable(T) method
+
+### Older Releases
+
+**0.6.6** *released 2011-08-15*
+
+- Disabled two concurrency unit tests since I believe they are flawed and do not yield reproducible results
- Added Derby database dialect. Derby 10.7.1.1 and 10.8.1.2 pass 100% of tests.
- Implemented HSQL MERGE syntax. HSQL 2.2.4 fails 1 test which is a known [bug in HSQL](https://sourceforge.net/tracker/?func=detail&aid=3390047&group_id=23316&atid=378131)
- Updated to H2 1.3.159
-### Older Releases
-
**0.6.5** *released 2011-08-12*
- fixed failure of db.delete(PrimitiveModel) and db.update(PrimitiveModel)
diff --git a/src/com/iciql/Db.java b/src/com/iciql/Db.java index bb087e4..09c26a1 100644 --- a/src/com/iciql/Db.java +++ b/src/com/iciql/Db.java @@ -38,6 +38,7 @@ import com.iciql.DbUpgrader.DefaultDbUpgrader; import com.iciql.Iciql.IQTable;
import com.iciql.Iciql.IQVersion;
import com.iciql.util.JdbcUtils;
+import com.iciql.util.StatementLogger;
import com.iciql.util.StringUtils;
import com.iciql.util.Utils;
import com.iciql.util.WeakIdentityHashMap;
@@ -180,7 +181,10 @@ public class Db { public <T> void insert(T t) {
Class<?> clazz = t.getClass();
- define(clazz).createTableIfRequired(this).insert(this, t, false);
+ long rc = define(clazz).createTableIfRequired(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) {
@@ -236,6 +240,26 @@ public class Db { }
@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);
+ StatementLogger.drop(stat.getSQL());
+ int rc = 0;
+ try {
+ rc = stat.executeUpdate();
+ } catch (IciqlException e) {
+ if (e.getIciqlCode() != IciqlException.CODE_SCHEMA_NOT_FOUND
+ && e.getIciqlCode() != IciqlException.CODE_TABLE_NOT_FOUND) {
+ throw e;
+ }
+ }
+ // remove this model class from the table definition cache
+ classMap.remove(modelClass);
+ return rc;
+ }
+
+ @SuppressWarnings("unchecked")
public <T> List<T> buildObjects(Class<? extends T> modelClass, ResultSet rs) {
List<T> result = new ArrayList<T>();
TableDefinition<T> def = (TableDefinition<T>) define(modelClass);
@@ -259,14 +283,18 @@ public class Db { IQVersion model = dbUpgrader.getClass().getAnnotation(IQVersion.class);
if (model.value() > 0) {
DbVersion v = new DbVersion();
- DbVersion dbVersion =
// (SCHEMA="" && TABLE="") == DATABASE
- from(v).where(v.schemaName).is("").and(v.tableName).is("").selectFirst();
+ 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());
- insert(newDb);
+ // 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.
@@ -293,8 +321,8 @@ public class Db { // 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).like(schema).and(v.tableName)
- .like(model.tableName).selectFirst();
+ 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
@@ -348,7 +376,7 @@ public class Db { upgradeChecked.clear();
}
- SQLDialect getDialect() {
+ public SQLDialect getDialect() {
return dialect;
}
diff --git a/src/com/iciql/IciqlException.java b/src/com/iciql/IciqlException.java index 7d6f152..524d184 100644 --- a/src/com/iciql/IciqlException.java +++ b/src/com/iciql/IciqlException.java @@ -27,9 +27,10 @@ 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_TABLE_NOT_FOUND = 3;
- public static final int CODE_TABLE_ALREADY_EXISTS = 4;
- public static final int CODE_INDEX_ALREADY_EXISTS = 5;
+ public static final int CODE_SCHEMA_NOT_FOUND = 3;
+ public static final int CODE_TABLE_NOT_FOUND = 4;
+ public static final int CODE_TABLE_ALREADY_EXISTS = 5;
+ public static final int CODE_INDEX_ALREADY_EXISTS = 6;
private static final String TOKEN_UNMAPPED_FIELD = "\\? (=|\\>|\\<|\\<\\>|!=|\\>=|\\<=|LIKE|BETWEEN) \\?";
@@ -95,8 +96,17 @@ public class IciqlException extends RuntimeException { // http://developer.mimer.com/documentation/html_92/Mimer_SQL_Mobile_DocSet/App_Return_Codes2.html
SQLException s = (SQLException) t;
String state = s.getSQLState();
- if ("23505".equals(state)) {
+ if ("23000".equals(state)) {
+ // MySQL
iciqlCode = CODE_DUPLICATE_KEY;
+ } else if ("23505".equals(state)) {
+ iciqlCode = CODE_DUPLICATE_KEY;
+ } else if ("42000".equals(state)) {
+ // MySQL
+ iciqlCode = CODE_DUPLICATE_KEY;
+ } else if ("42Y07".equals(state)) {
+ // Derby
+ iciqlCode = CODE_SCHEMA_NOT_FOUND;
} else if ("42X05".equals(state)) {
// Derby
iciqlCode = CODE_TABLE_NOT_FOUND;
diff --git a/src/com/iciql/SQLDialect.java b/src/com/iciql/SQLDialect.java index 97d9fe9..6e6be25 100644 --- a/src/com/iciql/SQLDialect.java +++ b/src/com/iciql/SQLDialect.java @@ -36,6 +36,14 @@ public interface SQLDialect { 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 @@ -64,6 +72,14 @@ public interface SQLDialect { <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 INDEX statement. * * @param schemaName diff --git a/src/com/iciql/SQLDialectDefault.java b/src/com/iciql/SQLDialectDefault.java index 69502c3..0b611e0 100644 --- a/src/com/iciql/SQLDialectDefault.java +++ b/src/com/iciql/SQLDialectDefault.java @@ -57,7 +57,8 @@ public class SQLDialectDefault implements SQLDialect { * @param sqlType
* @return the SQL type or a preferred alternative
*/
- protected String convertSqlType(String sqlType) {
+ @Override
+ public String convertSqlType(String sqlType) {
return sqlType;
}
@@ -95,6 +96,14 @@ public class SQLDialectDefault implements SQLDialect { }
@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;
+ }
+
+ @Override
public <T> void prepareCreateTable(SQLStatement stat, TableDefinition<T> def) {
StatementBuilder buff;
if (def.memoryTable && supportsMemoryTables()) {
diff --git a/src/com/iciql/SQLDialectDerby.java b/src/com/iciql/SQLDialectDerby.java index 42f8cfd..019c285 100644 --- a/src/com/iciql/SQLDialectDerby.java +++ b/src/com/iciql/SQLDialectDerby.java @@ -33,7 +33,7 @@ public class SQLDialectDerby extends SQLDialectDefault { }
@Override
- protected String convertSqlType(String sqlType) {
+ public String convertSqlType(String sqlType) {
if ("TINYINT".equals(sqlType)) {
// Derby does not have a TINYINT/BYTE type
return "SMALLINT";
@@ -82,6 +82,14 @@ public class SQLDialectDerby extends SQLDialectDefault { }
@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;
+ }
+
+ @Override
public void prepareCreateIndex(SQLStatement stat, String schema, String table, IndexDefinition index) {
StatementBuilder buff = new StatementBuilder();
buff.append("CREATE ");
diff --git a/src/com/iciql/SQLDialectMySQL.java b/src/com/iciql/SQLDialectMySQL.java index a6c1218..1c1674a 100644 --- a/src/com/iciql/SQLDialectMySQL.java +++ b/src/com/iciql/SQLDialectMySQL.java @@ -16,6 +16,7 @@ package com.iciql;
+import com.iciql.TableDefinition.FieldDefinition;
import com.iciql.TableDefinition.IndexDefinition;
import com.iciql.util.StatementBuilder;
@@ -25,7 +26,7 @@ import com.iciql.util.StatementBuilder; public class SQLDialectMySQL extends SQLDialectDefault {
@Override
- protected String convertSqlType(String sqlType) {
+ public String convertSqlType(String sqlType) {
if (sqlType.equals("CLOB")) {
return "TEXT";
}
@@ -75,16 +76,36 @@ public class SQLDialectMySQL extends SQLDialectDefault { buff.append(prepareColumnName(col));
}
buff.append(") ");
+ stat.setSQL(buff.toString().trim());
+ }
- // USING
- switch (index.type) {
- case HASH:
- buff.append("USING HASH");
- break;
- case UNIQUE_HASH:
- buff.append("USING HASH");
- break;
+ @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);
}
- stat.setSQL(buff.toString().trim());
+ 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/TableDefinition.java b/src/com/iciql/TableDefinition.java index 4d9fec2..251f098 100644 --- a/src/com/iciql/TableDefinition.java +++ b/src/com/iciql/TableDefinition.java @@ -573,7 +573,8 @@ public class TableDefinition<T> { try {
stat.executeUpdate();
} catch (IciqlException e) {
- if (e.getIciqlCode() != IciqlException.CODE_INDEX_ALREADY_EXISTS) {
+ if (e.getIciqlCode() != IciqlException.CODE_INDEX_ALREADY_EXISTS
+ && e.getIciqlCode() != IciqlException.CODE_DUPLICATE_KEY) {
throw e;
}
}
diff --git a/src/com/iciql/TableInspector.java b/src/com/iciql/TableInspector.java index dc28956..093055c 100644 --- a/src/com/iciql/TableInspector.java +++ b/src/com/iciql/TableInspector.java @@ -433,13 +433,13 @@ public class TableInspector { if (!isNullOrEmpty(schema)) { if (isNullOrEmpty(def.schemaName)) { remarks.add(consider(table, "SCHEMA", - format("@{0}(name={1})", IQSchema.class.getSimpleName(), schema))); + format("@{0}(\"{1}\")", IQSchema.class.getSimpleName(), schema))); } else if (!schema.equalsIgnoreCase(def.schemaName)) { remarks.add(error( table, "SCHEMA", - format("@{0}(name={1}) != {2}", IQSchema.class.getSimpleName(), def.schemaName, - schema)).throwError(throwError)); + format("@{0}(\"{1}\") != {2}", IQSchema.class.getSimpleName(), def.schemaName, schema)) + .throwError(throwError)); } } diff --git a/src/com/iciql/build/Build.java b/src/com/iciql/build/Build.java index 0102739..8dfd7df 100644 --- a/src/com/iciql/build/Build.java +++ b/src/com/iciql/build/Build.java @@ -58,6 +58,7 @@ public class Build { downloadFromApache(MavenObject.H2, BuildType.COMPILETIME);
downloadFromApache(MavenObject.HSQLDB, BuildType.RUNTIME);
downloadFromApache(MavenObject.DERBY, BuildType.RUNTIME);
+ downloadFromApache(MavenObject.MYSQL, BuildType.RUNTIME);
downloadFromApache(MavenObject.JCOMMANDER, BuildType.RUNTIME);
downloadFromApache(MavenObject.JCOMMANDER, BuildType.COMPILETIME);
downloadFromApache(MavenObject.MARKDOWNPAPERS, BuildType.RUNTIME);
@@ -170,9 +171,9 @@ public class Build { "219a3540f3b27d7cc3b1d91d6ea046cd8723290e", "0bb50eec177acf0e94d58e0cf07262fe5164331d",
"c7adc475ca40c288c93054e0f4fe58f3a98c0cb5");
- public static final MavenObject H2 = new MavenObject("com/h2database", "h2", "1.3.159",
- "dd89f939661eb5593909584e1c243db0c25de130", "4d953bf765e8a13c7e06ca51165438338966c698",
- "4c79ed03f994820a1a873150c8a9f13c667784d3");
+ public static final MavenObject H2 = new MavenObject("com/h2database", "h2", "1.3.158",
+ "4bac13427caeb32ef6e93b70101e61f370c7b5e2", "6bb165156a0831879fa7797df6e18bdcd4421f2d",
+ "446d3f58c44992534cb54f67134532d95961904a");
public static final MavenObject HSQLDB = new MavenObject("org/hsqldb", "hsqldb", "2.2.4",
"6a6e040b07f5ee409fc825f1c5e5b574b1fa1428", "", "");
@@ -180,6 +181,9 @@ public class Build { public static final MavenObject DERBY = new MavenObject("org/apache/derby", "derby", "10.8.1.2",
"2f8717d96eafe3eef3de445ba653f142d54ddab1", "", "");
+ public static final MavenObject MYSQL = new MavenObject("mysql", "mysql-connector-java", "5.1.15",
+ "0fbc80454d27cc65f3addfa516707e9f8e60c3eb", "", "");
+
public static final MavenObject JUNIT = new MavenObject("junit", "junit", "4.8.2",
"c94f54227b08100974c36170dcb53329435fe5ad", "", "");
diff --git a/src/com/iciql/util/StatementLogger.java b/src/com/iciql/util/StatementLogger.java index 0504c98..b11a5f9 100644 --- a/src/com/iciql/util/StatementLogger.java +++ b/src/com/iciql/util/StatementLogger.java @@ -22,6 +22,8 @@ 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 StatementListeners.<br> * Statement logging is disabled by default. @@ -35,7 +37,7 @@ public class StatementLogger { * Enumeration of the different statement types that are logged. */ public enum StatementType { - STAT, TOTAL, CREATE, INSERT, UPDATE, MERGE, DELETE, SELECT; + STAT, TOTAL, CREATE, INSERT, UPDATE, MERGE, DELETE, SELECT, DROP; } /** @@ -61,19 +63,20 @@ public class StatementLogger { 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(); /** * Activates the Console Logger. */ public static void activateConsoleLogger() { - LISTENERS.add(CONSOLE); + registerListener(CONSOLE); } /** * Deactivates the Console Logger. */ public static void deactivateConsoleLogger() { - LISTENERS.remove(CONSOLE); + unregisterListener(CONSOLE); } /** @@ -91,7 +94,9 @@ public class StatementLogger { * @param listener */ public static void unregisterListener(StatementListener listener) { - LISTENERS.remove(listener); + if (!LISTENERS.remove(listener)) { + throw new IciqlException("Failed to remove statement listener {0}", listener); + } } public static void create(String statement) { @@ -124,6 +129,11 @@ public class StatementLogger { logStatement(StatementType.SELECT, statement); } + public static void drop(String statement) { + DROP_COUNT.incrementAndGet(); + logStatement(StatementType.DROP, statement); + } + private static void logStatement(final StatementType type, final String statement) { for (final StatementListener listener : LISTENERS) { EXEC.execute(new Runnable() { @@ -158,9 +168,13 @@ public class StatementLogger { return SELECT_COUNT.longValue(); } + public static long getDropCount() { + return DROP_COUNT.longValue(); + } + public static long getTotalCount() { return getCreateCount() + getInsertCount() + getUpdateCount() + getDeleteCount() + getMergeCount() - + getSelectCount(); + + getSelectCount() + getDropCount(); } public static void logStats() { @@ -172,6 +186,7 @@ public class StatementLogger { logStat(StatementType.MERGE, getMergeCount()); logStat(StatementType.DELETE, getDeleteCount()); logStat(StatementType.SELECT, getSelectCount()); + logStat(StatementType.DROP, getDropCount()); logStatement(StatementType.STAT, "========================"); logStat(StatementType.TOTAL, getTotalCount()); } diff --git a/tests/com/iciql/test/AnnotationsTest.java b/tests/com/iciql/test/AnnotationsTest.java index 7e4e918..4f50d61 100644 --- a/tests/com/iciql/test/AnnotationsTest.java +++ b/tests/com/iciql/test/AnnotationsTest.java @@ -69,30 +69,24 @@ public class AnnotationsTest { // test indexes are created, and columns are in the right order DatabaseMetaData meta = db.getConnection().getMetaData(); boolean isH2 = meta.getDatabaseProductName().equals("H2"); - boolean isDerby = meta.getDatabaseProductName().equals("Apache Derby"); - ResultSet rs; - if (isDerby) { - // Derby defaults to USERNAME schema - rs = meta.getIndexInfo(null, "SA", "ANNOTATEDPRODUCT", false, true); - } else { - // H2, HSQL default to PUBLIC schema - rs = meta.getIndexInfo(null, "PUBLIC", "ANNOTATEDPRODUCT", false, true); - } + String schema = IciqlSuite.getDefaultSchema(db); + ResultSet rs = meta.getIndexInfo(null, schema, "ANNOTATEDPRODUCT", false, true); + // first index is primary key index // H2 gives this a testable name. assertTrue(rs.next()); if (isH2) { - assertStartsWith(rs.getString("INDEX_NAME"), "PRIMARY_KEY"); + assertStartsWith(rs.getString("INDEX_NAME").toUpperCase(), "PRIMARY_KEY"); } assertTrue(rs.next()); - assertStartsWith(rs.getString("INDEX_NAME"), "ANNOTATEDPRODUCT_0"); - assertStartsWith(rs.getString("COLUMN_NAME"), "NAME"); + assertStartsWith(rs.getString("INDEX_NAME").toUpperCase(), "ANNOTATEDPRODUCT_0"); + assertStartsWith(rs.getString("COLUMN_NAME").toUpperCase(), "NAME"); assertTrue(rs.next()); - assertStartsWith(rs.getString("INDEX_NAME"), "ANNOTATEDPRODUCT_0"); - assertStartsWith(rs.getString("COLUMN_NAME"), "CAT"); + assertStartsWith(rs.getString("INDEX_NAME").toUpperCase(), "ANNOTATEDPRODUCT_0"); + assertStartsWith(rs.getString("COLUMN_NAME").toUpperCase(), "CAT"); assertTrue(rs.next()); - assertStartsWith(rs.getString("INDEX_NAME"), "NAMEIDX"); - assertStartsWith(rs.getString("COLUMN_NAME"), "NAME"); + assertStartsWith(rs.getString("INDEX_NAME").toUpperCase(), "NAMEIDX"); + assertStartsWith(rs.getString("COLUMN_NAME").toUpperCase(), "NAME"); assertFalse(rs.next()); } diff --git a/tests/com/iciql/test/ClobTest.java b/tests/com/iciql/test/ClobTest.java index 3b32dcb..49cee72 100644 --- a/tests/com/iciql/test/ClobTest.java +++ b/tests/com/iciql/test/ClobTest.java @@ -42,12 +42,14 @@ public class ClobTest { db.executeUpdate(MessageFormat.format(create, "VARCHAR(255)")); db.insertAll(StringRecord.getList()); testSimpleUpdate(db, "VARCHAR fail"); + db.executeUpdate("DROP TABLE CLOB_TEST"); db.close(); db = IciqlSuite.openNewDb(); - db.executeUpdate(MessageFormat.format(create, "CLOB")); + db.executeUpdate(MessageFormat.format(create, db.getDialect().convertSqlType("CLOB"))); db.insertAll(StringRecord.getList()); testSimpleUpdate(db, "CLOB fail because of single quote artifacts"); + db.executeUpdate("DROP TABLE CLOB_TEST"); db.close(); } diff --git a/tests/com/iciql/test/IciqlSuite.java b/tests/com/iciql/test/IciqlSuite.java index b91f3a4..0389d80 100644 --- a/tests/com/iciql/test/IciqlSuite.java +++ b/tests/com/iciql/test/IciqlSuite.java @@ -40,6 +40,20 @@ import com.beust.jcommander.ParameterException; import com.beust.jcommander.Parameters;
import com.iciql.Constants;
import com.iciql.Db;
+import com.iciql.test.models.BooleanModel;
+import com.iciql.test.models.ComplexObject;
+import com.iciql.test.models.Customer;
+import com.iciql.test.models.DefaultValuesModel;
+import com.iciql.test.models.EnumModels.EnumIdModel;
+import com.iciql.test.models.EnumModels.EnumOrdinalModel;
+import com.iciql.test.models.EnumModels.EnumStringModel;
+import com.iciql.test.models.Order;
+import com.iciql.test.models.PrimitivesModel;
+import com.iciql.test.models.Product;
+import com.iciql.test.models.ProductAnnotationOnly;
+import com.iciql.test.models.ProductInheritedAnnotation;
+import com.iciql.test.models.ProductMixedAnnotation;
+import com.iciql.test.models.SupportedTypes;
import com.iciql.util.StatementLogger;
import com.iciql.util.StatementLogger.StatementListener;
import com.iciql.util.StatementLogger.StatementType;
@@ -58,12 +72,13 @@ import com.iciql.util.StringUtils; @RunWith(Suite.class)
@SuiteClasses({ AliasMapTest.class, AnnotationsTest.class, BooleanModelTest.class, ClobTest.class,
ConcurrencyTest.class, EnumsTest.class, ModelsTest.class, PrimitivesTest.class,
- RuntimeQueryTest.class, SamplesTest.class, UpdateTest.class, UUIDTest.class })
+ RuntimeQueryTest.class, SamplesTest.class, UpdateTest.class, UpgradesTest.class, UUIDTest.class })
public class IciqlSuite {
- private static final TestDb[] TEST_DBS = { new TestDb("H2", "jdbc:h2:mem:db{0,number,000}"),
- new TestDb("HSQL", "jdbc:hsqldb:mem:db{0,number,000}"),
- new TestDb("Derby", "jdbc:derby:memory:db{0,number,000};create=true") };
+ private static final TestDb[] TEST_DBS = { new TestDb("H2 (embedded)", "jdbc:h2:mem:db{0,number,000}"),
+ new TestDb("HSQL (embedded)", "jdbc:hsqldb:mem:db{0,number,000}"),
+ new TestDb("Derby (embedded)", "jdbc:derby:memory:db{0,number,000};create=true"),
+ new TestDb("MySQL (tcp/myisam)", "jdbc:mysql://localhost:3306/iciql") };
private static final TestDb DEFAULT_TEST_DB = TEST_DBS[0];
@@ -82,6 +97,13 @@ public class IciqlSuite { value.startsWith(startsWith));
}
+ public static boolean equivalentTo(double expected, double actual) {
+ if (Double.compare(expected, actual) == 0) {
+ return true;
+ }
+ return Math.abs(expected - actual) <= 0.000001d;
+ }
+
/**
* Increment the database counter, open and create a new database.
*
@@ -93,7 +115,25 @@ public class IciqlSuite { testUrl = DEFAULT_TEST_DB.url;
}
testUrl = MessageFormat.format(testUrl, openCount.incrementAndGet());
- return Db.open(testUrl, username, password);
+ Db db = Db.open(testUrl, username, password);
+
+ // drop tables
+ db.dropTable(BooleanModel.class);
+ db.dropTable(ComplexObject.class);
+ db.dropTable(Customer.class);
+ db.dropTable(DefaultValuesModel.class);
+ db.dropTable(EnumIdModel.class);
+ db.dropTable(EnumOrdinalModel.class);
+ db.dropTable(EnumStringModel.class);
+ db.dropTable(Order.class);
+ db.dropTable(PrimitivesModel.class);
+ db.dropTable(Product.class);
+ db.dropTable(ProductAnnotationOnly.class);
+ db.dropTable(ProductInheritedAnnotation.class);
+ db.dropTable(ProductMixedAnnotation.class);
+ db.dropTable(SupportedTypes.class);
+
+ return db;
}
/**
@@ -111,6 +151,15 @@ public class IciqlSuite { }
/**
+ * Drops all tables from the current database.
+ *
+ * @return the current database
+ */
+ public static void dropAllTables(Db db) {
+
+ }
+
+ /**
* Returns the name of the underlying database engine for the Db object.
*
* @param db
@@ -146,6 +195,16 @@ public class IciqlSuite { }
/**
+ * Returns true if the underlying database engine is MySQL.
+ *
+ * @param db
+ * @return true if underlying database engine is MySQL
+ */
+ public static boolean isMySQL(Db db) {
+ return IciqlSuite.getDatabaseEngineName(db).equals("MySQL");
+ }
+
+ /**
* Gets the default schema of the underlying database engine.
*
* @param db
@@ -155,7 +214,11 @@ public class IciqlSuite { if (isDerby(db)) {
// Derby sets default schema name to username
return username.toUpperCase();
+ } else if (isMySQL(db)) {
+ // MySQL does not have schemas
+ return null;
}
+
return "PUBLIC";
}
@@ -206,8 +269,8 @@ public class IciqlSuite { SuiteClasses suiteClasses = IciqlSuite.class.getAnnotation(SuiteClasses.class);
long quickestDatabase = Long.MAX_VALUE;
- String dividerMajor = buildDivider('*', 70);
- String dividerMinor = buildDivider('-', 70);
+ String dividerMajor = buildDivider('*', 79);
+ String dividerMinor = buildDivider('-', 79);
// Header
out.println(dividerMajor);
@@ -225,7 +288,7 @@ public class IciqlSuite { showProperty("available processors", "" + Runtime.getRuntime().availableProcessors());
showProperty(
"available memory",
- MessageFormat.format("{0,number,#.0} GB", ((double) Runtime.getRuntime().maxMemory())
+ MessageFormat.format("{0,number,0.0} GB", ((double) Runtime.getRuntime().maxMemory())
/ (1024 * 1024)));
out.println();
@@ -246,32 +309,42 @@ public class IciqlSuite { statementWriter.append("\n\n");
}
- System.setProperty("iciql.url", testDb.url);
- Result result = JUnitCore.runClasses(suiteClasses.value());
- testDb.runtime = result.getRunTime();
- if (testDb.runtime < quickestDatabase) {
- quickestDatabase = testDb.runtime;
- }
- testDb.statements = StatementLogger.getTotalCount() - lastCount;
- // reset total count for next database
- lastCount = StatementLogger.getTotalCount();
-
- out.println(MessageFormat.format(
- "{0} tests ({1} failures, {2} ignores) {3} statements in {4,number,0.000} secs",
- result.getRunCount(), result.getFailureCount(), result.getIgnoreCount(),
- testDb.statements, result.getRunTime() / 1000f));
-
- if (result.getFailureCount() == 0) {
- out.println();
+ if (testDb.getVersion().equals("OFFLINE")) {
+ // Database not available
+ out.println("Skipping. Could not find " + testDb.url);
} else {
- for (Failure failure : result.getFailures()) {
- out.println(MessageFormat.format("\n + {0}\n {1}\n", failure.getTestHeader(),
- failure.getMessage()));
+ // Test database
+ System.setProperty("iciql.url", testDb.url);
+ Result result = JUnitCore.runClasses(suiteClasses.value());
+ testDb.runtime = result.getRunTime();
+ if (testDb.runtime < quickestDatabase) {
+ quickestDatabase = testDb.runtime;
+ }
+ testDb.statements = StatementLogger.getTotalCount() - lastCount;
+ // reset total count for next database
+ lastCount = StatementLogger.getTotalCount();
+
+ out.println(MessageFormat.format(
+ "{0} tests ({1} failures, {2} ignores) {3} statements in {4,number,0.000} secs",
+ result.getRunCount(), result.getFailureCount(), result.getIgnoreCount(),
+ testDb.statements, result.getRunTime() / 1000f));
+
+ if (result.getFailureCount() == 0) {
+ out.println();
+ out.println(" 100% successful test suite run.");
+ out.println();
+ } else {
+ for (Failure failure : result.getFailures()) {
+ out.println(MessageFormat.format("\n + {0}\n {1}", failure.getTestHeader(),
+ failure.getMessage()));
+ }
+ out.println();
}
}
}
// Display runtime results sorted by performance leader
+ out.println();
out.println(dividerMajor);
out.println(MessageFormat.format("{0} {1} ({2}) test suite performance results", Constants.NAME,
Constants.VERSION, Constants.VERSION_DATE));
@@ -281,6 +354,12 @@ public class IciqlSuite { @Override
public int compare(TestDb o1, TestDb o2) {
+ if (o1.runtime == 0) {
+ return 1;
+ }
+ if (o2.runtime == 0) {
+ return -1;
+ }
if (o1.runtime == o2.runtime) {
return 0;
}
@@ -292,11 +371,11 @@ public class IciqlSuite { });
for (TestDb testDb : dbs) {
out.println(MessageFormat.format(
- "{0} {1} {2,number,0.0} stats/sec {3,number,0.000} secs ({4,number,#.0}x)",
- StringUtils.pad(testDb.name, 6, " ", true),
- StringUtils.pad(testDb.getVersion(), 22, " ", true),
- ((double) testDb.statements)/ (testDb.runtime/1000d), testDb.runtime / 1000f,
- ((double) testDb.runtime) / quickestDatabase));
+ "{0} {1} {2,number,0} stats/sec {3,number,0.000} secs ({4,number,0.0}x)",
+ StringUtils.pad(testDb.name, 20, " ", true),
+ StringUtils.pad(testDb.getVersion(), 22, " ", true), ((double) testDb.statements)
+ / (testDb.runtime / 1000d), testDb.runtime / 1000f, ((double) testDb.runtime)
+ / quickestDatabase));
}
// close PrintStream and restore System.err
@@ -362,8 +441,8 @@ public class IciqlSuite { version = db.getConnection().getMetaData().getDatabaseProductVersion();
db.close();
return version;
- } catch (SQLException s) {
- version = "";
+ } catch (Throwable t) {
+ version = "OFFLINE";
}
}
return version;
diff --git a/tests/com/iciql/test/ModelsTest.java b/tests/com/iciql/test/ModelsTest.java index 9bbf450..d2e02fa 100644 --- a/tests/com/iciql/test/ModelsTest.java +++ b/tests/com/iciql/test/ModelsTest.java @@ -23,7 +23,6 @@ import static org.junit.Assert.assertTrue; import java.sql.SQLException; import java.text.MessageFormat; import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; import org.junit.After; import org.junit.Before; @@ -33,15 +32,12 @@ import org.junit.rules.ErrorCollector; import com.iciql.Db; import com.iciql.DbInspector; -import com.iciql.DbUpgrader; -import com.iciql.DbVersion; -import com.iciql.Iciql.IQVersion; import com.iciql.ValidationRemark; import com.iciql.test.models.Product; import com.iciql.test.models.ProductAnnotationOnly; import com.iciql.test.models.ProductMixedAnnotation; import com.iciql.test.models.SupportedTypes; -import com.iciql.test.models.SupportedTypes.SupportedTypes2; +import com.iciql.util.StringUtils; /** * Test that the mapping between classes and tables is done correctly. @@ -72,13 +68,9 @@ public class ModelsTest { @Test public void testValidateModels() { - boolean isH2 = IciqlSuite.isH2(db); - boolean isDerby = IciqlSuite.isDerby(db); String schemaName = IciqlSuite.getDefaultSchema(db); - DbInspector inspector = new DbInspector(db); - validateModel(inspector, schemaName, new Product(), 3); - validateModel(inspector, schemaName, new ProductAnnotationOnly(), (isH2 || isDerby) ? 2 : 3); + validateModel(inspector, schemaName, new ProductAnnotationOnly(), 2); validateModel(inspector, schemaName, new ProductMixedAnnotation(), 4); } @@ -95,8 +87,14 @@ public class ModelsTest { errorCollector.addError(new SQLException(remark.toString())); } } - assertTrue(remarks.get(0).message.equals(MessageFormat.format("@IQSchema(name={0})", schemaName))); - assertEquals(sb.toString(), expected, remarks.size()); + + if (StringUtils.isNullOrEmpty(schemaName)) { + // no schema expected + assertEquals(sb.toString(), expected - 1, remarks.size()); + } else { + assertEquals(sb.toString(), expected, remarks.size()); + assertEquals(MessageFormat.format("@IQSchema(\"{0}\")", schemaName), remarks.get(0).message); + } } @Test @@ -133,65 +131,4 @@ public class ModelsTest { assertEquals(1489, models.get(0).length()); } } - - @Test - public void testDatabaseUpgrade() { - // insert a database version record - db.insert(new DbVersion(1)); - - TestDbUpgrader dbUpgrader = new TestDbUpgrader(); - db.setDbUpgrader(dbUpgrader); - - List<SupportedTypes> original = SupportedTypes.createList(); - db.insertAll(original); - - assertEquals(1, dbUpgrader.oldVersion.get()); - assertEquals(2, dbUpgrader.newVersion.get()); - } - - @Test - public void testTableUpgrade() { - Db db = IciqlSuite.openNewDb(); - - // insert first, this will create version record automatically - List<SupportedTypes> original = SupportedTypes.createList(); - db.insertAll(original); - - // reset the dbUpgrader (clears the update check cache) - TestDbUpgrader dbUpgrader = new TestDbUpgrader(); - db.setDbUpgrader(dbUpgrader); - - SupportedTypes2 s2 = new SupportedTypes2(); - - List<SupportedTypes2> types = db.from(s2).select(); - assertEquals(10, types.size()); - assertEquals(1, dbUpgrader.oldVersion.get()); - assertEquals(2, dbUpgrader.newVersion.get()); - db.close(); - } - - /** - * A sample database upgrader class. - */ - @IQVersion(2) - class TestDbUpgrader implements DbUpgrader { - final AtomicInteger oldVersion = new AtomicInteger(0); - final AtomicInteger newVersion = new AtomicInteger(0); - - public boolean upgradeTable(Db db, String schema, String table, int fromVersion, int toVersion) { - // just claims success on upgrade request - oldVersion.set(fromVersion); - newVersion.set(toVersion); - return true; - } - - public boolean upgradeDatabase(Db db, int fromVersion, int toVersion) { - // just claims success on upgrade request - oldVersion.set(fromVersion); - newVersion.set(toVersion); - return true; - } - - } - } diff --git a/tests/com/iciql/test/SamplesTest.java b/tests/com/iciql/test/SamplesTest.java index f16672a..17c2151 100644 --- a/tests/com/iciql/test/SamplesTest.java +++ b/tests/com/iciql/test/SamplesTest.java @@ -91,6 +91,7 @@ public class SamplesTest { TestReverse check = db.from(new TestReverse()).selectFirst();
assertEquals(t.name, check.name);
assertEquals(t.id, check.id);
+ db.executeUpdate("DROP TABLE testreverse");
}
@Test
@@ -238,7 +239,8 @@ public class SamplesTest { public void testIsNull() {
Product p = new Product();
String sql = db.from(p).whereTrue(isNull(p.productName)).getSQL();
- assertEquals("SELECT * FROM Product WHERE (productName IS NULL)", sql);
+ assertEquals("SELECT * FROM Product WHERE (" + db.getDialect().prepareColumnName("productName")
+ + " IS NULL)", sql);
}
@Test
@@ -258,11 +260,13 @@ public class SamplesTest { public void testOrAndNot() {
Product p = new Product();
String sql = db.from(p).whereTrue(not(isNull(p.productName))).getSQL();
- assertEquals("SELECT * FROM Product WHERE (NOT productName IS NULL)", sql);
+ String productName = db.getDialect().prepareColumnName("productName");
+ assertEquals("SELECT * FROM Product WHERE (NOT " + productName + " IS NULL)", sql);
sql = db.from(p).whereTrue(not(isNull(p.productName))).getSQL();
- assertEquals("SELECT * FROM Product WHERE (NOT productName IS NULL)", sql);
+ assertEquals("SELECT * FROM Product WHERE (NOT " + productName + " IS NULL)", sql);
sql = db.from(p).whereTrue(db.test(p.productId).is(1)).getSQL();
- assertEquals("SELECT * FROM Product WHERE ((productId = ?))", sql);
+ String productId = db.getDialect().prepareColumnName("productId");
+ assertEquals("SELECT * FROM Product WHERE ((" + productId + " = ?))", sql);
}
@Test
@@ -316,8 +320,24 @@ public class SamplesTest { .lessThan(java.sql.Timestamp.valueOf("2005-05-05 05:05:05")).and(co.name).is("hello")
.and(co.time).lessThan(java.sql.Time.valueOf("23:23:23")).and(co.value)
.is(new BigDecimal("1")).getSQL();
- assertEquals("SELECT * FROM ComplexObject WHERE id = ? AND amount = ? "
- + "AND birthday < ? AND created < ? AND name = ? AND time < ? AND value = ?", sql);
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("SELECT * FROM ComplexObject WHERE ");
+ sb.append(db.getDialect().prepareColumnName("id"));
+ sb.append(" = ? AND ");
+ sb.append(db.getDialect().prepareColumnName("amount"));
+ sb.append(" = ? AND ");
+ sb.append(db.getDialect().prepareColumnName("birthday"));
+ sb.append(" < ? AND ");
+ sb.append(db.getDialect().prepareColumnName("created"));
+ sb.append(" < ? AND ");
+ sb.append(db.getDialect().prepareColumnName("name"));
+ sb.append(" = ? AND ");
+ sb.append(db.getDialect().prepareColumnName("time"));
+ sb.append(" < ? AND ");
+ sb.append(db.getDialect().prepareColumnName("value"));
+ sb.append(" = ?");
+ assertEquals(sb.toString(), sql);
long count = db.from(co).where(co.id).is(1).and(co.amount).is(1L).and(co.birthday)
.lessThan(new java.util.Date()).and(co.created)
@@ -340,7 +360,14 @@ public class SamplesTest { return co.id == x && co.name.equals(name) && co.name.equals("hello");
}
}).getSQL();
- assertEquals("SELECT * FROM ComplexObject WHERE id=? AND ?=name AND 'hello'=name", sql);
+ StringBuilder sb = new StringBuilder();
+ sb.append("SELECT * FROM ComplexObject WHERE ");
+ sb.append(db.getDialect().prepareColumnName("id"));
+ sb.append("=? AND ?=");
+ sb.append(db.getDialect().prepareColumnName("name"));
+ sb.append(" AND 'hello'=");
+ sb.append(db.getDialect().prepareColumnName("name"));
+ assertEquals(sb.toString(), sql);
long count = db.from(co).where(new Filter() {
public boolean where() {
diff --git a/tests/com/iciql/test/UUIDTest.java b/tests/com/iciql/test/UUIDTest.java index bc3bd12..9b88cb8 100644 --- a/tests/com/iciql/test/UUIDTest.java +++ b/tests/com/iciql/test/UUIDTest.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.UUID; import org.junit.After; +import org.junit.Assume; import org.junit.Before; import org.junit.Test; @@ -52,10 +53,9 @@ public class UUIDTest { @Test public void testUUIDs() throws Exception { - if (!IciqlSuite.isH2(db)) { - // do not test non-H2 databases - return; - } + // do not test non-H2 databases + Assume.assumeTrue(IciqlSuite.isH2(db)); + List<UUIDRecord> originals = UUIDRecord.getList(); db.insertAll(originals); UUIDRecord u = new UUIDRecord(); diff --git a/tests/com/iciql/test/UpgradesTest.java b/tests/com/iciql/test/UpgradesTest.java new file mode 100644 index 0000000..d4c15e1 --- /dev/null +++ b/tests/com/iciql/test/UpgradesTest.java @@ -0,0 +1,134 @@ +/*
+ * 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.test;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.junit.Test;
+
+import com.iciql.Db;
+import com.iciql.DbUpgrader;
+import com.iciql.Iciql.IQVersion;
+import com.iciql.test.models.Product;
+import com.iciql.test.models.SupportedTypes;
+import com.iciql.test.models.SupportedTypes.SupportedTypes2;
+
+/**
+ * Tests the database and table upgrade functions.
+ *
+ */
+public class UpgradesTest {
+
+ @Test
+ public void testDatabaseUpgrade() {
+ Db db = IciqlSuite.openNewDb();
+
+ List<Product> products = Product.getList();
+
+ // set the v1 upgrader and insert a record.
+ // this will trigger the upgrade.
+ V1DbUpgrader v1 = new V1DbUpgrader();
+ db.setDbUpgrader(v1);
+ db.insert(products.get(0));
+
+ // confirm that upgrade occurred
+ assertEquals(0, v1.oldVersion.get());
+ assertEquals(1, v1.newVersion.get());
+
+ // open a second connection to the database
+ // and then apply the v2 upgrade.
+ // For H2 its important to keep the first connection
+ // alive so that the database is not destroyed.
+ Db db2 = IciqlSuite.openCurrentDb();
+
+ // set the v2 upgrader and insert a record.
+ // this will trigger the upgrade.
+ V2DbUpgrader v2 = new V2DbUpgrader();
+ db2.setDbUpgrader(v2);
+ db2.insert(products.get(1));
+
+ // confirm that upgrade occurred
+ assertEquals(1, v2.oldVersion.get());
+ assertEquals(2, v2.newVersion.get());
+
+ db.executeUpdate("DROP TABLE iq_versions");
+ db.close();
+ db2.close();
+ }
+
+ @Test
+ public void testTableUpgrade() {
+ Db db = IciqlSuite.openNewDb();
+
+ // insert first, this will create version record automatically
+ List<SupportedTypes> original = SupportedTypes.createList();
+ db.insertAll(original);
+
+ // reset the dbUpgrader (clears the update check cache)
+ V2DbUpgrader dbUpgrader = new V2DbUpgrader();
+ db.setDbUpgrader(dbUpgrader);
+
+ SupportedTypes2 s2 = new SupportedTypes2();
+
+ List<SupportedTypes2> types = db.from(s2).select();
+ assertEquals(10, types.size());
+ assertEquals(1, dbUpgrader.oldVersion.get());
+ assertEquals(2, dbUpgrader.newVersion.get());
+ db.executeUpdate("DROP TABLE iq_versions");
+ db.close();
+ }
+
+ /**
+ * A sample database upgrader class.
+ */
+ class BaseDbUpgrader implements DbUpgrader {
+ final AtomicInteger oldVersion = new AtomicInteger(0);
+ final AtomicInteger newVersion = new AtomicInteger(0);
+
+ public boolean upgradeTable(Db db, String schema, String table, int fromVersion, int toVersion) {
+ // just claims success on upgrade request
+ oldVersion.set(fromVersion);
+ newVersion.set(toVersion);
+ return true;
+ }
+
+ public boolean upgradeDatabase(Db db, int fromVersion, int toVersion) {
+ // just claims success on upgrade request
+ oldVersion.set(fromVersion);
+ newVersion.set(toVersion);
+ return true;
+ }
+ }
+
+ /**
+ * A sample V1 database upgrader class.
+ */
+ @IQVersion(1)
+ class V1DbUpgrader extends BaseDbUpgrader {
+ }
+
+ /**
+ * A sample V2 database upgrader class.
+ */
+ @IQVersion(2)
+ class V2DbUpgrader extends BaseDbUpgrader {
+ }
+
+}
diff --git a/tests/com/iciql/test/models/PrimitivesModel.java b/tests/com/iciql/test/models/PrimitivesModel.java index 0affd28..44e8b9b 100644 --- a/tests/com/iciql/test/models/PrimitivesModel.java +++ b/tests/com/iciql/test/models/PrimitivesModel.java @@ -21,6 +21,7 @@ import java.util.Random; import com.iciql.Iciql.IQColumn;
import com.iciql.Iciql.IQTable;
+import com.iciql.test.IciqlSuite;
/**
* Primitive types model.
@@ -67,8 +68,8 @@ public class PrimitivesModel { same &= myShort == p.myShort;
same &= myByte == p.myByte;
same &= myBoolean == p.myBoolean;
- same &= myDouble == p.myDouble;
- same &= myFloat == p.myFloat;
+ same &= IciqlSuite.equivalentTo(myDouble, p.myDouble);
+ same &= IciqlSuite.equivalentTo(myFloat, p.myFloat);
return same;
}
diff --git a/tests/com/iciql/test/models/ProductAnnotationOnly.java b/tests/com/iciql/test/models/ProductAnnotationOnly.java index 80bf0a1..e4de22d 100644 --- a/tests/com/iciql/test/models/ProductAnnotationOnly.java +++ b/tests/com/iciql/test/models/ProductAnnotationOnly.java @@ -34,12 +34,9 @@ import com.iciql.Iciql.IndexType; @IQIndexes({ @IQIndex({ "name", "cat" }), @IQIndex(name = "nameidx", type = IndexType.HASH, value = "name") }) public class ProductAnnotationOnly { - @IQColumn(autoIncrement = true) - public Integer autoIncrement; - public String unmappedField; - @IQColumn(name = "id") + @IQColumn(name = "id", autoIncrement = true) public Integer productId; @IQColumn(name = "cat", length = 15, trim = true) diff --git a/tests/com/iciql/test/models/SupportedTypes.java b/tests/com/iciql/test/models/SupportedTypes.java index 596af74..1aaa833 100644 --- a/tests/com/iciql/test/models/SupportedTypes.java +++ b/tests/com/iciql/test/models/SupportedTypes.java @@ -32,6 +32,7 @@ import com.iciql.Iciql.IQIndexes; import com.iciql.Iciql.IQTable; import com.iciql.Iciql.IQVersion; import com.iciql.Iciql.IndexType; +import com.iciql.test.IciqlSuite; import com.iciql.test.models.EnumModels.Tree; import com.iciql.util.Utils; @@ -166,8 +167,8 @@ public class SupportedTypes { same &= myShort.equals(s.myShort); same &= myInteger.equals(s.myInteger); same &= myLong.equals(s.myLong); - same &= myFloat.equals(s.myFloat); - same &= myDouble.equals(s.myDouble); + same &= IciqlSuite.equivalentTo(myFloat, s.myFloat); + same &= IciqlSuite.equivalentTo(myDouble, s.myDouble); same &= myBigDecimal.compareTo(s.myBigDecimal) == 0; SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); same &= df.format(myUtilDate).equals(df.format(s.myUtilDate)); |