aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJames Moger <james.moger@gitblit.com>2014-10-06 12:46:50 -0400
committerJames Moger <james.moger@gitblit.com>2014-10-22 22:29:05 -0400
commit6889aa2e367d4658105c1bc2514afccb425770f3 (patch)
tree987102f49e6c6e41facc4dcb7d15db884d49c75b /src
parentecb0c4d4a0f118792c73b1244b389e6a02d00d31 (diff)
downloadiciql-6889aa2e367d4658105c1bc2514afccb425770f3.tar.gz
iciql-6889aa2e367d4658105c1bc2514afccb425770f3.zip
Support generic types for EnumId mapping
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/iciql/Iciql.java65
-rw-r--r--src/main/java/com/iciql/ModelUtils.java24
-rw-r--r--src/main/java/com/iciql/TableDefinition.java82
-rw-r--r--src/main/java/com/iciql/util/Utils.java65
-rw-r--r--src/test/java/com/iciql/test/EnumsTest.java30
-rw-r--r--src/test/java/com/iciql/test/models/EnumModels.java98
6 files changed, 254 insertions, 110 deletions
diff --git a/src/main/java/com/iciql/Iciql.java b/src/main/java/com/iciql/Iciql.java
index 9f73ffa..521e460 100644
--- a/src/main/java/com/iciql/Iciql.java
+++ b/src/main/java/com/iciql/Iciql.java
@@ -171,7 +171,7 @@ import java.lang.annotation.Target;
* <p>
* Automatic model generation: you may automatically generate model classes as
* strings with the Db and DbInspector objects:
- *
+ *
* <pre>
* Db db = Db.open(&quot;jdbc:h2:mem:&quot;, &quot;sa&quot;, &quot;sa&quot;);
* DbInspector inspector = new DbInspector(db);
@@ -179,10 +179,10 @@ import java.lang.annotation.Target;
* inspector.generateModel(schema, table, packageName,
* annotateSchema, trimStrings)
* </pre>
- *
+ *
* Or you may use the GenerateModels tool to generate and save your classes to
* the file system:
- *
+ *
* <pre>
* java -jar iciql.jar
* -url &quot;jdbc:h2:mem:&quot;
@@ -190,10 +190,10 @@ import java.lang.annotation.Target;
* -package packageName -folder destination
* -annotateSchema false -trimStrings true
* </pre>
- *
+ *
* Model validation: you may validate your model class with DbInspector object.
* The DbInspector will report errors, warnings, and suggestions:
- *
+ *
* <pre>
* Db db = Db.open(&quot;jdbc:h2:mem:&quot;, &quot;sa&quot;, &quot;sa&quot;);
* DbInspector inspector = new DbInspector(db);
@@ -208,7 +208,7 @@ public interface Iciql {
/**
* An annotation for an iciql version.
* <p>
- *
+ *
* @IQVersion(1)
*/
@Retention(RetentionPolicy.RUNTIME)
@@ -229,7 +229,7 @@ public interface Iciql {
/**
* An annotation for a schema.
* <p>
- *
+ *
* @IQSchema("PUBLIC")
*/
@Retention(RetentionPolicy.RUNTIME)
@@ -278,9 +278,9 @@ public interface Iciql {
* <li>com.iciql.iciql.IndexType.HASH
* <li>com.iciql.iciql.IndexType.UNIQUE_HASH
* </ul>
- *
+ *
* HASH indexes may only be valid for single column indexes.
- *
+ *
*/
IndexType type() default IndexType.STANDARD;
@@ -307,21 +307,21 @@ public interface Iciql {
public static enum ConstraintUpdateType {
UNSET, CASCADE, RESTRICT, SET_NULL, NO_ACTION, SET_DEFAULT;
}
-
+
/**
* Enumeration defining the deferrability.
*/
public static enum ConstraintDeferrabilityType {
UNSET, DEFERRABLE_INITIALLY_DEFERRED, DEFERRABLE_INITIALLY_IMMEDIATE, NOT_DEFERRABLE;
}
-
+
/**
* A foreign key constraint annotation.
* <p>
* <ul>
* <li>@IQContraintForeignKey(
- * foreignColumns = { "idaccount"},
- * referenceName = "account",
+ * foreignColumns = { "idaccount"},
+ * referenceName = "account",
* referenceColumns = { "id" },
* deleteType = ConstrainDeleteType.CASCADE,
* updateType = ConstraintUpdateType.NO_ACTION )
@@ -372,7 +372,7 @@ public interface Iciql {
* </ul>
*/
ConstraintDeferrabilityType deferrabilityType() default ConstraintDeferrabilityType.UNSET;
-
+
/**
* The source table for the columns defined as foreign.
*/
@@ -391,7 +391,7 @@ public interface Iciql {
* The reference table for the columns defined as references.
*/
String referenceName() default "";
-
+
/**
* Columns defined as 'references'.
* <ul>
@@ -410,7 +410,7 @@ public interface Iciql {
public @interface IQContraintsForeignKey {
IQContraintForeignKey[] value() default {};
}
-
+
/**
* A unique constraint annotation.
* <p>
@@ -447,7 +447,7 @@ public interface Iciql {
public @interface IQContraintsUnique {
IQContraintUnique[] value() default {};
}
-
+
/**
* Annotation to define a view.
*/
@@ -463,7 +463,7 @@ public interface Iciql {
* model class is not annotated with IQView. Default: unspecified.
*/
String name() default "";
-
+
/**
* The source table for the view.
* <p>
@@ -491,7 +491,7 @@ public interface Iciql {
*/
boolean annotationsOnly() default true;
}
-
+
/**
* String snippet defining SQL constraints for a field. Use "this" as
* a placeholder for the column name. "this" will be substituted at
@@ -507,8 +507,8 @@ public interface Iciql {
public @interface IQConstraint {
String value() default "";
- }
-
+ }
+
/**
* Annotation to specify multiple indexes.
*/
@@ -657,7 +657,7 @@ public interface Iciql {
*/
String defaultValue() default "";
- }
+ }
/**
* Interface for using the EnumType.ENUMID enumeration mapping strategy.
@@ -665,19 +665,22 @@ public interface Iciql {
* Enumerations wishing to use EnumType.ENUMID must implement this
* interface.
*/
- public interface EnumId {
- int enumId();
+ public interface EnumId<X> {
+ X enumId();
+ Class<X> enumIdClass();
}
+
+
/**
* Enumeration representing how to map a java.lang.Enum to a column.
* <p>
* <ul>
* <li>NAME - name() : string
* <li>ORDINAL - ordinal() : int
- * <li>ENUMID - enumId() : int
+ * <li>ENUMID - enumId() : X
* </ul>
- *
+ *
* @see com.iciql.Iciql.EnumId interface
*/
public enum EnumType {
@@ -700,14 +703,14 @@ public interface Iciql {
* annotation.
* <p>
* The default mapping is by NAME.
- *
+ *
* <pre>
* IQEnum(EnumType.NAME)
* </pre>
- *
+ *
* A string mapping will generate either a VARCHAR, if IQColumn.length > 0
* or a TEXT column if IQColumn.length == 0
- *
+ *
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.TYPE })
@@ -720,9 +723,9 @@ public interface Iciql {
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
- public @interface IQIgnore{
+ public @interface IQIgnore{
}
-
+
/**
* This method is called to let the table define the primary key, indexes,
* and the table name.
diff --git a/src/main/java/com/iciql/ModelUtils.java b/src/main/java/com/iciql/ModelUtils.java
index 56e6440..c3fd847 100644
--- a/src/main/java/com/iciql/ModelUtils.java
+++ b/src/main/java/com/iciql/ModelUtils.java
@@ -147,7 +147,7 @@ class ModelUtils {
/**
* Returns a SQL type mapping for a Java class.
- *
+ *
* @param fieldDef
* the field to map
* @return
@@ -157,8 +157,14 @@ class ModelUtils {
if (fieldClass.isEnum()) {
switch (fieldDef.enumType) {
case ORDINAL:
- case ENUMID:
return "INT";
+ case ENUMID:
+ String sqlType = SUPPORTED_TYPES.get(fieldDef.enumTypeClass);
+ if (sqlType == null) {
+ throw new IciqlException("Unsupported enum mapping type {0} for {1}",
+ fieldDef.enumTypeClass, fieldDef.columnName);
+ }
+ return sqlType;
case NAME:
default:
return "VARCHAR";
@@ -172,7 +178,7 @@ class ModelUtils {
/**
* Returns the Java class for a given SQL type.
- *
+ *
* @param sqlType
* @param dateTimeClass
* the preferred date class (java.util.Date or
@@ -211,7 +217,7 @@ class ModelUtils {
/**
* Tries to create a convert a SQL table name to a camel case class name.
- *
+ *
* @param tableName
* the SQL table name
* @return the class name
@@ -239,7 +245,7 @@ class ModelUtils {
/**
* Ensures that SQL column names don't collide with Java keywords.
- *
+ *
* @param columnName
* the column name
* @return the Java field name
@@ -254,7 +260,7 @@ class ModelUtils {
/**
* Converts a DEFAULT clause value into an object.
- *
+ *
* @param field
* definition
* @return object
@@ -360,7 +366,7 @@ class ModelUtils {
/**
* Converts the object into a DEFAULT clause value.
- *
+ *
* @param o
* the default object
* @return the value formatted for a DEFAULT clause
@@ -395,7 +401,7 @@ class ModelUtils {
/**
* Checks the formatting of IQColumn.defaultValue().
- *
+ *
* @param defaultValue
* the default value
* @return true if it is
@@ -412,7 +418,7 @@ class ModelUtils {
/**
* Checks to see if the default value matches the class.
- *
+ *
* @param modelClass
* the class
* @param defaultValue
diff --git a/src/main/java/com/iciql/TableDefinition.java b/src/main/java/com/iciql/TableDefinition.java
index e0cc169..0cb1ad2 100644
--- a/src/main/java/com/iciql/TableDefinition.java
+++ b/src/main/java/com/iciql/TableDefinition.java
@@ -37,11 +37,11 @@ import com.iciql.Iciql.EnumId;
import com.iciql.Iciql.EnumType;
import com.iciql.Iciql.IQColumn;
import com.iciql.Iciql.IQConstraint;
+import com.iciql.Iciql.IQContraintForeignKey;
import com.iciql.Iciql.IQContraintUnique;
+import com.iciql.Iciql.IQContraintsForeignKey;
import com.iciql.Iciql.IQContraintsUnique;
import com.iciql.Iciql.IQEnum;
-import com.iciql.Iciql.IQContraintForeignKey;
-import com.iciql.Iciql.IQContraintsForeignKey;
import com.iciql.Iciql.IQIgnore;
import com.iciql.Iciql.IQIndex;
import com.iciql.Iciql.IQIndexes;
@@ -58,7 +58,7 @@ import com.iciql.util.Utils;
/**
* A table definition contains the index definitions of a table, the field
* definitions, the table name, and other meta data.
- *
+ *
* @param <T>
* the table type
*/
@@ -79,7 +79,7 @@ public class TableDefinition<T> {
/**
* The meta data of a constraint on foreign key.
*/
-
+
public static class ConstraintForeignKeyDefinition {
public String constraintName;
@@ -90,18 +90,18 @@ public class TableDefinition<T> {
public ConstraintUpdateType updateType = ConstraintUpdateType.UNSET;
public ConstraintDeferrabilityType deferrabilityType = ConstraintDeferrabilityType.UNSET;
}
-
+
/**
* The meta data of a unique constraint.
*/
-
+
public static class ConstraintUniqueDefinition {
public String constraintName;
public List<String> uniqueColumns;
}
-
-
+
+
/**
* The meta data of a field.
*/
@@ -118,6 +118,7 @@ public class TableDefinition<T> {
boolean nullable;
String defaultValue;
EnumType enumType;
+ Class<?> enumTypeClass;
boolean isPrimitive;
String constraint;
@@ -161,12 +162,12 @@ public class TableDefinition<T> {
throw new IciqlException(e);
}
}
-
+
@Override
public int hashCode() {
return columnName.hashCode();
}
-
+
@Override
public boolean equals(Object o) {
if (o instanceof FieldDefinition) {
@@ -228,7 +229,7 @@ public class TableDefinition<T> {
/**
* Define a primary key by the specified model fields.
- *
+ *
* @param modelFields
* the ordered list of model fields
*/
@@ -239,7 +240,7 @@ public class TableDefinition<T> {
/**
* Define a primary key by the specified column names.
- *
+ *
* @param columnNames
* the ordered list of column names
*/
@@ -270,7 +271,7 @@ public class TableDefinition<T> {
/**
* Defines an index with the specified model fields.
- *
+ *
* @param name
* the index name (optional)
* @param type
@@ -285,7 +286,7 @@ public class TableDefinition<T> {
/**
* Defines an index with the specified column names.
- *
+ *
* @param type
* the index type (STANDARD, HASH, UNIQUE, UNIQUE_HASH)
* @param columnNames
@@ -305,7 +306,7 @@ public class TableDefinition<T> {
/**
* Defines an unique constraint with the specified model fields.
- *
+ *
* @param name
* the constraint name (optional)
* @param modelFields
@@ -318,7 +319,7 @@ public class TableDefinition<T> {
/**
* Defines an unique constraint.
- *
+ *
* @param name
* @param columnNames
*/
@@ -335,7 +336,7 @@ public class TableDefinition<T> {
/**
* Defines a foreign key constraint with the specified model fields.
- *
+ *
* @param name
* the constraint name (optional)
* @param modelFields
@@ -426,7 +427,7 @@ public class TableDefinition<T> {
if (inheritColumns) {
Class<?> superClass = clazz.getSuperclass();
classFields.addAll(Arrays.asList(superClass.getDeclaredFields()));
-
+
if (superClass.isAnnotationPresent(IQView.class)) {
IQView superView = superClass.getAnnotation(IQView.class);
if (superView.inheritColumns()) {
@@ -461,6 +462,7 @@ public class TableDefinition<T> {
boolean trim = false;
boolean nullable = !f.getType().isPrimitive();
EnumType enumType = null;
+ Class<?> enumTypeClass = null;
String defaultValue = "";
String constraint = "";
// configure Java -> SQL enum mapping
@@ -476,6 +478,11 @@ public class TableDefinition<T> {
IQEnum iqenum = f.getAnnotation(IQEnum.class);
enumType = iqenum.value();
}
+
+ if (EnumId.class.isAssignableFrom(f.getType())) {
+ // custom enumid mapping
+ enumTypeClass = ((EnumId<?>) f.getType().getEnumConstants()[0]).enumIdClass();
+ }
}
// try using default object
@@ -515,7 +522,7 @@ public class TableDefinition<T> {
defaultValue = col.defaultValue();
}
}
-
+
boolean hasConstraint = f.isAnnotationPresent(IQConstraint.class);
if (hasConstraint) {
IQConstraint con = f.getAnnotation(IQConstraint.class);
@@ -539,13 +546,14 @@ public class TableDefinition<T> {
fieldDef.nullable = nullable;
fieldDef.defaultValue = defaultValue;
fieldDef.enumType = enumType;
+ fieldDef.enumTypeClass = enumTypeClass;
fieldDef.dataType = ModelUtils.getDataType(fieldDef);
fieldDef.constraint = constraint;
uniqueFields.add(fieldDef);
}
}
fields.addAll(uniqueFields);
-
+
List<String> primaryKey = Utils.newArrayList();
int primitiveBoolean = 0;
for (FieldDefinition fieldDef : fields) {
@@ -623,7 +631,7 @@ public class TableDefinition<T> {
if (!EnumId.class.isAssignableFrom(value.getClass())) {
throw new IciqlException(field.field.getName() + " does not implement EnumId!");
}
- EnumId enumid = (EnumId) value;
+ EnumId<?> enumid = (EnumId<?>) value;
return enumid.enumId();
}
}
@@ -643,7 +651,7 @@ public class TableDefinition<T> {
// return the value unchanged
return value;
}
-
+
PreparedStatement createInsertStatement(Db db, Object obj, boolean returnKey) {
SQLStatement stat = new SQLStatement(db);
StatementBuilder buff = new StatementBuilder("INSERT INTO ");
@@ -896,7 +904,7 @@ public class TableDefinition<T> {
}
}
}
-
+
// create foreign keys constraints
for (ConstraintForeignKeyDefinition constraint : constraintsForeignKey) {
stat = new SQLStatement(db);
@@ -1004,17 +1012,17 @@ public class TableDefinition<T> {
viewTableName = parentView.tableName();
}
}
-
+
if (StringUtils.isNullOrEmpty(viewTableName)) {
// still missing view table name
throw new IciqlException("View model class \"{0}\" is missing a table name!", tableName);
}
}
-
+
// allow control over createTableIfRequired()
createIfRequired = viewAnnotation.create();
}
-
+
if (clazz.isAnnotationPresent(IQIndex.class)) {
// single table index
IQIndex index = clazz.getAnnotation(IQIndex.class);
@@ -1028,7 +1036,7 @@ public class TableDefinition<T> {
addIndex(index);
}
}
-
+
if (clazz.isAnnotationPresent(IQContraintUnique.class)) {
// single table unique constraint
IQContraintUnique constraint = clazz.getAnnotation(IQContraintUnique.class);
@@ -1042,7 +1050,7 @@ public class TableDefinition<T> {
addConstraintUnique(constraint);
}
}
-
+
if (clazz.isAnnotationPresent(IQContraintForeignKey.class)) {
// single table constraint
IQContraintForeignKey constraint = clazz.getAnnotation(IQContraintForeignKey.class);
@@ -1056,7 +1064,7 @@ public class TableDefinition<T> {
addConstraintForeignKey(constraint);
}
}
-
+
}
private void addConstraintForeignKey(IQContraintForeignKey constraint) {
@@ -1064,15 +1072,15 @@ public class TableDefinition<T> {
List<String> referenceColumns = Arrays.asList(constraint.referenceColumns());
addConstraintForeignKey(constraint.name(), foreignColumns, constraint.referenceName(), referenceColumns, constraint.deleteType(), constraint.updateType(), constraint.deferrabilityType());
}
-
+
private void addConstraintUnique(IQContraintUnique constraint) {
List<String> uniqueColumns = Arrays.asList(constraint.uniqueColumns());
addConstraintUnique(constraint.name(), uniqueColumns);
}
-
+
/**
* Defines a foreign key constraint with the specified parameters.
- *
+ *
* @param name
* name of the constraint
* @param foreignColumns
@@ -1119,11 +1127,11 @@ public class TableDefinition<T> {
List<ConstraintUniqueDefinition> getContraintsUnique() {
return constraintsUnique;
}
-
+
List<ConstraintForeignKeyDefinition> getContraintsForeignKey() {
return constraintsForeignKey;
}
-
+
private void initObject(Object obj, Map<Object, FieldDefinition> map) {
for (FieldDefinition def : fields) {
Object newValue = def.initWithNewObject(obj);
@@ -1152,13 +1160,13 @@ public class TableDefinition<T> {
* JaQu assumed that you can always use the integer index of the
* reflectively mapped field definition to determine position in the result
* set.
- *
+ *
* This is not always true.
- *
+ *
* iciql identifies when a select * query is executed and maps column names
* to a column index from the result set. If the select statement is
* explicit, then the standard assumed column index is used instead.
- *
+ *
* @param rs
* @return
*/
diff --git a/src/main/java/com/iciql/util/Utils.java b/src/main/java/com/iciql/util/Utils.java
index 64fe6b3..5b2914a 100644
--- a/src/main/java/com/iciql/util/Utils.java
+++ b/src/main/java/com/iciql/util/Utils.java
@@ -135,8 +135,8 @@ public class Utils {
}
}
throw new IciqlException(e,
- "Missing default constructor? Exception trying to instantiate {0}: {1}",
- clazz.getName(), e.getMessage());
+ "Missing default constructor? Exception trying to instantiate {0}: {1}", clazz.getName(),
+ e.getMessage());
}
}
};
@@ -214,8 +214,7 @@ public class Utils {
}
}
}
- throw new IciqlException(e,
- "Missing default constructor?! Exception trying to instantiate {0}: {1}",
+ throw new IciqlException(e, "Missing default constructor?! Exception trying to instantiate {0}: {1}",
clazz.getName(), e.getMessage());
}
}
@@ -337,7 +336,7 @@ public class Utils {
if (!EnumId.class.isAssignableFrom(o.getClass())) {
throw new IciqlException("Can not convert the enum {0} using ENUMID", o);
}
- EnumId enumid = (EnumId) o;
+ EnumId<?> enumid = (EnumId<?>) o;
return enumid.enumId();
case NAME:
default:
@@ -367,17 +366,39 @@ public class Utils {
}
// find name match
- for (Enum<?> value : values) {
- if (value.name().equalsIgnoreCase(name)) {
- return value;
+ if (type.equals(EnumType.ENUMID)) {
+ // ENUMID mapping
+ for (Enum<?> value : values) {
+ EnumId<?> enumid = (EnumId<?>) value;
+ if (enumid.enumId().equals(name)) {
+ return value;
+ }
+ }
+ } else if (type.equals(EnumType.NAME)) {
+ // standard Enum.name() mapping
+ for (Enum<?> value : values) {
+ if (value.name().equalsIgnoreCase(name)) {
+ return value;
+ }
}
}
} else if (String.class.isAssignableFrom(currentType)) {
// VARCHAR field
String name = (String) o;
- for (Enum<?> value : values) {
- if (value.name().equalsIgnoreCase(name)) {
- return value;
+ if (type.equals(EnumType.ENUMID)) {
+ // ENUMID mapping
+ for (Enum<?> value : values) {
+ EnumId<?> enumid = (EnumId<?>) value;
+ if (enumid.enumId().equals(name)) {
+ return value;
+ }
+ }
+ } else if (type.equals(EnumType.NAME)) {
+ // standard Enum.name() mapping
+ for (Enum<?> value : values) {
+ if (value.name().equalsIgnoreCase(name)) {
+ return value;
+ }
}
}
} else if (Number.class.isAssignableFrom(currentType)) {
@@ -397,8 +418,23 @@ public class Utils {
}
// ENUMID mapping
for (Enum<?> value : values) {
- EnumId enumid = (EnumId) value;
- if (enumid.enumId() == n) {
+ EnumId<?> enumid = (EnumId<?>) value;
+ if (enumid.enumId().equals(n)) {
+ return value;
+ }
+ }
+ }
+ } else {
+ // custom object mapping
+ if (type.equals(EnumType.ENUMID)) {
+ if (!EnumId.class.isAssignableFrom(targetType)) {
+ throw new IciqlException("Can not convert the value {0} from {1} to {2} using ENUMID", o,
+ currentType, targetType);
+ }
+ // ENUMID mapping
+ for (Enum<?> value : values) {
+ EnumId<?> enumid = (EnumId<?>) value;
+ if (enumid.enumId().equals(o)) {
return value;
}
}
@@ -456,8 +492,7 @@ public class Utils {
length = Integer.MAX_VALUE;
}
int block = Math.min(BUFFER_BLOCK_SIZE, length);
- ByteArrayOutputStream out = new ByteArrayOutputStream(length == Integer.MAX_VALUE ? block
- : length);
+ ByteArrayOutputStream out = new ByteArrayOutputStream(length == Integer.MAX_VALUE ? block : length);
byte[] buff = new byte[block];
while (length > 0) {
int len = Math.min(block, length);
diff --git a/src/test/java/com/iciql/test/EnumsTest.java b/src/test/java/com/iciql/test/EnumsTest.java
index d8a0589..8e1f90e 100644
--- a/src/test/java/com/iciql/test/EnumsTest.java
+++ b/src/test/java/com/iciql/test/EnumsTest.java
@@ -31,6 +31,7 @@ import com.iciql.test.models.EnumModels;
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.EnumModels.Genus;
import com.iciql.test.models.EnumModels.Tree;
/**
@@ -58,6 +59,7 @@ public class EnumsTest {
testIntEnums(new EnumIdModel());
testIntEnums(new EnumOrdinalModel());
testStringEnums(new EnumStringModel());
+ testStringEnumIds(new EnumStringModel());
}
private void testIntEnums(EnumModels e) {
@@ -110,7 +112,31 @@ public class EnumsTest {
list = db.from(e).where(e.tree()).between(Tree.MAPLE).and(Tree.PINE).select();
assertEquals(3, list.size());
}
-
+
+ private void testStringEnumIds(EnumModels e) {
+ // ensure all records inserted
+ long count = db.from(e).selectCount();
+ assertEquals(5, count);
+
+ // special case:
+ // value is first enum constant which is also the alias object.
+ // the first enum constant is used as the alias because we can not
+ // instantiate an enum reflectively.
+ EnumModels firstEnumValue = db.from(e).where(e.genus()).is(Genus.PINUS).selectFirst();
+ assertEquals(Tree.PINE, firstEnumValue.tree());
+ assertEquals(Genus.PINUS, firstEnumValue.genus());
+
+ EnumModels model = db.from(e).where(e.genus()).is(Genus.JUGLANS).selectFirst();
+
+ assertEquals(400, model.id.intValue());
+ assertEquals(Tree.WALNUT, model.tree());
+ assertEquals(Genus.JUGLANS, model.genus());
+
+ List<EnumModels> list = db.from(e).where(e.genus()).isNot(Genus.BETULA).select();
+ assertEquals(count - 1, list.size());
+
+ }
+
@Test
public void testMultipleEnumInstances() {
BadEnums b = new BadEnums();
@@ -121,7 +147,7 @@ public class EnumsTest {
assertTrue(e.getMessage(), e.getMessage().startsWith("Can not explicitly reference Tree"));
}
}
-
+
public static class BadEnums {
Tree tree1 = Tree.BIRCH;
Tree tree2 = Tree.MAPLE;
diff --git a/src/test/java/com/iciql/test/models/EnumModels.java b/src/test/java/com/iciql/test/models/EnumModels.java
index a865f6c..2320734 100644
--- a/src/test/java/com/iciql/test/models/EnumModels.java
+++ b/src/test/java/com/iciql/test/models/EnumModels.java
@@ -34,14 +34,14 @@ public abstract class EnumModels {
/**
* Test of @IQEnum annotated enumeration. This strategy is the default
* strategy for all fields of the Tree enum.
- *
+ *
* Individual Tree field declarations can override this strategy by
* specifying a different @IQEnum annotation.
- *
+ *
* Here ORDINAL specifies that this enum will be mapped to an INT column.
*/
@IQEnum(EnumType.ENUMID)
- public enum Tree implements EnumId {
+ public enum Tree implements EnumId<Integer> {
PINE(10), OAK(20), BIRCH(30), WALNUT(40), MAPLE(50);
private int enumid;
@@ -51,9 +51,39 @@ public abstract class EnumModels {
}
@Override
- public int enumId() {
+ public Integer enumId() {
return enumid;
}
+
+ @Override
+ public Class<Integer> enumIdClass() {
+ return Integer.class;
+ }
+
+ }
+
+ /**
+ * Enum for testing custom ENUMID mapping.
+ */
+ @IQEnum(EnumType.ENUMID)
+ public enum Genus implements EnumId<String> {
+ PINUS("pinaceae"), QUERCUS("fagaceae"), BETULA("betulaceae"), JUGLANS("juglandaceae"), ACER("aceraceae");
+
+ private String family;
+
+ Genus(String id) {
+ this.family = id;
+ }
+
+ @Override
+ public String enumId() {
+ return family;
+ }
+
+ @Override
+ public Class<String> enumIdClass() {
+ return String.class;
+ }
}
@IQColumn(primaryKey = true)
@@ -61,6 +91,8 @@ public abstract class EnumModels {
public abstract Tree tree();
+ public abstract Genus genus();
+
/**
* Test model for enum-as-enumid.
*/
@@ -72,12 +104,18 @@ public abstract class EnumModels {
@IQColumn
private Tree tree;
+ // no need to specify ENUMID type as the enumeration definition
+ // specifies it.
+ @IQColumn
+ private Genus genus;
+
public EnumIdModel() {
}
- public EnumIdModel(int id, Tree tree) {
+ public EnumIdModel(int id, Tree tree, Genus genus) {
this.id = id;
this.tree = tree;
+ this.genus = genus;
}
@Override
@@ -85,10 +123,17 @@ public abstract class EnumModels {
return tree;
}
+ @Override
+ public Genus genus() {
+ return genus;
+ }
+
public static List<EnumIdModel> createList() {
- return Arrays.asList(new EnumIdModel(400, Tree.WALNUT), new EnumIdModel(200, Tree.OAK),
- new EnumIdModel(500, Tree.MAPLE), new EnumIdModel(300, Tree.BIRCH), new EnumIdModel(100,
- Tree.PINE));
+ return Arrays.asList(new EnumIdModel(400, Tree.WALNUT, Genus.JUGLANS),
+ new EnumIdModel(200, Tree.OAK, Genus.QUERCUS),
+ new EnumIdModel(500, Tree.MAPLE, Genus.ACER),
+ new EnumIdModel(300, Tree.BIRCH, Genus.BETULA),
+ new EnumIdModel(100, Tree.PINE, Genus.PINUS));
}
}
@@ -103,10 +148,13 @@ public abstract class EnumModels {
@IQColumn
private Tree tree;
+ @IQColumn
+ private Genus genus;
+
public EnumOrdinalModel() {
}
- public EnumOrdinalModel(int id, Tree tree) {
+ public EnumOrdinalModel(int id, Tree tree, Genus genus) {
this.id = id;
this.tree = tree;
}
@@ -116,10 +164,17 @@ public abstract class EnumModels {
return tree;
}
+ @Override
+ public Genus genus() {
+ return genus;
+ }
+
public static List<EnumOrdinalModel> createList() {
- return Arrays.asList(new EnumOrdinalModel(400, Tree.WALNUT), new EnumOrdinalModel(200, Tree.OAK),
- new EnumOrdinalModel(500, Tree.MAPLE), new EnumOrdinalModel(300, Tree.BIRCH),
- new EnumOrdinalModel(100, Tree.PINE));
+ return Arrays.asList(new EnumOrdinalModel(400, Tree.WALNUT, Genus.JUGLANS),
+ new EnumOrdinalModel(200, Tree.OAK, Genus.QUERCUS),
+ new EnumOrdinalModel(500, Tree.MAPLE, Genus.ACER),
+ new EnumOrdinalModel(300, Tree.BIRCH, Genus.BETULA),
+ new EnumOrdinalModel(100, Tree.PINE, Genus.PINUS));
}
}
@@ -135,12 +190,16 @@ public abstract class EnumModels {
@IQColumn(length = 25)
private Tree tree;
+ @IQColumn(trim = true, length = 25)
+ private Genus genus;
+
public EnumStringModel() {
}
- public EnumStringModel(int id, Tree tree) {
+ public EnumStringModel(int id, Tree tree, Genus genus) {
this.id = id;
this.tree = tree;
+ this.genus = genus;
}
@Override
@@ -148,10 +207,17 @@ public abstract class EnumModels {
return tree;
}
+ @Override
+ public Genus genus() {
+ return genus;
+ }
+
public static List<EnumStringModel> createList() {
- return Arrays.asList(new EnumStringModel(400, Tree.WALNUT), new EnumStringModel(200, Tree.OAK),
- new EnumStringModel(500, Tree.MAPLE), new EnumStringModel(300, Tree.BIRCH),
- new EnumStringModel(100, Tree.PINE));
+ return Arrays.asList(new EnumStringModel(400, Tree.WALNUT, Genus.JUGLANS),
+ new EnumStringModel(200, Tree.OAK, Genus.QUERCUS),
+ new EnumStringModel(500, Tree.MAPLE, Genus.ACER),
+ new EnumStringModel(300, Tree.BIRCH, Genus.BETULA),
+ new EnumStringModel(100, Tree.PINE, Genus.PINUS));
}
}
}