aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build.xml18
-rw-r--r--docs/00_index.mkd2
-rw-r--r--docs/01_model_classes.mkd19
-rw-r--r--docs/05_releases.mkd20
-rw-r--r--docs/resources/iciql.css5
-rw-r--r--src/com/iciql/Constants.java10
-rw-r--r--src/com/iciql/Db.java2
-rw-r--r--src/com/iciql/DbVersion.java2
-rw-r--r--src/com/iciql/Iciql.java69
-rw-r--r--src/com/iciql/IciqlException.java5
-rw-r--r--src/com/iciql/ModelUtils.java45
-rw-r--r--src/com/iciql/TableDefinition.java86
-rw-r--r--src/com/iciql/TableInspector.java48
-rw-r--r--src/com/iciql/util/Utils.java2
-rw-r--r--tests/com/iciql/test/DefaultValuesTest.java61
-rw-r--r--tests/com/iciql/test/models/DefaultValuesModel.java58
16 files changed, 336 insertions, 116 deletions
diff --git a/build.xml b/build.xml
index 2c94cc4..9e54239 100644
--- a/build.xml
+++ b/build.xml
@@ -65,21 +65,6 @@
</filterchain>
</loadfile>
- <!-- extract iciql previous api version from source code -->
- <loadfile property="iq.apiPrevious" srcfile="${basedir}/src/com/iciql/Constants.java">
- <filterchain>
- <linecontains>
- <contains value="public static final String API_PREVIOUS = " />
- </linecontains>
- <striplinebreaks />
- <tokenfilter>
- <replacestring from="public static final String API_PREVIOUS = &quot;" to="" />
- <replacestring from="&quot;;" to="" />
- <trim />
- </tokenfilter>
- </filterchain>
- </loadfile>
-
<property name="library.jar" value="${basedir}/iciql-${iq.version}.jar" />
<property name="javadoc.jar" value="${basedir}/iciql-${iq.version}-javadoc.jar" />
<property name="sources.jar" value="${basedir}/iciql-${iq.version}-sources.jar" />
@@ -140,7 +125,8 @@
<!-- versioning -->
<param name="-since"/> <param name="api/v1.xml"/> <param name="v1" />
- <param name="-since"/> <param name="api/v${iq.apiPrevious}.xml"/> <param name="v${iq.apiPrevious}" />
+ <param name="-since"/> <param name="api/v2.xml"/> <param name="v2" />
+ <param name="-since"/> <param name="api/v3.xml"/> <param name="v3" />
<param name="-apiversion" value="v${iq.apiCurrent}"/>
<param name="-apixml" value="api/v${iq.apiCurrent}.xml"/>
diff --git a/docs/00_index.mkd b/docs/00_index.mkd
index 3371ce2..06bec5b 100644
--- a/docs/00_index.mkd
+++ b/docs/00_index.mkd
@@ -46,6 +46,8 @@ iciql requires a Java 6 Runtime Environment (JRE) or a Java 6 Development Kit (J
### Current Release
+<span class="warning">iciql is undergoing rapid development so api and configuration are subject to change from release to release</span>
+
**%VERSION%** ([zip](http://code.google.com/p/iciql/downloads/detail?name=%ZIP%)|[jar](http://code.google.com/p/iciql/downloads/detail?name=%JAR%)) &nbsp; *released %BUILDDATE%*
issues, binaries, & source @ [Google Code][googlecode]<br/>
diff --git a/docs/01_model_classes.mkd b/docs/01_model_classes.mkd
index 846ef6c..274cb92 100644
--- a/docs/01_model_classes.mkd
+++ b/docs/01_model_classes.mkd
@@ -143,6 +143,7 @@ The recommended approach to setup a model class is to annotate the class and fie
### advantages
- annotated fields may have any scope
+- annotated fields may specify default values
- annotated models support annotated field inheritance making it possible to design a single base class that defines the fields and then create table subclasses that specify the table mappings.
- model runtime dependency is limited to the small, portable `com.iciql.Iciql` class file which contains the annotation definitions
@@ -151,6 +152,24 @@ The recommended approach to setup a model class is to annotate the class and fie
- more verbose model classes
- indexes are defined using "fragile" string column names
- compound primary keys are defined using "fragile" string column names
+
+### default values
+
+You may specify default values for an @IQColumn by either:
+
+1. specifying the default value string within your annotation<br/>
+%BEGINCODE%
+// notice the single ticks!
+@IQColumn(defaultValue="'2000-01-01 00:00:00'")
+Date myDate;
+%ENDCODE%
+2. setting a default object on the field<br/>
+%BEGINCODE%
+@IQColumn
+Date myDate = new Date(100, 0, 1);
+%ENDCODE%
+
+If you want to specify a database-specific variable or function as your default value (e.g. CURRENT_TIMESTAMP) you must do that within the annotation. Also note that the IQColumn.defaultValue must be a well-formatted SQL DEFAULT expression whereas object defaults will be automatically converted to an SQL DEFAULT expression.
### Example Annotated Model
%BEGINCODE%
diff --git a/docs/05_releases.mkd b/docs/05_releases.mkd
index b060fd2..8d1295b 100644
--- a/docs/05_releases.mkd
+++ b/docs/05_releases.mkd
@@ -2,8 +2,26 @@
### Current Release
+<span class="warning">iciql is undergoing rapid development so api and configuration are subject to change from release to release</span>
+
**%VERSION%** ([zip](http://code.google.com/p/iciql/downloads/detail?name=%ZIP%)|[jar](http://code.google.com/p/iciql/downloads/detail?name=%JAR%)) &nbsp; *released %BUILDDATE%*
+- api change release (API v4)
+- allow using objects to assign default values<br/>
+%BEGINCODE%
+// CREATE TABLE ... myDate DATETIME DEFAULT '2000-02-01 00:00:00'
+@IQColumn
+Date myDate = new Date(100, 1, 1);
+%ENDCODE%
+- changed @IQTable.primaryKey definition to use array of column names<br/>
+%BEGINCODE%
+@IQTable( primaryKey = {"name", "nickname"})
+%ENDCODE%
+
+### Older Releases
+
+**0.6.3** &nbsp; *released 2011-08-08*
+
- api change release (API v3)
- finished enum support (issue 4)
- added UUID type support (H2 databases only)
@@ -11,8 +29,6 @@
- added *between(A y).and(A z)* condition syntax
- moved dialects into separate package
-### Older Releases
-
**0.6.2** &nbsp; *released 2011-08-05*
- api change release (API v2)
diff --git a/docs/resources/iciql.css b/docs/resources/iciql.css
index 7f8a48b..3ba942b 100644
--- a/docs/resources/iciql.css
+++ b/docs/resources/iciql.css
@@ -77,6 +77,11 @@ a:hover, a:visited, a:active {
color: #880000;
}
+span.warning {
+ font-weight: bold;
+ color: #f00000;
+}
+
img.logo {
margin-top:-8px;
float: right;
diff --git a/src/com/iciql/Constants.java b/src/com/iciql/Constants.java
index 809c06c..917fcb0 100644
--- a/src/com/iciql/Constants.java
+++ b/src/com/iciql/Constants.java
@@ -25,18 +25,14 @@ public class Constants {
// 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 = "0.6.3";
+ public static final String VERSION = "0.6.4-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 = "2011-08-08";
-
- // 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 = "3";
+ 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_PREVIOUS = "2";
+ public static final String API_CURRENT = "4";
}
diff --git a/src/com/iciql/Db.java b/src/com/iciql/Db.java
index 121e50c..621e825 100644
--- a/src/com/iciql/Db.java
+++ b/src/com/iciql/Db.java
@@ -114,7 +114,7 @@ public class Db {
return TOKENS.get(x);
}
- private static <T> T instance(Class<T> clazz) {
+ static <T> T instance(Class<T> clazz) {
try {
return clazz.newInstance();
} catch (Exception e) {
diff --git a/src/com/iciql/DbVersion.java b/src/com/iciql/DbVersion.java
index ff72ec0..2a8aa44 100644
--- a/src/com/iciql/DbVersion.java
+++ b/src/com/iciql/DbVersion.java
@@ -23,7 +23,7 @@ import com.iciql.Iciql.IQTable;
/**
* A system table to track database and table versions.
*/
-@IQTable(name = "_iq_versions", primaryKey = "schemaName tableName", memoryTable = true)
+@IQTable(name = "_iq_versions", primaryKey = { "schemaName", "tableName"}, memoryTable = true)
public class DbVersion {
@IQColumn(name = "schemaName", length = 255, allowNull = false)
diff --git a/src/com/iciql/Iciql.java b/src/com/iciql/Iciql.java
index 64c2158..2eaf783 100644
--- a/src/com/iciql/Iciql.java
+++ b/src/com/iciql/Iciql.java
@@ -35,7 +35,9 @@ import java.lang.annotation.Target;
* <p>
* Fully Supported Data Types:
* <table>
- * <tr><th colspan="2">All Databases</th></tr>
+ * <tr>
+ * <th colspan="2">All Databases</th>
+ * </tr>
* <tr>
* <td>java.lang.String</td>
* <td>VARCHAR (length > 0) or TEXT (length == 0)</td>
@@ -104,7 +106,9 @@ import java.lang.annotation.Target;
* <td>INT<br/>
* EnumType.ENUMID</td>
* </tr>
- * <tr><th colspan="2">H2 Databases</th></tr>
+ * <tr>
+ * <th colspan="2">H2 Databases</th>
+ * </tr>
* <tr>
* <td>java.util.UUID</td>
* <td>UUID</td>
@@ -117,22 +121,38 @@ import java.lang.annotation.Target;
* 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>
+ * <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
@@ -302,13 +322,13 @@ public interface Iciql {
* then no primary key is set by the IQTable annotation. You may specify
* a composite primary key.
* <ul>
- * <li>primaryKey = "id, name"
- * <li>primaryKey = "id name"
+ * <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 "";
+ String[] primaryKey() default {};
/**
* The inherit columns allows this model class to inherit columns from
@@ -406,6 +426,11 @@ public interface Iciql {
* 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 "";
@@ -435,7 +460,7 @@ public interface Iciql {
*/
public enum EnumType {
NAME, ORDINAL, ENUMID;
-
+
public static final EnumType DEFAULT_TYPE = NAME;
}
diff --git a/src/com/iciql/IciqlException.java b/src/com/iciql/IciqlException.java
index 9f411d9..1e2a890 100644
--- a/src/com/iciql/IciqlException.java
+++ b/src/com/iciql/IciqlException.java
@@ -30,6 +30,11 @@ public class IciqlException extends RuntimeException {
}
+ public IciqlException(Throwable t, String message, Object... parameters) {
+ super(parameters.length > 0 ? MessageFormat.format(message, parameters) : message, t);
+
+ }
+
public IciqlException(Throwable t) {
super(t);
}
diff --git a/src/com/iciql/ModelUtils.java b/src/com/iciql/ModelUtils.java
index 579c7f6..2e42a7d 100644
--- a/src/com/iciql/ModelUtils.java
+++ b/src/com/iciql/ModelUtils.java
@@ -21,14 +21,16 @@ import static com.iciql.util.StringUtils.isNullOrEmpty;
import java.lang.reflect.Method;
import java.math.BigDecimal;
+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.Iciql.EnumType;
import com.iciql.TableDefinition.FieldDefinition;
import com.iciql.util.StringUtils;
@@ -61,7 +63,7 @@ class ModelUtils {
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));
@@ -201,9 +203,9 @@ class ModelUtils {
// do not map from SQL TYPE to primitive type
continue;
}
- if (SUPPORTED_TYPES.get(clazz).equalsIgnoreCase(sqlType)) {
+ if (SUPPORTED_TYPES.get(clazz).equalsIgnoreCase(sqlType)) {
mappedClass = clazz;
-
+
break;
}
}
@@ -253,6 +255,41 @@ class ModelUtils {
}
/**
+ * 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
+ value = ((Number) 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();
+ } else if (Boolean.class.isAssignableFrom(objectClass)) {
+ // BOOLEAN
+ value = o.toString();
+ }
+ if (value == null) {
+ return "''";
+ }
+ return MessageFormat.format("''{0}''", value);
+ }
+
+ /**
* Checks the formatting of IQColumn.defaultValue().
*
* @param defaultValue
diff --git a/src/com/iciql/TableDefinition.java b/src/com/iciql/TableDefinition.java
index 7b3e1e4..6e25c91 100644
--- a/src/com/iciql/TableDefinition.java
+++ b/src/com/iciql/TableDefinition.java
@@ -267,6 +267,7 @@ public class TableDefinition<T> {
classFields.addAll(Arrays.asList(superClass.getDeclaredFields()));
}
+ T defaultObject = Db.instance(clazz);
for (Field f : classFields) {
// default to field name
String columnName = f.getName();
@@ -277,6 +278,21 @@ public class TableDefinition<T> {
boolean allowNull = true;
EnumType enumType = null;
String defaultValue = "";
+ // 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();
+ }
+ }
+
boolean hasAnnotation = f.isAnnotationPresent(IQColumn.class);
if (hasAnnotation) {
IQColumn col = f.getAnnotation(IQColumn.class);
@@ -288,21 +304,29 @@ public class TableDefinition<T> {
maxLength = col.length();
trimString = col.trim();
allowNull = col.allowNull();
- defaultValue = col.defaultValue();
- }
- // 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();
+ // 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);
}
- if (f.isAnnotationPresent(IQEnum.class)) {
- // this instance of the enum is annotated
- IQEnum iqenum = f.getAnnotation(IQEnum.class);
- enumType = iqenum.value();
+
+ // annotation overrides
+ if (!StringUtils.isNullOrEmpty(col.defaultValue())) {
+ defaultValue = col.defaultValue();
}
}
@@ -340,6 +364,9 @@ public class TableDefinition<T> {
*/
private 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;
@@ -352,13 +379,13 @@ public class TableDefinition<T> {
}
return iqenum.name();
case ORDINAL:
- return iqenum.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();
+ return enumid.enumId();
}
}
if (field.trimString && field.maxLength > 0) {
@@ -580,30 +607,6 @@ public class TableDefinition<T> {
return this;
}
- /**
- * Retrieve list of columns from primary key definition.
- *
- * @param index
- * the primary key columns, separated by space
- * @return the column list
- */
- private List<String> getColumns(String index) {
- List<String> cols = Utils.newArrayList();
- if (index == null || index.length() == 0) {
- return null;
- }
- String[] cs = index.split("(,|\\s)");
- for (String c : cs) {
- if (c != null && c.trim().length() > 0) {
- cols.add(c.trim());
- }
- }
- if (cols.size() == 0) {
- return null;
- }
- return cols;
- }
-
void mapObject(Object obj) {
fieldMap.clear();
initObject(obj, fieldMap);
@@ -636,8 +639,9 @@ public class TableDefinition<T> {
}
// setup the primary index, if properly annotated
- List<String> primaryKey = getColumns(tableAnnotation.primaryKey());
- if (primaryKey != null) {
+ if (tableAnnotation.primaryKey().length > 0) {
+ List<String> primaryKey = Utils.newArrayList();
+ primaryKey.addAll(Arrays.asList(tableAnnotation.primaryKey()));
setPrimaryKey(primaryKey);
}
}
diff --git a/src/com/iciql/TableInspector.java b/src/com/iciql/TableInspector.java
index 080e20e..6ec848d 100644
--- a/src/com/iciql/TableInspector.java
+++ b/src/com/iciql/TableInspector.java
@@ -226,11 +226,15 @@ public class TableInspector {
ap.addParameter("name", table);
if (primaryKeys.size() > 1) {
- StringBuilder pk = new StringBuilder();
+ StatementBuilder pk = new StatementBuilder();
+ pk.append("{ ");
for (String key : primaryKeys) {
- pk.append(key).append(' ');
+ pk.appendExceptFirst(", ");
+ pk.append("\"");
+ pk.append(key);
+ pk.append("\"");
}
- pk.trimToSize();
+ pk.append(" }");
ap.addParameter("primaryKey", pk.toString());
}
@@ -328,8 +332,8 @@ public class TableInspector {
// 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 if (clazz.getPackage().getName().equals("java.lang")) {
+ } else if (clazz.equals(byte[].class)) {
} else {
imports.add(clazz.getCanonicalName());
}
@@ -508,13 +512,12 @@ public class TableInspector {
remarks.add(warn(
table,
col,
- format("{0}.maxLength={1}, ColumnMaxLength={2}", IQColumn.class.getSimpleName(),
+ format("{0}.length={1}, ColumnMaxLength={2}", IQColumn.class.getSimpleName(),
fieldDef.maxLength, col.size)));
}
if (fieldDef.maxLength > 0 && !fieldDef.trimString) {
- remarks.add(consider(table, col,
- format("{0}.truncateToMaxLength=true" + " will prevent IciqlExceptions on"
- + " INSERT or UPDATE, but will clip data!", IQColumn.class.getSimpleName())));
+ remarks.add(consider(table, col, format("{0}.trim=true will prevent IciqlExceptions on"
+ + " INSERT or UPDATE, but will clip data!", IQColumn.class.getSimpleName())));
}
}
@@ -523,55 +526,58 @@ public class TableInspector {
remarks.add(warn(
table,
col,
- format("{0}.isAutoIncrement={1}" + " while Column autoIncrement={2}",
+ 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(fieldDef.defaultValue)) {
+ if (!ModelUtils.isProperlyFormattedDefaultValue(defaultValue)) {
remarks.add(error(
table,
col,
format("{0}.defaultValue=\"{1}\"" + " is improperly formatted!",
- IQColumn.class.getSimpleName(), fieldDef.defaultValue))
- .throwError(throwError));
+ IQColumn.class.getSimpleName(), defaultValue)).throwError(throwError));
// next field
return;
}
// compare Model.defaultValue to Column.defaultValue
- if (isNullOrEmpty(fieldDef.defaultValue) && !isNullOrEmpty(col.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(fieldDef.defaultValue) && isNullOrEmpty(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(), fieldDef.defaultValue)));
- } else if (!isNullOrEmpty(fieldDef.defaultValue) && !isNullOrEmpty(col.defaultValue)) {
- if (!fieldDef.defaultValue.equals(col.defaultValue)) {
+ 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(), fieldDef.defaultValue, col.defaultValue)));
+ IQColumn.class.getSimpleName(), defaultValue, col.defaultValue)));
}
}
// sanity check Model.defaultValue literal value
- if (!ModelUtils.isValidDefaultValue(fieldDef.field.getType(), fieldDef.defaultValue)) {
+ if (!ModelUtils.isValidDefaultValue(fieldDef.field.getType(), defaultValue)) {
remarks.add(error(
table,
col,
format("{0}.defaultValue=\"{1}\" is invalid!", IQColumn.class.getSimpleName(),
- fieldDef.defaultValue)));
+ defaultValue)));
}
}
}
diff --git a/src/com/iciql/util/Utils.java b/src/com/iciql/util/Utils.java
index 3237742..fa794cf 100644
--- a/src/com/iciql/util/Utils.java
+++ b/src/com/iciql/util/Utils.java
@@ -116,7 +116,7 @@ public class Utils {
}
}
}
- throw new IciqlException("Exception trying to create " + clazz.getName() + ": " + e, e);
+ throw new IciqlException("Missing default constructor? Exception trying to create " + clazz.getName() + ": " + e, e);
}
}
};
diff --git a/tests/com/iciql/test/DefaultValuesTest.java b/tests/com/iciql/test/DefaultValuesTest.java
new file mode 100644
index 0000000..b39dd7c
--- /dev/null
+++ b/tests/com/iciql/test/DefaultValuesTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+
+import com.iciql.Db;
+import com.iciql.DbInspector;
+import com.iciql.ValidationRemark;
+import com.iciql.test.models.DefaultValuesModel;
+
+/**
+ * Tests default object values.
+ */
+public class DefaultValuesTest {
+
+ @Test
+ public void testDefaultObjectValues() {
+ Db db = Db.open("jdbc:h2:mem:", "sa", "sa");
+
+ // insert random model
+ DefaultValuesModel model = new DefaultValuesModel();
+ db.insert(model);
+
+ DefaultValuesModel v = new DefaultValuesModel();
+
+ // retrieve model and compare
+ DefaultValuesModel retrievedModel = db.from(v).selectFirst();
+ assertTrue(model.myInteger.equals(retrievedModel.myInteger));
+ assertTrue(model.myDate.equals(retrievedModel.myDate));
+ assertTrue(model.myEnumIdTree.equals(retrievedModel.myEnumIdTree));
+ assertTrue(model.myNameTree.equals(retrievedModel.myNameTree));
+ assertTrue(model.myOrdinalTree.equals(retrievedModel.myOrdinalTree));
+ assertTrue(retrievedModel.myNullTree == null);
+
+ DbInspector inspector = new DbInspector(db);
+ List<ValidationRemark> remarks = inspector.validateModel(model, false);
+ db.close();
+ for (ValidationRemark remark : remarks) {
+ System.out.println(remark.toString());
+ }
+ }
+}
diff --git a/tests/com/iciql/test/models/DefaultValuesModel.java b/tests/com/iciql/test/models/DefaultValuesModel.java
new file mode 100644
index 0000000..2669257
--- /dev/null
+++ b/tests/com/iciql/test/models/DefaultValuesModel.java
@@ -0,0 +1,58 @@
+/*
+ * 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.models;
+
+import java.util.Date;
+
+import com.iciql.Iciql.EnumType;
+import com.iciql.Iciql.IQColumn;
+import com.iciql.Iciql.IQEnum;
+import com.iciql.Iciql.IQTable;
+import com.iciql.test.models.EnumModels.Tree;
+
+/**
+ * Default values model.
+ */
+@IQTable(name = "DefaultValuesTest")
+public class DefaultValuesModel {
+
+ @IQColumn(primaryKey = true, autoIncrement = true)
+ public Long myLong;
+
+ @SuppressWarnings("deprecation")
+ @IQColumn
+ public Date myDate = new Date(100, 7, 1);
+
+ @IQColumn
+ public Integer myInteger = 12345;
+
+ @IQColumn
+ public Tree myEnumIdTree = Tree.WALNUT;
+
+ @IQColumn
+ @IQEnum(EnumType.NAME)
+ public Tree myNameTree = Tree.MAPLE;
+
+ @IQColumn
+ @IQEnum(EnumType.ORDINAL)
+ public Tree myOrdinalTree = Tree.PINE;
+
+ @IQColumn(allowNull = true)
+ public Tree myNullTree;
+
+ public DefaultValuesModel() {
+ }
+}