summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Moger <james.moger@gmail.com>2011-08-09 11:28:48 -0400
committerJames Moger <james.moger@gmail.com>2011-08-09 11:28:48 -0400
commit1a2339a9f1f96ddca64ab392dd7f9e1621e6c201 (patch)
tree413631f6e46e2bb2826e67f98df5b5180468833b
parentfec6df5eaac334540e220d7f7c05c9d21357f554 (diff)
downloadiciql-1a2339a9f1f96ddca64ab392dd7f9e1621e6c201.tar.gz
iciql-1a2339a9f1f96ddca64ab392dd7f9e1621e6c201.zip
IQTable.primaryKey is now an array. Default values from objects.
Also fixed an error with allowing null objects. Noted rapid churn of iciql in documentation. Changed build constants for next release.
-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() {
+ }
+}