@@ -10,7 +10,7 @@ name: Iciql | |||
description: 'a model-based database access wrapper for JDBC' | |||
groupId: com.iciql | |||
artifactId: iciql | |||
version: 1.7.0-SNAPSHOT | |||
version: 1.6.2-SNAPSHOT | |||
packaging: jar+zip | |||
inceptionYear: 2011 | |||
@@ -9,7 +9,8 @@ r26: { | |||
html: ~ | |||
text: ~ | |||
security: ~ | |||
fixes: ~ | |||
fixes: | |||
- Reverted change which keyed DataTypeAdapters by the target Java type | |||
changes: ~ | |||
additions: ~ | |||
dependencyChanges: ~ | |||
@@ -30,8 +31,13 @@ r25: { | |||
fixes: | |||
- Fix column inheritance from superclasses (pr-14) | |||
- Use webapp classloader rather than global classloader (pr-12) | |||
- Fix deserialization of null values | |||
changes: | |||
- Improve SQLite dialect based on upstream JDBC improvements | |||
- Key DataTypeAdapters by target Java type | |||
- Drop precision and length from SQL->Java type determination | |||
- Improve readability of the generated performance benchmark table | |||
- Added Derby TCP benchmark test | |||
additions: ~ | |||
dependencyChanges: | |||
- SQLite 3.8.10 | |||
@@ -56,8 +62,13 @@ r24: { | |||
fixes: | |||
- Fix column inheritance from superclasses (pr-14) | |||
- Use webapp classloader rather than global classloader (pr-12) | |||
- Fix deserialization of null values | |||
changes: | |||
- Improve SQLite dialect based on upstream JDBC improvements | |||
- Key DataTypeAdapters by target Java type | |||
- Drop precision and length from SQL->Java type determination | |||
- Improve readability of the generated performance benchmark table | |||
- Added Derby TCP benchmark test | |||
additions: ~ | |||
dependencyChanges: | |||
- SQLite 3.8.10 |
@@ -193,18 +193,13 @@ final class DaoProxy<X extends Dao> implements InvocationHandler, Dao { | |||
} else { | |||
// query of (array of) standard Java type or a DataTypeAdapter type | |||
if (adapter != null) { | |||
DataTypeAdapter<?> dta = Utils.newObject(adapter); | |||
db.getDialect().registerAdapter(dta); | |||
} | |||
objects = Utils.newArrayList(); | |||
ResultSet rs = db.executeQuery(preparedSql.sql, preparedSql.parameters); | |||
try { | |||
while (rs.next()) { | |||
Object value = db.getDialect().deserialize(rs, 1, returnType); | |||
Object value = db.getDialect().deserialize(rs, 1, returnType, adapter); | |||
objects.add(value); | |||
if (!isArray) { | |||
@@ -688,13 +683,8 @@ final class DaoProxy<X extends Dao> implements InvocationHandler, Dao { | |||
typeAdapter = Utils.getDataTypeAdapter(methodArg.getClass().getAnnotations()); | |||
} | |||
if (typeAdapter != null) { | |||
DataTypeAdapter<?> dta = Utils.newObject(typeAdapter); | |||
db.getDialect().registerAdapter(dta); | |||
} | |||
// prepare the parameter | |||
parameters[i] = db.getDialect().serialize(value); | |||
parameters[i] = db.getDialect().serialize(value, typeAdapter); | |||
} | |||
@@ -37,20 +37,21 @@ public interface SQLDialect { | |||
void registerAdapter(DataTypeAdapter<?> typeAdapter); | |||
/** | |||
* Returns the registered instance of the type adapter for the specified object class. | |||
* Returns the registered instance of the type adapter. | |||
* | |||
* @param objectClass | |||
* @param typeAdapter | |||
* @return the type adapter instance | |||
*/ | |||
DataTypeAdapter<?> getAdapter(Class<?> objectClass); | |||
DataTypeAdapter<?> getAdapter(Class<? extends DataTypeAdapter<?>> typeAdapter); | |||
/** | |||
* Serialize the Java object into a type or format that the database will accept. | |||
* | |||
* @param value | |||
* @param typeAdapter | |||
* @return the serialized object | |||
*/ | |||
<T> Object serialize(T value); | |||
<T> Object serialize(T value, Class<? extends DataTypeAdapter<?>> typeAdapter); | |||
/** | |||
* Deserialize the object received from the database into a Java type. | |||
@@ -58,9 +59,10 @@ public interface SQLDialect { | |||
* @param rs | |||
* @param columnIndex | |||
* @param targetType | |||
* @param typeAdapter | |||
* @return the deserialized object | |||
*/ | |||
Object deserialize(ResultSet rs, int columnIndex, Class<?> targetType); | |||
Object deserialize(ResultSet rs, int columnIndex, Class<?> targetType, Class<? extends DataTypeAdapter<?>> typeAdapter); | |||
/** | |||
* Configure the dialect. |
@@ -55,10 +55,10 @@ public class SQLDialectDefault implements SQLDialect { | |||
String databaseName; | |||
String productVersion; | |||
Mode mode; | |||
Map<Class<?>, DataTypeAdapter<?>> typeAdapters; | |||
Map<Class<? extends DataTypeAdapter<?>>, DataTypeAdapter<?>> typeAdapters; | |||
public SQLDialectDefault() { | |||
typeAdapters = new ConcurrentHashMap<Class<?>, DataTypeAdapter<?>>(); | |||
typeAdapters = new ConcurrentHashMap<Class<? extends DataTypeAdapter<?>>, DataTypeAdapter<?>>(); | |||
} | |||
@Override | |||
@@ -420,7 +420,7 @@ public class SQLDialectDefault implements SQLDialect { | |||
buff.appendExceptFirst(", "); | |||
buff.append('?'); | |||
Object value = def.getValue(obj, field); | |||
Object parameter = serialize(value); | |||
Object parameter = serialize(value, field.typeAdapter); | |||
stat.addParameter(parameter); | |||
} | |||
buff.append(" FROM "); | |||
@@ -432,7 +432,7 @@ public class SQLDialectDefault implements SQLDialect { | |||
buff.appendExceptFirst(" AND "); | |||
buff.append(MessageFormat.format("{0} = ?", prepareColumnName(field.columnName))); | |||
Object value = def.getValue(obj, field); | |||
Object parameter = serialize(value); | |||
Object parameter = serialize(value, field.typeAdapter); | |||
stat.addParameter(parameter); | |||
} | |||
} | |||
@@ -452,35 +452,37 @@ public class SQLDialectDefault implements SQLDialect { | |||
@Override | |||
public void registerAdapter(DataTypeAdapter<?> typeAdapter) { | |||
typeAdapters.put(typeAdapter.getJavaType(), typeAdapter); | |||
typeAdapters.put((Class<? extends DataTypeAdapter<?>>) typeAdapter.getClass(), typeAdapter); | |||
} | |||
@Override | |||
public DataTypeAdapter<?> getAdapter(Class<?> objectClass) { | |||
DataTypeAdapter<?> dta = typeAdapters.get(objectClass); | |||
if (dta != null) { | |||
dta.setMode(mode); | |||
public DataTypeAdapter<?> getAdapter(Class<? extends DataTypeAdapter<?>> typeAdapter) { | |||
DataTypeAdapter<?> dta = typeAdapters.get(typeAdapter); | |||
if (dta == null) { | |||
dta = Utils.newObject(typeAdapter); | |||
typeAdapters.put(typeAdapter, dta); | |||
} | |||
dta.setMode(mode); | |||
return dta; | |||
} | |||
@SuppressWarnings("unchecked") | |||
@Override | |||
public <T> Object serialize(T value) { | |||
DataTypeAdapter dta = getAdapter(value.getClass()); | |||
if (dta == null) { | |||
public <T> Object serialize(T value, Class<? extends DataTypeAdapter<?>> typeAdapter) { | |||
if (typeAdapter == null) { | |||
// pass-through | |||
return value; | |||
} | |||
DataTypeAdapter<T> dta = (DataTypeAdapter<T>) getAdapter(typeAdapter); | |||
return dta.serialize(value); | |||
} | |||
@Override | |||
public Object deserialize(ResultSet rs, int columnIndex, Class<?> targetType) { | |||
public Object deserialize(ResultSet rs, int columnIndex, Class<?> targetType, Class<? extends DataTypeAdapter<?>> typeAdapter) { | |||
Object value = null; | |||
try { | |||
DataTypeAdapter<?> dta = getAdapter(targetType); | |||
if (dta == null) { | |||
if (typeAdapter == null) { | |||
// standard object deserialization | |||
Object o = rs.getObject(columnIndex); | |||
if (o == null) { | |||
@@ -495,6 +497,7 @@ public class SQLDialectDefault implements SQLDialect { | |||
} | |||
} else { | |||
// custom object deserialization with a DataTypeAdapter | |||
DataTypeAdapter<?> dta = getAdapter(typeAdapter); | |||
Object object = rs.getObject(columnIndex); | |||
value = dta.deserialize(object); | |||
} | |||
@@ -521,4 +524,4 @@ public class SQLDialectDefault implements SQLDialect { | |||
return o.toString(); | |||
} | |||
} | |||
} |
@@ -127,7 +127,7 @@ public class SQLDialectH2 extends SQLDialectDefault { | |||
buff.appendExceptFirst(", "); | |||
buff.append('?'); | |||
Object value = def.getValue(obj, field); | |||
Object parameter = serialize(value); | |||
Object parameter = serialize(value, field.typeAdapter); | |||
stat.addParameter(parameter); | |||
} | |||
buff.append(')'); |
@@ -91,7 +91,7 @@ public class SQLDialectHSQL extends SQLDialectDefault { | |||
} | |||
buff.append(')'); | |||
Object value = def.getValue(obj, field); | |||
Object parameter = serialize(value); | |||
Object parameter = serialize(value, field.typeAdapter); | |||
stat.addParameter(parameter); | |||
} | |||
@@ -77,7 +77,7 @@ public class SQLDialectMySQL extends SQLDialectDefault { | |||
buff.appendExceptFirst(", "); | |||
buff.append('?'); | |||
Object value = def.getValue(obj, field); | |||
Object parameter = serialize(value); | |||
Object parameter = serialize(value, field.typeAdapter); | |||
stat.addParameter(parameter); | |||
} | |||
buff.append(") ON DUPLICATE KEY UPDATE "); |
@@ -22,6 +22,7 @@ import java.sql.SQLException; | |||
import java.sql.Time; | |||
import java.sql.Timestamp; | |||
import com.iciql.Iciql.DataTypeAdapter; | |||
import com.iciql.TableDefinition.FieldDefinition; | |||
import com.iciql.TableDefinition.IndexDefinition; | |||
import com.iciql.util.IciqlLogger; | |||
@@ -131,7 +132,7 @@ public class SQLDialectSQLite extends SQLDialectDefault { | |||
buff.appendExceptFirst(", "); | |||
buff.append('?'); | |||
Object value = def.getValue(obj, field); | |||
Object parameter = serialize(value); | |||
Object parameter = serialize(value, field.typeAdapter); | |||
stat.addParameter(parameter); | |||
} | |||
buff.append(')'); | |||
@@ -139,11 +140,11 @@ public class SQLDialectSQLite extends SQLDialectDefault { | |||
} | |||
@Override | |||
public Object deserialize(ResultSet rs, int columnIndex, Class<?> targetType) { | |||
public Object deserialize(ResultSet rs, int columnIndex, Class<?> targetType, Class<? extends DataTypeAdapter<?>> typeAdapter) { | |||
try { | |||
return super.deserialize(rs, columnIndex, targetType); | |||
return super.deserialize(rs, columnIndex, targetType, typeAdapter); | |||
} catch (IciqlException e) { | |||
if (e.getMessage().startsWith("Can not convert")) { | |||
if (typeAdapter == null && e.getMessage().startsWith("Can not convert")) { | |||
try { | |||
// give the SQLite JDBC driver an opportunity to deserialize DateTime objects | |||
if (Timestamp.class.equals(targetType)) { | |||
@@ -176,4 +177,4 @@ public class SQLDialectSQLite extends SQLDialectDefault { | |||
} | |||
return super.prepareStringParameter(o); | |||
} | |||
} | |||
} |
@@ -475,9 +475,8 @@ public class TableDefinition<T> { | |||
} | |||
if (typeAdapter != null) { | |||
DataTypeAdapter<?> dta = Utils.newObject(typeAdapter); | |||
dataType = dta.getDataType(); | |||
db.getDialect().registerAdapter(dta); | |||
DataTypeAdapter<?> dtt = db.getDialect().getAdapter(typeAdapter); | |||
dataType = dtt.getDataType(); | |||
} | |||
boolean hasAnnotation = f.isAnnotationPresent(IQColumn.class); | |||
@@ -674,7 +673,7 @@ public class TableDefinition<T> { | |||
// try to interpret and instantiate a default value | |||
value = ModelUtils.getDefaultValue(field, db.getDialect().getDateTimeClass()); | |||
} | |||
Object parameter = db.getDialect().serialize(value); | |||
Object parameter = db.getDialect().serialize(value, field.typeAdapter); | |||
stat.addParameter(parameter); | |||
} | |||
buff.append(')'); | |||
@@ -710,7 +709,7 @@ public class TableDefinition<T> { | |||
// try to interpret and instantiate a default value | |||
value = ModelUtils.getDefaultValue(field, db.getDialect().getDateTimeClass()); | |||
} | |||
Object parameter = db.getDialect().serialize(value); | |||
Object parameter = db.getDialect().serialize(value, field.typeAdapter); | |||
stat.addParameter(parameter); | |||
} | |||
buff.append(')'); | |||
@@ -785,7 +784,7 @@ public class TableDefinition<T> { | |||
buff.appendExceptFirst(", "); | |||
buff.append(db.getDialect().prepareColumnName(field.columnName)); | |||
buff.append(" = ?"); | |||
Object parameter = db.getDialect().serialize(value); | |||
Object parameter = db.getDialect().serialize(value, field.typeAdapter); | |||
stat.addParameter(parameter); | |||
} | |||
} | |||
@@ -1178,7 +1177,7 @@ public class TableDefinition<T> { | |||
} | |||
o = Utils.convertEnum(obj, targetType, def.enumType); | |||
} else { | |||
o = dialect.deserialize(rs, columns[i], targetType); | |||
o = dialect.deserialize(rs, columns[i], targetType, def.typeAdapter); | |||
} | |||
def.setValue(item, o); | |||
} |