Allow registration of custom SqlDialects This permits using an odd driver type whose URL isn't standard, a subclass of SqlDialect can be created and registered, making it available to any Database instance. Change-Id: Ia04ee41154161be73c28f35783ad29e9cfc78f46 Signed-off-by: Shawn O. Pearce <sop@google.com>
diff --git a/pom.xml b/pom.xml index 4852e57..f19f4e6 100644 --- a/pom.xml +++ b/pom.xml
@@ -21,7 +21,7 @@ <groupId>gwtorm</groupId> <artifactId>gwtorm</artifactId> <packaging>jar</packaging> - <version>1.1.5</version> + <version>1.1.6</version> <name>gwtorm</name> <description>Tiny ORM</description> <url>http://android.git.kernel.org/?p=tools/gwtorm.git</url>
diff --git a/src/main/java/com/google/gwtorm/jdbc/Database.java b/src/main/java/com/google/gwtorm/jdbc/Database.java index e3d71c1..65d0929 100644 --- a/src/main/java/com/google/gwtorm/jdbc/Database.java +++ b/src/main/java/com/google/gwtorm/jdbc/Database.java
@@ -23,9 +23,6 @@ import com.google.gwtorm.jdbc.gen.SchemaGen; import com.google.gwtorm.schema.SchemaModel; import com.google.gwtorm.schema.java.JavaSchemaModel; -import com.google.gwtorm.schema.sql.DialectH2; -import com.google.gwtorm.schema.sql.DialectMySQL; -import com.google.gwtorm.schema.sql.DialectPostgreSQL; import com.google.gwtorm.schema.sql.SqlDialect; import com.google.gwtorm.server.StandardKeyEncoder; @@ -106,28 +103,14 @@ SqlDialect dialect; try { - final Connection c = ds.getConnection(); + Connection c = ds.getConnection(); try { - final String url = c.getMetaData().getURL(); - if (url.startsWith("jdbc:postgresql:")) { - dialect = new DialectPostgreSQL(); - - } else if (url.startsWith("jdbc:h2:")) { - dialect = new DialectH2(); - - } else if (url.startsWith("jdbc:mysql:")) { - dialect = new DialectMySQL(); - - } else { - throw new OrmException("No dialect known for " + url); - } - - dialect = dialect.refine(c); + dialect = SqlDialect.getDialectFor(c); } finally { c.close(); } } catch (SQLException e) { - throw new OrmException("Unable to determine driver URL", e); + throw new OrmException("Unable to determine SqlDialect", e); } schemaModel = new JavaSchemaModel(schema);
diff --git a/src/main/java/com/google/gwtorm/schema/sql/DialectH2.java b/src/main/java/com/google/gwtorm/schema/sql/DialectH2.java index 971118b..5d0fa59 100644 --- a/src/main/java/com/google/gwtorm/schema/sql/DialectH2.java +++ b/src/main/java/com/google/gwtorm/schema/sql/DialectH2.java
@@ -29,6 +29,11 @@ /** Dialect for <a href="http://www.h2database.com/">H2</a> */ public class DialectH2 extends SqlDialect { @Override + public boolean handles(String url, Connection c) { + return url.startsWith("jdbc:h2:"); + } + + @Override public OrmException convertError(final String op, final String entity, final SQLException err) { switch (getSQLStateInt(err)) {
diff --git a/src/main/java/com/google/gwtorm/schema/sql/DialectMySQL.java b/src/main/java/com/google/gwtorm/schema/sql/DialectMySQL.java index bc787da..f81ad33 100644 --- a/src/main/java/com/google/gwtorm/schema/sql/DialectMySQL.java +++ b/src/main/java/com/google/gwtorm/schema/sql/DialectMySQL.java
@@ -77,6 +77,11 @@ } @Override + public boolean handles(String url, Connection c) { + return url.startsWith("jdbc:mysql:"); + } + + @Override public String getCreateSequenceSql(final SequenceModel seq) { final StringBuilder r = new StringBuilder(); r.append("CREATE TABLE ");
diff --git a/src/main/java/com/google/gwtorm/schema/sql/DialectPostgreSQL.java b/src/main/java/com/google/gwtorm/schema/sql/DialectPostgreSQL.java index e9b323d..32ea333 100644 --- a/src/main/java/com/google/gwtorm/schema/sql/DialectPostgreSQL.java +++ b/src/main/java/com/google/gwtorm/schema/sql/DialectPostgreSQL.java
@@ -36,6 +36,11 @@ } @Override + public boolean handles(String url, Connection c) { + return url.startsWith("jdbc:postgresql:"); + } + + @Override public SqlDialect refine(final Connection c) throws SQLException { final int major = c.getMetaData().getDatabaseMajorVersion(); final int minor = c.getMetaData().getDatabaseMinorVersion();
diff --git a/src/main/java/com/google/gwtorm/schema/sql/SqlDialect.java b/src/main/java/com/google/gwtorm/schema/sql/SqlDialect.java index 0e51db3..e1ea7c3 100644 --- a/src/main/java/com/google/gwtorm/schema/sql/SqlDialect.java +++ b/src/main/java/com/google/gwtorm/schema/sql/SqlDialect.java
@@ -29,10 +29,36 @@ import java.sql.Types; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; public abstract class SqlDialect { + private static final List<SqlDialect> DIALECTS = + new CopyOnWriteArrayList<SqlDialect>(); + + static { + DIALECTS.add(new DialectH2()); + DIALECTS.add(new DialectPostgreSQL()); + DIALECTS.add(new DialectMySQL()); + } + + public static void register(SqlDialect dialect) { + DIALECTS.add(0, dialect); + } + + public static SqlDialect getDialectFor(Connection c) + throws SQLException, OrmException { + String url = c.getMetaData().getURL(); + for (SqlDialect d : DIALECTS) { + if (d.handles(url, c)) { + return d.refine(c); + } + } + throw new OrmException("No dialect known for " + url); + } + protected final Map<Class<?>, SqlTypeInfo> types; protected final Map<Integer, String> typeNames; @@ -58,6 +84,8 @@ typeNames.put(Types.TIMESTAMP, "TIMESTAMP"); } + public abstract boolean handles(String url, Connection c) throws SQLException; + /** Select a better dialect definition for this connection */ public SqlDialect refine(final Connection c) throws SQLException { return this;