You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2006/12/30 02:38:34 UTC

svn commit: r491148 - in /incubator/openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/conf/ openjpa-project/src/doc/manual/

Author: pcl
Date: Fri Dec 29 17:38:33 2006
New Revision: 491148

URL: http://svn.apache.org/viewvc?view=rev&rev=491148
Log:
submitting patches for OPENJPA-92. I have not tested them aside from compiling and running the regression tests (against Derby).

Added:
    incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/H2Dictionary.java
Modified:
    incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionaryFactory.java
    incubator/openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/conf/localizer.properties
    incubator/openjpa/trunk/openjpa-project/src/doc/manual/supported_databases.xml

Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionaryFactory.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionaryFactory.java?view=diff&rev=491148&r1=491147&r2=491148
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionaryFactory.java (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionaryFactory.java Fri Dec 29 17:38:33 2006
@@ -201,6 +201,12 @@
             return CacheDictionary.class.getName();
         if (prod.indexOf("derby") != -1)
             return DerbyDictionary.class.getName();
+        // test h2 in a special way, because there's a decent chance the string 
+        // h2 could appear in the URL of another database
+        if (prod.indexOf("jdbc:h2:") != -1)
+            return H2Dictionary.class.getName();
+        if (prod.indexOf("h2 database") != -1)
+            return H2Dictionary.class.getName();
         // test db2 last, because there's a decent chance this string could
         // appear in the URL of another database (like if the db is named
         // "testdb2" or something)

Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/H2Dictionary.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/H2Dictionary.java?view=auto&rev=491148
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/H2Dictionary.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/H2Dictionary.java Fri Dec 29 17:38:33 2006
@@ -0,0 +1,230 @@
+package org.apache.openjpa.jdbc.sql;
+
+import java.math.BigDecimal;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Arrays;
+import java.util.Locale;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.PrimaryKey;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.jdbc.schema.Unique;
+import org.apache.openjpa.meta.JavaTypes;
+
+/**
+ * Support for the H2 database ({@link http://www.h2database.com}).
+ *
+ * @since 0.9.7
+ */
+public class H2Dictionary extends DBDictionary {
+
+    public H2Dictionary() {
+        platform = "H2";
+        validationSQL = "CALL 1";
+        closePoolSQL = "SHUTDOWN";
+
+        supportsAutoAssign = true;
+        lastGeneratedKeyQuery = "CALL IDENTITY()";
+        autoAssignClause = "IDENTITY";
+        autoAssignTypeName = "INTEGER";
+        nextSequenceQuery = "CALL NEXT VALUE FOR {0}";
+
+        // CROSS JOIN is currently not supported
+        crossJoinClause = "JOIN";
+        requiresConditionForCrossJoin = true;
+        stringLengthFunction = "LENGTH({0})";
+        trimLeadingFunction = "LTRIM({0})";
+        trimTrailingFunction = "RTRIM({0})";
+        trimBothFunction = "TRIM({0})";
+
+        useSchemaName = true;
+        supportsSelectForUpdate = true;
+        supportsSelectStartIndex = true;
+        supportsSelectEndIndex = true;
+        rangePosition = RANGE_POST_LOCK;
+        supportsDeferredConstraints = false;
+
+        useGetObjectForBlobs = true;
+        blobTypeName = "BLOB";
+        doubleTypeName = "DOUBLE";
+
+        supportsNullTableForGetPrimaryKeys = true;
+        supportsNullTableForGetIndexInfo = true;
+
+        requiresCastForMathFunctions = false;
+        requiresCastForComparisons = false;
+
+        reservedWordSet.addAll(Arrays.asList(new String[] {
+            "CURRENT_TIMESTAMP", "CURRENT_TIME", "CURRENT_DATE", "CROSS",
+            "DISTINCT", "EXCEPT", "EXISTS", "FROM", "FOR", "FALSE", "FULL",
+            "GROUP", "HAVING", "INNER", "INTERSECT", "IS", "JOIN", "LIKE",
+            "MINUS", "NATURAL", "NOT", "NULL", "ON", "ORDER", "PRIMARY",
+            "ROWNUM", "SELECT", "SYSDATE", "SYSTIME", "SYSTIMESTAMP", "TODAY",
+            "TRUE", "UNION", "WHERE" 
+            }));
+    }
+
+    public int getJDBCType(int metaTypeCode, boolean lob) {
+        int type = super.getJDBCType(metaTypeCode, lob);
+        switch (type) {
+        case Types.BIGINT:
+            if (metaTypeCode == JavaTypes.BIGINTEGER)
+                return Types.NUMERIC;
+            break;
+        }
+        return type;
+    }
+
+    public int getPreferredType(int type) {
+        return super.getPreferredType(type);
+    }
+
+    public String[] getAddPrimaryKeySQL(PrimaryKey pk) {
+        return new String[0];
+    }
+
+    public String[] getDropPrimaryKeySQL(PrimaryKey pk) {
+        return new String[0];
+    }
+
+    public String[] getAddColumnSQL(Column column) {
+        return new String[] { 
+            "ALTER TABLE " + getFullName(column.getTable(), false) 
+                + " ADD COLUMN " + getDeclareColumnSQL(column, true) 
+        };
+    }
+
+    public String[] getCreateTableSQL(Table table) {
+        StringBuffer buf = new StringBuffer();
+        buf.append("CREATE TABLE ").append(getFullName(table, false))
+            .append(" (");
+
+        Column[] cols = table.getColumns();
+        for (int i = 0; i < cols.length; i++) {
+            if (i > 0)
+                buf.append(", ");
+            buf.append(getDeclareColumnSQL(cols[i], false));
+        }
+
+        PrimaryKey pk = table.getPrimaryKey();
+        String pkStr;
+        if (pk != null) {
+            pkStr = getPrimaryKeyConstraintSQL(pk);
+            if (!StringUtils.isEmpty(pkStr))
+                buf.append(", ").append(pkStr);
+        }
+
+        Unique[] unqs = table.getUniques();
+        String unqStr;
+        for (int i = 0; i < unqs.length; i++) {
+            unqStr = getUniqueConstraintSQL(unqs[i]);
+            if (unqStr != null)
+                buf.append(", ").append(unqStr);
+        }
+
+        buf.append(")");
+        return new String[] { buf.toString() };
+    }
+
+    protected String getPrimaryKeyConstraintSQL(PrimaryKey pk) {
+        Column[] cols = pk.getColumns();
+        if (cols.length == 1 && cols[0].isAutoAssigned())
+            return null;
+        return super.getPrimaryKeyConstraintSQL(pk);
+    }
+
+    public boolean isSystemIndex(String name, Table table) {
+        return name.toUpperCase(Locale.ENGLISH).startsWith("SYSTEM_");
+    }
+
+    protected String getSequencesSQL(String schemaName, String sequenceName) {
+        StringBuffer buf = new StringBuffer();
+        buf.append("SELECT SEQUENCE_SCHEMA, SEQUENCE_NAME FROM ")
+            .append("INFORMATION_SCHEMA.SEQUENCES");
+        if (schemaName != null || sequenceName != null)
+            buf.append(" WHERE ");
+        if (schemaName != null) {
+            buf.append("SEQUENCE_SCHEMA = ?");
+            if (sequenceName != null)
+                buf.append(" AND ");
+        }
+        if (sequenceName != null)
+            buf.append("SEQUENCE_NAME = ?");
+        return buf.toString();
+    }
+
+    protected SQLBuffer toOperation(String op, SQLBuffer selects,
+        SQLBuffer from, SQLBuffer where, SQLBuffer group, SQLBuffer having,
+        SQLBuffer order, boolean distinct, boolean forUpdate, long start,
+        long end) {
+        return super.toOperation(op, selects, from, where, group, having,
+            order, distinct, forUpdate, start, end);
+    }
+
+    public Column[] getColumns(DatabaseMetaData meta, String catalog,
+        String schemaName, String tableName, String columnName, Connection conn)
+        throws SQLException {
+        Column[] cols = super.getColumns(meta, catalog, schemaName, tableName, 
+            columnName, conn);
+        return cols;
+    }
+
+    public void setDouble(PreparedStatement stmnt, int idx, double val,
+        Column col)
+        throws SQLException {
+        super.setDouble(stmnt, idx, val, col);
+    }
+
+    public void setBigDecimal(PreparedStatement stmnt, int idx, BigDecimal val,
+        Column col)
+        throws SQLException {
+        super.setBigDecimal(stmnt, idx, val, col);
+    }
+
+    protected void appendSelectRange(SQLBuffer buf, long start, long end) {
+        if (end != Long.MAX_VALUE)
+            buf.append(" LIMIT ").appendValue(end - start);
+        if (start != 0)
+            buf.append(" OFFSET ").appendValue(start);
+    }
+
+    public void substring(SQLBuffer buf, FilterValue str, FilterValue start,
+        FilterValue end) {
+        buf.append("SUBSTR(");
+        str.appendTo(buf);
+        buf.append(", (");
+        start.appendTo(buf);
+        buf.append(" + 1)");
+        if (end != null) {
+            buf.append(", (");
+            end.appendTo(buf);
+            buf.append(" - ");
+            start.appendTo(buf);
+            buf.append(")");
+        }
+        buf.append(")");
+    }
+
+    public void indexOf(SQLBuffer buf, FilterValue str, FilterValue find,
+        FilterValue start) {
+        buf.append("(POSITION(");
+        find.appendTo(buf);
+        buf.append(" IN ");
+        if (start != null)
+            substring(buf, str, start, null);
+        else
+            str.appendTo(buf);
+        buf.append(") - 1");
+        if (start != null) {
+            buf.append(" + ");
+            start.appendTo(buf);
+        }
+        buf.append(")");
+    }
+}
\ No newline at end of file

Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/conf/localizer.properties
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/conf/localizer.properties?view=diff&rev=491148&r1=491147&r2=491148
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/conf/localizer.properties (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/conf/localizer.properties Fri Dec 29 17:38:33 2006
@@ -179,6 +179,7 @@
 MappingDefaults-interface: org.apache.openjpa.jdbc.meta.MappingDefaults
 
 ConnectionDriverName-values: org.hsqldb.jdbcDriver,org.hsql.jdbcDriver,\
+	org.h2.Driver,\
 	COM.cloudscape.core.JDBCDriver,in.co.daffodil.db.jdbc.DaffodilDBDriver,\
 	com.ddtek.jdbc.db2.DB2Driver,interbase.interclient.Driver,\
 	com.mysql.jdbc.Driver,com.ddtek.jdbc.oracle.OracleDriver,\
@@ -213,7 +214,7 @@
 	MaxPooledStatements=0,\
 	jdbc:datadirect:sqlserver://<hostname>:1433;SelectMethod=cursor;\
 	DatabaseName=<database>,jdbc:datadirect:sybase://<hostname>:5000,\
-	jdbc:db2://<hostname>/<database>,jdbc:hsqldb:<database>,\
+	jdbc:db2://<hostname>/<database>,jdbc:hsqldb:<database>,jdbc:h2:<database>,\
 	jdbc:idb:<database>.properties,\
 	jdbc:informix-sqli://<hostname>:1526/<database>:INFORMIXSERVER=<database>,\
 	jdbc:interbase://<hostname>//<database>.gdb,\

Modified: incubator/openjpa/trunk/openjpa-project/src/doc/manual/supported_databases.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/supported_databases.xml?view=diff&rev=491148&r1=491147&r2=491148
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/supported_databases.xml (original)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/supported_databases.xml Fri Dec 29 17:38:33 2006
@@ -134,6 +134,20 @@
                 </row>
                 <row>
                     <entry colname="dbname">
+                        H2 Database Engine
+                    </entry>
+                    <entry colname="dbversion">
+                        1.0
+                    </entry>
+                    <entry colname="drivname">
+                        H2
+                    </entry>
+                    <entry colname="drivversion">
+                        1.0
+                    </entry>
+                </row>
+                <row>
+                    <entry colname="dbname">
                         Hypersonic Database Engine
                     </entry>
                     <entry colname="dbversion">
@@ -443,6 +457,32 @@
                 <listitem>
                     <para>
 Only the category 2 non-local driver is supported.
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </section>
+    </section>
+    <section id="dbsupport_h2">
+        <title>
+            H2 Database Engine
+        </title>
+        <example id="example_props_h2">
+            <title>
+                Example properties for H2 Database Engine
+            </title>
+<programlisting>
+openjpa.ConnectionDriverName: org.h2.Driver
+openjpa.ConnectionURL: jdbc:h2:DB_NAME
+</programlisting>
+        </example>
+        <section id="dbsupport_h2_issues">
+            <title>
+                Known issues with H2 Database Engine
+            </title>
+            <itemizedlist>
+                <listitem>
+                    <para>
+H2 does not support cross joins
                     </para>
                 </listitem>
             </itemizedlist>