diff options
author | James Moger <james.moger@gitblit.com> | 2014-11-10 11:10:01 -0500 |
---|---|---|
committer | James Moger <james.moger@gitblit.com> | 2014-11-10 21:46:37 -0500 |
commit | c1d81bcdfc948b417964c6b69be2ee5801e5e1c9 (patch) | |
tree | eab491b340179bdf24f7645977977ddb245455c6 /src | |
parent | 4b9a61d0ef0fc2a9230a53a0ade45a20889aa9e3 (diff) | |
download | iciql-c1d81bcdfc948b417964c6b69be2ee5801e5e1c9.tar.gz iciql-c1d81bcdfc948b417964c6b69be2ee5801e5e1c9.zip |
Add support for runtime Mode in the DataTypeAdapters
Diffstat (limited to 'src')
11 files changed, 170 insertions, 21 deletions
diff --git a/src/main/java/com/iciql/Db.java b/src/main/java/com/iciql/Db.java index 13c9260..794417e 100644 --- a/src/main/java/com/iciql/Db.java +++ b/src/main/java/com/iciql/Db.java @@ -41,6 +41,7 @@ import com.iciql.DbUpgrader.DefaultDbUpgrader; import com.iciql.Iciql.IQTable; import com.iciql.Iciql.IQVersion; import com.iciql.Iciql.IQView; +import com.iciql.Iciql.Mode; import com.iciql.util.IciqlLogger; import com.iciql.util.JdbcUtils; import com.iciql.util.StringUtils; @@ -64,6 +65,7 @@ public class Db implements AutoCloseable { private static final Map<String, Class<? extends SQLDialect>> DIALECTS; private final Connection conn; + private final Mode mode; private final Map<Class<?>, TableDefinition<?>> classMap = Collections .synchronizedMap(new HashMap<Class<?>, TableDefinition<?>>()); private final SQLDialect dialect; @@ -88,8 +90,9 @@ public class Db implements AutoCloseable { DIALECTS.put("SQLite", SQLDialectSQLite.class); } - private Db(Connection conn) { + private Db(Connection conn, Mode mode) { this.conn = conn; + this.mode = mode; String databaseName = null; try { DatabaseMetaData data = conn.getMetaData(); @@ -148,50 +151,81 @@ public class Db implements AutoCloseable { } public static Db open(String url) { + return open(url, Mode.PROD); + } + + public static Db open(String url, Mode mode) { try { Connection conn = JdbcUtils.getConnection(null, url, null, null); - return new Db(conn); + return new Db(conn, mode); } catch (SQLException e) { throw new IciqlException(e); } } public static Db open(String url, String user, String password) { + return open(url, user, password, Mode.PROD); + } + + public static Db open(String url, String user, String password, Mode mode) { try { Connection conn = JdbcUtils.getConnection(null, url, user, password); - return new Db(conn); + return new Db(conn, mode); } catch (SQLException e) { throw new IciqlException(e); } } public static Db open(String url, String user, char[] password) { + return open(url, user, password, Mode.PROD); + } + + public static Db open(String url, String user, char[] password, Mode mode) { try { Connection conn = JdbcUtils.getConnection(null, url, user, password == null ? null : new String(password)); - return new Db(conn); + return new Db(conn, mode); } catch (SQLException e) { throw new IciqlException(e); } } + public static Db open(DataSource ds) { + return open(ds, Mode.PROD); + } + /** * Create a new database instance using a data source. This method is fast, * so that you can always call open() / close() on usage. * * @param ds * the data source + * @param mode + * the runtime mode * @return the database instance. */ - public static Db open(DataSource ds) { + public static Db open(DataSource ds, Mode mode) { try { - return new Db(ds.getConnection()); + return new Db(ds.getConnection(), mode); } catch (SQLException e) { throw new IciqlException(e); } } public static Db open(Connection conn) { - return new Db(conn); + return open(conn, Mode.PROD); + } + + public static Db open(Connection conn, Mode mode) { + return new Db(conn, mode); + } + + /** + * Returns the Iciql runtime mode. + * + * @return the runtime mode + */ + public Mode getMode() { + return mode; } /** @@ -806,4 +840,17 @@ public class Db implements AutoCloseable { return this.autoSavePoint; } + /** + * + * @author James Moger + * + */ + class NoExternalDaoStatements implements DaoStatementProvider { + + @Override + public String getStatement(String idOrStatement) { + return idOrStatement; + } + + } } diff --git a/src/main/java/com/iciql/Iciql.java b/src/main/java/com/iciql/Iciql.java index 524faa8..b303372 100644 --- a/src/main/java/com/iciql/Iciql.java +++ b/src/main/java/com/iciql/Iciql.java @@ -727,6 +727,25 @@ public interface Iciql { }
/**
+ * The runtime mode for Iciql.
+ */
+ public static enum Mode {
+
+ DEV, TEST, PROD;
+
+ public static Mode fromValue(String value) {
+
+ for (Mode mode : values()) {
+ if (mode.name().equalsIgnoreCase(value)) {
+ return mode;
+ }
+ }
+
+ return PROD;
+ }
+ }
+
+ /**
* This method is called to let the table define the primary key, indexes,
* and the table name.
*/
@@ -767,6 +786,18 @@ public interface Iciql { */
Class<T> getJavaType();
+
+ /**
+ * Set the runtime mode.
+ * <p>
+ * Allows type adapters to adapt type mappings based on the runtime
+ * mode.
+ * </p>
+ *
+ * @param mode
+ */
+ void setMode(Mode mode);
+
/**
* Serializes your Java object into a JDBC object.
*
diff --git a/src/main/java/com/iciql/SQLDialectDefault.java b/src/main/java/com/iciql/SQLDialectDefault.java index 17ee763..d8a9ebd 100644 --- a/src/main/java/com/iciql/SQLDialectDefault.java +++ b/src/main/java/com/iciql/SQLDialectDefault.java @@ -29,6 +29,7 @@ import java.util.concurrent.ConcurrentHashMap; import com.iciql.Iciql.ConstraintDeleteType; import com.iciql.Iciql.ConstraintUpdateType; import com.iciql.Iciql.DataTypeAdapter; +import com.iciql.Iciql.Mode; import com.iciql.TableDefinition.ConstraintForeignKeyDefinition; import com.iciql.TableDefinition.ConstraintUniqueDefinition; import com.iciql.TableDefinition.FieldDefinition; @@ -50,6 +51,7 @@ public class SQLDialectDefault implements SQLDialect { int databaseMinorVersion; String databaseName; String productVersion; + Mode mode; Map<Class<? extends DataTypeAdapter<?>>, DataTypeAdapter<?>> typeAdapters; public SQLDialectDefault() { @@ -76,6 +78,8 @@ public class SQLDialectDefault implements SQLDialect { } catch (SQLException e) { throw new IciqlException(e, "failed to retrieve database metadata!"); } + + mode = db.getMode(); } @Override @@ -446,12 +450,13 @@ public class SQLDialectDefault implements SQLDialect { @Override public DataTypeAdapter<?> getAdapter(Class<? extends DataTypeAdapter<?>> typeAdapter) { - DataTypeAdapter<?> dtt = typeAdapters.get(typeAdapter); - if (dtt == null) { - dtt = Utils.newObject(typeAdapter); - typeAdapters.put(typeAdapter, dtt); + DataTypeAdapter<?> dta = typeAdapters.get(typeAdapter); + if (dta == null) { + dta = Utils.newObject(typeAdapter); + typeAdapters.put(typeAdapter, dta); } - return dtt; + dta.setMode(mode); + return dta; } @SuppressWarnings("unchecked") @@ -462,19 +467,19 @@ public class SQLDialectDefault implements SQLDialect { return value; } - DataTypeAdapter<T> dtt = (DataTypeAdapter<T>) getAdapter(typeAdapter); - return dtt.serialize(value); + DataTypeAdapter<T> dta = (DataTypeAdapter<T>) getAdapter(typeAdapter); + return dta.serialize(value); } @Override public Object deserialize(Object value, Class<? extends DataTypeAdapter<?>> typeAdapter) { - DataTypeAdapter<?> dtt = typeAdapters.get(typeAdapter); - if (dtt == null) { - dtt = Utils.newObject(typeAdapter); - typeAdapters.put(typeAdapter, dtt); + if (typeAdapter == null) { + // pass-through + return value; } - return dtt.deserialize(value); + DataTypeAdapter<?> dta = getAdapter(typeAdapter); + return dta.deserialize(value); } @Override diff --git a/src/main/java/com/iciql/adapter/GsonTypeAdapter.java b/src/main/java/com/iciql/adapter/GsonTypeAdapter.java index b07b7b5..8d23cfd 100644 --- a/src/main/java/com/iciql/adapter/GsonTypeAdapter.java +++ b/src/main/java/com/iciql/adapter/GsonTypeAdapter.java @@ -18,6 +18,7 @@ package com.iciql.adapter; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.iciql.Iciql.DataTypeAdapter; +import com.iciql.Iciql.Mode; /** * Base class for inserting/retrieving a Java Object (de)serialized as JSON @@ -39,11 +40,18 @@ import com.iciql.Iciql.DataTypeAdapter; */ public abstract class GsonTypeAdapter<T> implements DataTypeAdapter<T> { + protected Mode mode; + protected Gson gson() { return new GsonBuilder().create(); } @Override + public void setMode(Mode mode) { + this.mode = mode; + } + + @Override public String getDataType() { return "TEXT"; } diff --git a/src/main/java/com/iciql/adapter/JavaSerializationTypeAdapter.java b/src/main/java/com/iciql/adapter/JavaSerializationTypeAdapter.java index c475817..df24495 100644 --- a/src/main/java/com/iciql/adapter/JavaSerializationTypeAdapter.java +++ b/src/main/java/com/iciql/adapter/JavaSerializationTypeAdapter.java @@ -25,9 +25,9 @@ import java.io.ObjectOutputStream; import java.sql.Blob; import java.sql.SQLException; -import com.iciql.Iciql; -import com.iciql.IciqlException; import com.iciql.Iciql.DataTypeAdapter; +import com.iciql.Iciql.Mode; +import com.iciql.IciqlException; /** * Base class for inserting/retrieving a Java Object as a BLOB field using Java Serialization. @@ -44,6 +44,13 @@ import com.iciql.Iciql.DataTypeAdapter; */ public abstract class JavaSerializationTypeAdapter<T> implements DataTypeAdapter<T> { + protected Mode mode; + + @Override + public void setMode(Mode mode) { + this.mode = mode; + } + @Override public final String getDataType() { return "BLOB"; diff --git a/src/main/java/com/iciql/adapter/SnakeYamlTypeAdapter.java b/src/main/java/com/iciql/adapter/SnakeYamlTypeAdapter.java index fe4541c..da3b20b 100644 --- a/src/main/java/com/iciql/adapter/SnakeYamlTypeAdapter.java +++ b/src/main/java/com/iciql/adapter/SnakeYamlTypeAdapter.java @@ -21,17 +21,25 @@ import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.nodes.Tag; import com.iciql.Iciql.DataTypeAdapter; +import com.iciql.Iciql.Mode; /** * Base class for inserting/retrieving a Java Object (de)serialized as YAML using SnakeYaml. */ public abstract class SnakeYamlTypeAdapter<T> implements DataTypeAdapter<T> { + protected Mode mode; + protected Yaml yaml() { return new Yaml(); } @Override + public void setMode(Mode mode) { + this.mode = mode; + } + + @Override public String getDataType() { return "TEXT"; } diff --git a/src/main/java/com/iciql/adapter/XStreamTypeAdapter.java b/src/main/java/com/iciql/adapter/XStreamTypeAdapter.java index 5e152df..a554724 100644 --- a/src/main/java/com/iciql/adapter/XStreamTypeAdapter.java +++ b/src/main/java/com/iciql/adapter/XStreamTypeAdapter.java @@ -17,6 +17,7 @@ package com.iciql.adapter; import com.iciql.Iciql.DataTypeAdapter; +import com.iciql.Iciql.Mode; import com.thoughtworks.xstream.XStream; /** @@ -24,11 +25,18 @@ import com.thoughtworks.xstream.XStream; */ public class XStreamTypeAdapter implements DataTypeAdapter<Object> { + protected Mode mode; + protected XStream xstream() { return new XStream(); } @Override + public void setMode(Mode mode) { + this.mode = mode; + } + + @Override public String getDataType() { return "TEXT"; } diff --git a/src/main/java/com/iciql/adapter/postgresql/JsonStringAdapter.java b/src/main/java/com/iciql/adapter/postgresql/JsonStringAdapter.java index c4fbd6a..01d2834 100644 --- a/src/main/java/com/iciql/adapter/postgresql/JsonStringAdapter.java +++ b/src/main/java/com/iciql/adapter/postgresql/JsonStringAdapter.java @@ -20,12 +20,20 @@ import java.sql.SQLException; import org.postgresql.util.PGobject; import com.iciql.Iciql.DataTypeAdapter; +import com.iciql.Iciql.Mode; /** * Handles transforming raw strings to/from the Postgres JSON data type. */ public class JsonStringAdapter implements DataTypeAdapter<String> { + protected Mode mode; + + @Override + public void setMode(Mode mode) { + this.mode = mode; + } + @Override public String getDataType() { return "json"; diff --git a/src/main/java/com/iciql/adapter/postgresql/JsonbStringAdapter.java b/src/main/java/com/iciql/adapter/postgresql/JsonbStringAdapter.java index cc2d9c4..9d7388b 100644 --- a/src/main/java/com/iciql/adapter/postgresql/JsonbStringAdapter.java +++ b/src/main/java/com/iciql/adapter/postgresql/JsonbStringAdapter.java @@ -20,12 +20,20 @@ import java.sql.SQLException; import org.postgresql.util.PGobject; import com.iciql.Iciql.DataTypeAdapter; +import com.iciql.Iciql.Mode; /** * Handles transforming raw strings to/from the Postgres JSONB data type. */ public class JsonbStringAdapter implements DataTypeAdapter<String> { + protected Mode mode; + + @Override + public void setMode(Mode mode) { + this.mode = mode; + } + @Override public String getDataType() { return "jsonb"; diff --git a/src/main/java/com/iciql/adapter/postgresql/XmlStringAdapter.java b/src/main/java/com/iciql/adapter/postgresql/XmlStringAdapter.java index defe9f9..0aea77e 100644 --- a/src/main/java/com/iciql/adapter/postgresql/XmlStringAdapter.java +++ b/src/main/java/com/iciql/adapter/postgresql/XmlStringAdapter.java @@ -20,12 +20,20 @@ import java.sql.SQLException; import org.postgresql.util.PGobject; import com.iciql.Iciql.DataTypeAdapter; +import com.iciql.Iciql.Mode; /** * Handles transforming raw strings to/from the Postgres XML data type. */ public class XmlStringAdapter implements DataTypeAdapter<String> { + protected Mode mode; + + @Override + public void setMode(Mode mode) { + this.mode = mode; + } + @Override public String getDataType() { return "xml"; diff --git a/src/site/dta.mkd b/src/site/dta.mkd index 70fc25e..dc19485 100644 --- a/src/site/dta.mkd +++ b/src/site/dta.mkd @@ -35,6 +35,13 @@ Let's take a look at *InvoiceAdapterImpl*. ---JAVA---
public class InvoiceAdapterImpl implements DataTypeAdapter<Invoice> {
+ Mode mode;
+
+ @Override
+ public void setMode(Mode mode) {
+ this.mode = mode;
+ }
+
@Override
public String getDataType() {
return "jsonb";
@@ -76,6 +83,10 @@ public class InvoiceAdapterImpl implements DataTypeAdapter<Invoice> { Here you can see how the *InvoiceTypeAdapter* defines a [Postgres JSONB data type](http://www.postgresql.org/docs/9.4/static/datatype-json.html) and automatically handles JSON (de)serialization with [Google Gson](https://code.google.com/p/google-gson) so that the database gets the content in a form that it requires but we can continue to work with objects in Java.
+### Runtime Mode
+
+Data type adapters can respond to the Iciql runtime mode (`DEV`, `TEST`, or `PROD`) allowing them to change their behavior. This is useful for targetting a data type that might be available in your production database but may not be available in your development or testing database.
+
### Custom annotations
It is a little verbose to repeat `@TypeAdapter(InvoiceAdapterImpl.class)` everywhere you want to use your adapter.
|