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();
|
||||
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)
|
||||
|
|
|
@ -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
|
||||
|
||||
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 @@ ConnectionURL-values: jdbc:JSQLConnect://<hostname>/database=<database>,\
|
|||
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,\
|
||||
|
|
|
@ -132,6 +132,20 @@ by OpenJPA.
|
|||
1.0.1
|
||||
</entry>
|
||||
</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
|
||||
|
@ -448,6 +462,32 @@ Only the category 2 non-local driver is supported.
|
|||
</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>
|
||||
</section>
|
||||
</section>
|
||||
<section id="dbsupport_hypersonic">
|
||||
<title>
|
||||
Hypersonic
|
||||
|
|
Loading…
Reference in New Issue