mirror of https://github.com/apache/openjpa.git
submitting patches for OPENJPA-92. I have not tested them aside from compiling and running the regression tests (against Derby).
git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@491148 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
4611bf9e43
commit
a255da6f65
|
@ -201,6 +201,12 @@ public class DBDictionaryFactory {
|
||||||
return CacheDictionary.class.getName();
|
return CacheDictionary.class.getName();
|
||||||
if (prod.indexOf("derby") != -1)
|
if (prod.indexOf("derby") != -1)
|
||||||
return DerbyDictionary.class.getName();
|
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
|
// 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
|
// appear in the URL of another database (like if the db is named
|
||||||
// "testdb2" or something)
|
// "testdb2" or something)
|
||||||
|
|
|
@ -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(")");
|
||||||
|
}
|
||||||
|
}
|
|
@ -179,6 +179,7 @@ MappingDefaults-displayorder: 50
|
||||||
MappingDefaults-interface: org.apache.openjpa.jdbc.meta.MappingDefaults
|
MappingDefaults-interface: org.apache.openjpa.jdbc.meta.MappingDefaults
|
||||||
|
|
||||||
ConnectionDriverName-values: org.hsqldb.jdbcDriver,org.hsql.jdbcDriver,\
|
ConnectionDriverName-values: org.hsqldb.jdbcDriver,org.hsql.jdbcDriver,\
|
||||||
|
org.h2.Driver,\
|
||||||
COM.cloudscape.core.JDBCDriver,in.co.daffodil.db.jdbc.DaffodilDBDriver,\
|
COM.cloudscape.core.JDBCDriver,in.co.daffodil.db.jdbc.DaffodilDBDriver,\
|
||||||
com.ddtek.jdbc.db2.DB2Driver,interbase.interclient.Driver,\
|
com.ddtek.jdbc.db2.DB2Driver,interbase.interclient.Driver,\
|
||||||
com.mysql.jdbc.Driver,com.ddtek.jdbc.oracle.OracleDriver,\
|
com.mysql.jdbc.Driver,com.ddtek.jdbc.oracle.OracleDriver,\
|
||||||
|
@ -213,7 +214,7 @@ ConnectionURL-values: jdbc:JSQLConnect://<hostname>/database=<database>,\
|
||||||
MaxPooledStatements=0,\
|
MaxPooledStatements=0,\
|
||||||
jdbc:datadirect:sqlserver://<hostname>:1433;SelectMethod=cursor;\
|
jdbc:datadirect:sqlserver://<hostname>:1433;SelectMethod=cursor;\
|
||||||
DatabaseName=<database>,jdbc:datadirect:sybase://<hostname>:5000,\
|
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:idb:<database>.properties,\
|
||||||
jdbc:informix-sqli://<hostname>:1526/<database>:INFORMIXSERVER=<database>,\
|
jdbc:informix-sqli://<hostname>:1526/<database>:INFORMIXSERVER=<database>,\
|
||||||
jdbc:interbase://<hostname>//<database>.gdb,\
|
jdbc:interbase://<hostname>//<database>.gdb,\
|
||||||
|
|
|
@ -132,6 +132,20 @@ by OpenJPA.
|
||||||
1.0.1
|
1.0.1
|
||||||
</entry>
|
</entry>
|
||||||
</row>
|
</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>
|
<row>
|
||||||
<entry colname="dbname">
|
<entry colname="dbname">
|
||||||
Hypersonic Database Engine
|
Hypersonic Database Engine
|
||||||
|
@ -448,6 +462,32 @@ Only the category 2 non-local driver is supported.
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
</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>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
<section id="dbsupport_hypersonic">
|
<section id="dbsupport_hypersonic">
|
||||||
<title>
|
<title>
|
||||||
Hypersonic
|
Hypersonic
|
||||||
|
|
Loading…
Reference in New Issue