package io.trygvis.persistence; import io.trygvis.container.compiler.InternalErrorException; import io.trygvis.container.compiler.model.TypeRef; import java.lang.reflect.Field; import java.sql.Types; import static java.sql.Types.*; public abstract class TypeHandler { private final String sqlType; private final int type; public final boolean nullable; protected TypeHandler(String sqlType, int type, boolean nullable) { this.sqlType = sqlType; this.type = type; this.nullable = nullable; } abstract String setter(int i, String expr); abstract String getter(String rs, int i); public String sqlType(FieldMirror field) { return sqlType; } public int type() { return type; } public final String typeName() { try { int type = type(); for (Field field : Types.class.getFields()) { Object o = field.get(null); if (o != null && o instanceof Integer && o.equals(type)) { return field.getName(); } } } catch (IllegalAccessException e) { throw new InternalErrorException(e); } throw new InternalErrorException("Unknown java.sql.Types: " + type); } // ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- public static class PrimitiveTypeHandler extends TypeHandler { private final String accessor; public PrimitiveTypeHandler(String sqlType, int type, String accessor, boolean nullable) { super(sqlType, type, nullable); this.accessor = accessor; } @Override public String setter(int i, String expr) { return "set" + accessor + "(" + i + ", " + expr + ")"; } @Override public String getter(String rs, int i) { return rs + ".get" + accessor + "(" + i + ")"; } } // public static class OrdinalEnumTypeHandler extends TypeHandler { // private final TypeRef enumType; // public OrdinalEnumTypeHandler(TypeRef enumType) { // super("INTEGER", INTEGER, true); // this.enumType = enumType; // } // // @Override // String setter(int i, String expr) { // return "setInt(" + i + ", " + expr + ".ordinal())"; // } // // @Override // String getter(String rs, int i) { // return "int ordinal = -1; for (Gender v : Gender.values()) if (v.ordinal() == ordinal) return v;"; // int ordinal = -1; for (EnumType v : EnumType.values()) if (v.ordinal() == ordinal) return v; // return enumType.plainName + ".ordinal(" + rs + ".getInt(" + i + "))"; // } // } public static class StringEnumTypeHandler extends TypeHandler { private final TypeRef enumType; public StringEnumTypeHandler(TypeRef enumType) { super("VARCHAR", VARCHAR, true); this.enumType = enumType; } @Override String setter(int i, String expr) { return "setString(" + i + ", " + expr + ".name())"; } @Override String getter(String rs, int i) { return enumType.plainName + ".valueOf(" + rs + ".getString(" + i + "))"; } } // ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- public static class StringTypeHandler extends PrimitiveTypeHandler { protected StringTypeHandler() { super(null, VARCHAR, "String", true); } @Override public String sqlType(FieldMirror field) { return "VARCHAR(1000)"; } } public static class DateTypeHandler extends TypeHandler { protected DateTypeHandler() { super("TIMESTAMP", TIMESTAMP, true); } @Override public String setter(int i, String expr) { return "setTimestamp(" + i + ", new java.sql.Timestamp(" + expr + ".getTime()))"; } @Override public String getter(String rs, int i) { return "new java.util.Date(" + rs + ".getTimestamp(" + i + ").getTime())"; } } public static class JodaDateTimeTypeHandler extends TypeHandler { protected JodaDateTimeTypeHandler() { super("TIMESTAMP", TIMESTAMP, true); } @Override public String setter(int i, String expr) { return "setTimestamp(" + i + ", new java.sql.Timestamp(" + expr + ".getTime()))"; } @Override public String getter(String rs, int i) { return "new org.joda.time.DateTime(" + rs + ".getTimestamp(" + i + ").getTime())"; } } public static class UuidTypeHandler extends PrimitiveTypeHandler { protected UuidTypeHandler() { super("CHAR(36)", CHAR, "String", true); } } }