diff options
Diffstat (limited to 'src/main')
-rw-r--r-- | src/main/java/com/iciql/Iciql.java | 46 | ||||
-rw-r--r-- | src/main/java/com/iciql/SQLDialectPostgreSQL.java | 33 | ||||
-rw-r--r-- | src/main/java/com/iciql/TableDefinition.java | 18 | ||||
-rw-r--r-- | src/main/java/com/iciql/util/Utils.java | 23 |
4 files changed, 78 insertions, 42 deletions
diff --git a/src/main/java/com/iciql/Iciql.java b/src/main/java/com/iciql/Iciql.java index 05cceeb..524faa8 100644 --- a/src/main/java/com/iciql/Iciql.java +++ b/src/main/java/com/iciql/Iciql.java @@ -657,14 +657,6 @@ public interface Iciql { */
String defaultValue() default "";
- /**
- * Allows specifying a custom data type adapter.
- * <p>
- * For example, you might use this option to map a Postgres JSON column.
- * </p>
- */
- Class<? extends DataTypeAdapter<?>> typeAdapter() default StandardJDBCTypeAdapter.class;
-
}
/**
@@ -741,6 +733,17 @@ public interface Iciql { void defineIQ();
/**
+ * Specify a custom type adapter for a method return type, a class field, or a method
+ * parameter. Type adapters allow you to transform content received from or inserted into
+ * a database field.
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
+ public @interface TypeAdapter {
+ Class<? extends DataTypeAdapter<?>> value();
+ }
+
+ /**
* Interface to allow implementations of custom data type adapters for supporting
* database-specific data types, like the Postgres 'json' or 'xml' types,
* or for supporting other object serialization schemes.
@@ -782,31 +785,4 @@ public interface Iciql { }
- /**
- * The standard type adapter allows iciql to use it's internal utility convert functions
- * to handle the standard JDBC types.
- */
- public final static class StandardJDBCTypeAdapter implements DataTypeAdapter<Object> {
-
- @Override
- public String getDataType() {
- throw new RuntimeException("This adapter is for all standard JDBC types.");
- }
-
- @Override
- public Class<Object> getJavaType() {
- throw new RuntimeException("This adapter is for all standard JDBC types.");
- }
-
- @Override
- public Object serialize(Object value) {
- return value;
- }
-
- @Override
- public Object deserialize(Object value) {
- return value;
- }
-
- }
}
diff --git a/src/main/java/com/iciql/SQLDialectPostgreSQL.java b/src/main/java/com/iciql/SQLDialectPostgreSQL.java index b5ac5c3..f10017c 100644 --- a/src/main/java/com/iciql/SQLDialectPostgreSQL.java +++ b/src/main/java/com/iciql/SQLDialectPostgreSQL.java @@ -140,6 +140,39 @@ public class SQLDialectPostgreSQL extends SQLDialectDefault { }
/**
+ * Handles transforming raw strings to/from the Postgres JSONB data type.
+ */
+ public class JsonbStringAdapter implements DataTypeAdapter<String> {
+
+ @Override
+ public String getDataType() {
+ return "jsonb";
+ }
+
+ @Override
+ public Class<String> getJavaType() {
+ return String.class;
+ }
+
+ @Override
+ public Object serialize(String value) {
+ PGobject pg = new PGobject();
+ pg.setType(getDataType());
+ try {
+ pg.setValue(value);
+ } catch (SQLException e) {
+ // not thrown on base PGobject
+ }
+ return pg;
+ }
+
+ @Override
+ public String deserialize(Object value) {
+ return value.toString();
+ }
+ }
+
+ /**
* Handles transforming raw strings to/from the Postgres XML data type.
*/
public class XmlStringAdapter implements DataTypeAdapter<String> {
diff --git a/src/main/java/com/iciql/TableDefinition.java b/src/main/java/com/iciql/TableDefinition.java index fc83d29..e4fff87 100644 --- a/src/main/java/com/iciql/TableDefinition.java +++ b/src/main/java/com/iciql/TableDefinition.java @@ -51,7 +51,6 @@ import com.iciql.Iciql.IQTable; import com.iciql.Iciql.IQVersion; import com.iciql.Iciql.IQView; import com.iciql.Iciql.IndexType; -import com.iciql.Iciql.StandardJDBCTypeAdapter; import com.iciql.util.IciqlLogger; import com.iciql.util.StatementBuilder; import com.iciql.util.StringUtils; @@ -525,6 +524,17 @@ public class TableDefinition<T> { throw new IciqlException(e, "failed to get default object for {0}", columnName); } + // identify the type adapter + typeAdapter = Utils.getDataTypeAdapter(f.getAnnotations()); + if (typeAdapter == null) { + typeAdapter = Utils.getDataTypeAdapter(f.getType().getAnnotations()); + } + + if (typeAdapter != null) { + DataTypeAdapter<?> dtt = db.getDialect().getAdapter(typeAdapter); + dataType = dtt.getDataType(); + } + boolean hasAnnotation = f.isAnnotationPresent(IQColumn.class); if (hasAnnotation) { IQColumn col = f.getAnnotation(IQColumn.class); @@ -538,12 +548,6 @@ public class TableDefinition<T> { trim = col.trim(); nullable = col.nullable(); - if (col.typeAdapter() != null && col.typeAdapter() != StandardJDBCTypeAdapter.class) { - typeAdapter = col.typeAdapter(); - DataTypeAdapter<?> dtt = db.getDialect().getAdapter(col.typeAdapter()); - dataType = dtt.getDataType(); - } - // annotation overrides if (!StringUtils.isNullOrEmpty(col.defaultValue())) { defaultValue = col.defaultValue(); diff --git a/src/main/java/com/iciql/util/Utils.java b/src/main/java/com/iciql/util/Utils.java index 346c6d7..bf66092 100644 --- a/src/main/java/com/iciql/util/Utils.java +++ b/src/main/java/com/iciql/util/Utils.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.InputStream;
import java.io.Reader;
import java.io.StringWriter;
+import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -40,8 +41,10 @@ import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
+import com.iciql.Iciql.DataTypeAdapter;
import com.iciql.Iciql.EnumId;
import com.iciql.Iciql.EnumType;
+import com.iciql.Iciql.TypeAdapter;
import com.iciql.IciqlException;
/**
@@ -532,4 +535,24 @@ public class Utils { in.close();
}
}
+
+ /**
+ * Identify the data type adapter class in the annotations.
+ *
+ * @param annotations
+ * @return null or the dtaa type adapter class
+ */
+ public static Class<? extends DataTypeAdapter<?>> getDataTypeAdapter(Annotation [] annotations) {
+ Class<? extends DataTypeAdapter<?>> typeAdapter = null;
+ if (annotations != null) {
+ for (Annotation annotation : annotations) {
+ if (annotation instanceof TypeAdapter) {
+ typeAdapter = ((TypeAdapter) annotation).value();
+ } else if (annotation.annotationType().isAnnotationPresent(TypeAdapter.class)) {
+ typeAdapter = annotation.annotationType().getAnnotation(TypeAdapter.class).value();
+ }
+ }
+ }
+ return typeAdapter;
+ }
}
|