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;