mirror of https://github.com/apache/openjpa.git
OPENJPA-2400: MariaDB support
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1501805 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
8cb451d1df
commit
1b1b60c9a7
|
@ -212,6 +212,7 @@ public class JDBCConfigurationImpl
|
|||
"informix", "org.apache.openjpa.jdbc.sql.InformixDictionary",
|
||||
"ingres", "org.apache.openjpa.jdbc.sql.IngresDictionary",
|
||||
"jdatastore", "org.apache.openjpa.jdbc.sql.JDataStoreDictionary",
|
||||
"mariadb", "org.apache.openjpa.jdbc.sql.MariaDBDictionary",
|
||||
"mysql", "org.apache.openjpa.jdbc.sql.MySQLDictionary",
|
||||
"oracle", "org.apache.openjpa.jdbc.sql.OracleDictionary",
|
||||
"pointbase", "org.apache.openjpa.jdbc.sql.PointbaseDictionary",
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.apache.openjpa.conf.BrokerFactoryValue;
|
|||
import org.apache.openjpa.conf.OpenJPAProductDerivation;
|
||||
import org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory;
|
||||
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
|
||||
import org.apache.openjpa.jdbc.sql.MariaDBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MySQLDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.OracleDictionary;
|
||||
import org.apache.openjpa.lib.conf.AbstractProductDerivation;
|
||||
|
@ -74,6 +75,7 @@ public class JDBCProductDerivation extends AbstractProductDerivation
|
|||
_hints.add(PREFIX + ".ResultSetType");
|
||||
_hints.add(PREFIX + ".SubclassFetchMode");
|
||||
|
||||
_hints.add(MariaDBDictionary.SELECT_HINT);
|
||||
_hints.add(MySQLDictionary.SELECT_HINT);
|
||||
_hints.add(OracleDictionary.SELECT_HINT);
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ public class DBDictionaryFactory {
|
|||
public static DBDictionary calculateDBDictionary(JDBCConfiguration conf,
|
||||
String url, String driver, String props) {
|
||||
String dclass = dictionaryClassForString(getProtocol(url), conf);
|
||||
if (dclass == null)
|
||||
if (dclass == null || (dclass != null && dclass.contains("MySQL")))
|
||||
dclass = dictionaryClassForString(driver, conf);
|
||||
if (dclass == null)
|
||||
return null;
|
||||
|
@ -90,11 +90,13 @@ public class DBDictionaryFactory {
|
|||
try {
|
||||
conn = ds.getConnection();
|
||||
DatabaseMetaData meta = conn.getMetaData();
|
||||
String dclass = dictionaryClassForString(meta
|
||||
.getDatabaseProductName(), conf);
|
||||
String dclass = dictionaryClassForString(meta.getDatabaseProductName(), conf);
|
||||
if (dclass == null)
|
||||
dclass = dictionaryClassForString(getProtocol(meta.getURL()),
|
||||
conf);
|
||||
dclass = dictionaryClassForString(getProtocol(meta.getURL()), conf);
|
||||
if (dclass != null && dclass.contains("MySQL")) {
|
||||
// MariaDB returns "MySQL" for product name, need to verify by looking at product version.
|
||||
dclass = dictionaryClassForString(meta.getDatabaseProductVersion(), conf);
|
||||
}
|
||||
if (dclass == null)
|
||||
dclass = DBDictionary.class.getName();
|
||||
return newDBDictionary(conf, dclass, props, conn);
|
||||
|
@ -225,6 +227,8 @@ public class DBDictionaryFactory {
|
|||
return dbdictionaryPlugin.unalias("sqlserver");
|
||||
if (prod.indexOf("jsqlconnect") != -1)
|
||||
return dbdictionaryPlugin.unalias("sqlserver");
|
||||
if (prod.indexOf("mariadb") != -1)
|
||||
return dbdictionaryPlugin.unalias("mariadb");
|
||||
if (prod.indexOf("mysql") != -1)
|
||||
return dbdictionaryPlugin.unalias("mysql");
|
||||
if (prod.indexOf("postgres") != -1)
|
||||
|
|
|
@ -0,0 +1,483 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.jdbc.sql;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
|
||||
import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
|
||||
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
|
||||
import org.apache.openjpa.jdbc.kernel.JDBCStore;
|
||||
import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
|
||||
import org.apache.openjpa.jdbc.schema.Column;
|
||||
import org.apache.openjpa.jdbc.schema.ForeignKey;
|
||||
import org.apache.openjpa.jdbc.schema.Index;
|
||||
import org.apache.openjpa.jdbc.schema.PrimaryKey;
|
||||
import org.apache.openjpa.jdbc.schema.Table;
|
||||
import org.apache.openjpa.util.StoreException;
|
||||
|
||||
/*
|
||||
* Dictionary for MariaDB, based off the MySQLDictionary.
|
||||
*
|
||||
*/
|
||||
public class MariaDBDictionary extends DBDictionary {
|
||||
public static final String SELECT_HINT = "openjpa.hint.MariaDBSelectHint";
|
||||
|
||||
public static final String DELIMITER_BACK_TICK = "`";
|
||||
|
||||
/**
|
||||
* The MySQL table type to use when creating tables; defaults to innodb.
|
||||
*/
|
||||
public String tableType = "innodb";
|
||||
|
||||
/**
|
||||
* Whether to use clobs; defaults to true. Set this to false if you have an
|
||||
* old version of MySQL which does not handle clobs properly.
|
||||
*/
|
||||
public boolean useClobs = true;
|
||||
|
||||
/**
|
||||
* Whether the driver automatically deserializes blobs.
|
||||
*/
|
||||
public boolean driverDeserializesBlobs = false;
|
||||
|
||||
/**
|
||||
* Whether to inline multi-table bulk-delete operations into MySQL's
|
||||
* combined <code>DELETE FROM foo, bar, baz</code> syntax.
|
||||
* Defaults to false, since this may fail in the presence of InnoDB tables
|
||||
* with foreign keys.
|
||||
* @see http://dev.mysql.com/doc/refman/5.0/en/delete.html
|
||||
*/
|
||||
public boolean optimizeMultiTableDeletes = false;
|
||||
|
||||
public static final String tinyBlobTypeName = "TINYBLOB";
|
||||
public static final String mediumBlobTypeName = "MEDIUMBLOB";
|
||||
public static final String longBlobTypeName = "LONGBLOB";
|
||||
|
||||
public MariaDBDictionary() {
|
||||
platform = "MariaDB";
|
||||
validationSQL = "SELECT NOW()";
|
||||
distinctCountColumnSeparator = ",";
|
||||
|
||||
supportsDeferredConstraints = false;
|
||||
constraintNameMode = CONS_NAME_MID;
|
||||
supportsMultipleNontransactionalResultSets = false;
|
||||
requiresAliasForSubselect = true; // new versions
|
||||
requiresTargetForDelete = true;
|
||||
supportsSelectStartIndex = true;
|
||||
supportsSelectEndIndex = true;
|
||||
|
||||
concatenateFunction = "CONCAT({0},{1})";
|
||||
|
||||
maxTableNameLength = 64;
|
||||
maxColumnNameLength = 64;
|
||||
maxIndexNameLength = 64;
|
||||
maxConstraintNameLength = 64;
|
||||
maxIndexesPerTable = 32;
|
||||
schemaCase = SCHEMA_CASE_PRESERVE;
|
||||
|
||||
supportsAutoAssign = true;
|
||||
lastGeneratedKeyQuery = "SELECT LAST_INSERT_ID()";
|
||||
autoAssignClause = "AUTO_INCREMENT";
|
||||
|
||||
clobTypeName = "TEXT";
|
||||
longVarcharTypeName = "TEXT";
|
||||
longVarbinaryTypeName = "LONG VARBINARY";
|
||||
timestampTypeName = "DATETIME";
|
||||
xmlTypeName = "TEXT";
|
||||
fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{
|
||||
"BOOL", "LONG VARBINARY", "MEDIUMBLOB", "LONGBLOB",
|
||||
"TINYBLOB", "LONG VARCHAR", "MEDIUMTEXT", "LONGTEXT", "TEXT",
|
||||
"TINYTEXT", "DOUBLE PRECISION", "ENUM", "SET", "DATETIME",
|
||||
}));
|
||||
reservedWordSet.addAll(Arrays.asList(new String[]{
|
||||
"AUTO_INCREMENT", "BINARY", "BLOB", "CHANGE", "ENUM", "INFILE",
|
||||
"INT1", "INT2", "INT4", "FLOAT1", "FLOAT2", "FLOAT4", "LOAD",
|
||||
"MEDIUMINT", "OUTFILE", "REPLACE", "STARTING", "TEXT", "UNSIGNED",
|
||||
"ZEROFILL", "INDEX",
|
||||
}));
|
||||
|
||||
// reservedWordSet subset that CANNOT be used as valid column names
|
||||
// (i.e., without surrounding them with double-quotes)
|
||||
invalidColumnWordSet.addAll(Arrays.asList(new String[]{
|
||||
"ADD", "ALL", "ALTER", "AND", "AS", "ASC", "BETWEEN", "BINARY",
|
||||
"BLOB", "BOTH", "BY", "CASCADE", "CASE", "CHANGE", "CHAR",
|
||||
"CHARACTER", "CHECK", "COLLATE", "COLUMN", "CONSTRAINT", "CONTINUE",
|
||||
"CONVERT", "CREATE", "CROSS", "CURRENT_DATE", "CURRENT_TIME",
|
||||
"CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", "DEC", "DECIMAL",
|
||||
"DECLARE", "DEFAULT", "DELETE", "DESC", "DESCRIBE", "DISTINCT",
|
||||
"DOUBLE", "DROP", "ELSE", "END-EXEC", "EXISTS", "FALSE", "FETCH",
|
||||
"FLOAT", "FLOAT4", "FOR", "FOREIGN", "FROM", "GRANT", "GROUP",
|
||||
"HAVING", "IN", "INFILE", "INNER", "INSENSITIVE", "INSERT", "INT",
|
||||
"INT1", "INT2", "INT4", "INTEGER", "INTERVAL", "INTO", "IS", "JOIN",
|
||||
"KEY", "LEADING", "LEFT", "LIKE", "LOAD", "MATCH", "MEDIUMINT",
|
||||
"NATURAL", "NOT", "NULL", "NUMERIC", "ON", "OPTION", "OR", "ORDER",
|
||||
"OUTER", "OUTFILE", "PRECISION", "PRIMARY", "PROCEDURE", "READ",
|
||||
"REAL", "REFERENCES", "REPLACE", "RESTRICT", "REVOKE", "RIGHT",
|
||||
"SCHEMA", "SELECT", "SET", "SMALLINT", "SQL", "SQLSTATE",
|
||||
"STARTING", "TABLE", "THEN", "TO", "TRAILING", "TRUE", "UNION",
|
||||
"UNIQUE", "UNSIGNED", "UPDATE", "USAGE", "USING", "VALUES",
|
||||
"VARCHAR", "VARYING", "WHEN", "WHERE", "WITH", "WRITE", "ZEROFILL",
|
||||
"INDEX",
|
||||
}));
|
||||
|
||||
requiresSearchStringEscapeForLike = true;
|
||||
// MariaDB requires double-escape for strings
|
||||
searchStringEscape = "\\\\";
|
||||
|
||||
typeModifierSet.addAll(Arrays.asList(new String[] { "UNSIGNED",
|
||||
"ZEROFILL" }));
|
||||
|
||||
setLeadingDelimiter(DELIMITER_BACK_TICK);
|
||||
setTrailingDelimiter(DELIMITER_BACK_TICK);
|
||||
|
||||
fixedSizeTypeNameSet.remove("NUMERIC");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectedConfiguration(Connection conn) throws SQLException {
|
||||
super.connectedConfiguration(conn);
|
||||
|
||||
DatabaseMetaData metaData = conn.getMetaData();
|
||||
int maj = 0;
|
||||
int min = 0;
|
||||
try {
|
||||
// The product version looks like 4.1.3-nt or 5.1.30
|
||||
String productVersion = metaData.getDatabaseProductVersion();
|
||||
int[] versions = getMajorMinorVersions(productVersion);
|
||||
maj = versions[0];
|
||||
min = versions[1];
|
||||
} catch (IllegalArgumentException e) {
|
||||
// we don't understand the version format.
|
||||
// That is ok. We just take the default values.
|
||||
if (log.isWarnEnabled())
|
||||
log.warn(e.toString(), e);
|
||||
}
|
||||
|
||||
supportsXMLColumn = true;
|
||||
}
|
||||
|
||||
protected void setDelimitedCase(DatabaseMetaData metaData) {
|
||||
// Determination of case sensitivity is not accurate; MariaDB JIRA CONJ-55
|
||||
delimitedCase = SCHEMA_CASE_PRESERVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection decorate(Connection conn) throws SQLException {
|
||||
conn = super.decorate(conn);
|
||||
return conn;
|
||||
}
|
||||
|
||||
private static int[] getMajorMinorVersions(String versionStr)
|
||||
throws IllegalArgumentException {
|
||||
int beginIndex = 0;
|
||||
|
||||
versionStr = versionStr.trim();
|
||||
char[] charArr = versionStr.toCharArray();
|
||||
for (int i = 0; i < charArr.length; i++) {
|
||||
if (Character.isDigit(charArr[i])) {
|
||||
beginIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int endIndex = charArr.length;
|
||||
for (int i = beginIndex+1; i < charArr.length; i++) {
|
||||
if (charArr[i] != '.' && !Character.isDigit(charArr[i])) {
|
||||
endIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
String[] arr = versionStr.substring(beginIndex, endIndex).split("\\.");
|
||||
if (arr.length < 2)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
int maj = Integer.parseInt(arr[0]);
|
||||
int min = Integer.parseInt(arr[1]);
|
||||
return new int[]{maj, min};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getCreateTableSQL(Table table) {
|
||||
String[] sql = super.getCreateTableSQL(table);
|
||||
if (!StringUtils.isEmpty(tableType))
|
||||
sql[0] = sql[0] + " ENGINE = " + tableType;
|
||||
return sql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDropIndexSQL(Index index) {
|
||||
return new String[]{ "DROP INDEX " + getFullName(index) + " ON "
|
||||
+ getFullName(index.getTable(), false) };
|
||||
}
|
||||
|
||||
/**
|
||||
* Return <code>ALTER TABLE <table name> DROP PRIMARY KEY</code>.
|
||||
*/
|
||||
@Override
|
||||
public String[] getDropPrimaryKeySQL(PrimaryKey pk) {
|
||||
if (DBIdentifier.isNull(pk.getIdentifier()))
|
||||
return new String[0];
|
||||
return new String[]{ "ALTER TABLE "
|
||||
+ getFullName(pk.getTable(), false)
|
||||
+ " DROP PRIMARY KEY" };
|
||||
}
|
||||
|
||||
/**
|
||||
* Return <code>ALTER TABLE <table name> DROP FOREIGN KEY
|
||||
* <fk name></code>.
|
||||
*/
|
||||
@Override
|
||||
public String[] getDropForeignKeySQL(ForeignKey fk, Connection conn) {
|
||||
if (DBIdentifier.isNull(fk.getIdentifier())) {
|
||||
DBIdentifier fkName = fk.loadIdentifierFromDB(this,conn);
|
||||
String[] retVal = (fkName == null) ? new String[0] :
|
||||
new String[]{ "ALTER TABLE "
|
||||
+ getFullName(fk.getTable(), false)
|
||||
+ " DROP FOREIGN KEY " + toDBName(fkName) };
|
||||
return retVal;
|
||||
}
|
||||
return new String[]{ "ALTER TABLE "
|
||||
+ getFullName(fk.getTable(), false)
|
||||
+ " DROP FOREIGN KEY " + toDBName(fk.getIdentifier()) };
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAddPrimaryKeySQL(PrimaryKey pk) {
|
||||
String[] sql = super.getAddPrimaryKeySQL(pk);
|
||||
|
||||
// mysql requires that a column be declared NOT NULL before
|
||||
// it can be made a primary key.
|
||||
Column[] cols = pk.getColumns();
|
||||
String[] ret = new String[cols.length + sql.length];
|
||||
for (int i = 0; i < cols.length; i++) {
|
||||
ret[i] = "ALTER TABLE " + getFullName(cols[i].getTable(), false)
|
||||
+ " CHANGE " + toDBName(cols[i].getIdentifier())
|
||||
+ " " + toDBName(cols[i].getIdentifier()) // name twice
|
||||
+ " " + getTypeName(cols[i]) + " NOT NULL";
|
||||
}
|
||||
|
||||
System.arraycopy(sql, 0, ret, cols.length, sql.length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDeleteTableContentsSQL(Table[] tables,Connection conn) {
|
||||
// mysql >= 4 supports more-optimal delete syntax
|
||||
if (!optimizeMultiTableDeletes)
|
||||
return super.getDeleteTableContentsSQL(tables,conn);
|
||||
else {
|
||||
StringBuilder buf = new StringBuilder(tables.length * 8);
|
||||
buf.append("DELETE FROM ");
|
||||
for (int i = 0; i < tables.length; i++) {
|
||||
buf.append(toDBName(tables[i].getFullIdentifier()));
|
||||
if (i < tables.length - 1)
|
||||
buf.append(", ");
|
||||
}
|
||||
return new String[] { buf.toString() };
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendSelectRange(SQLBuffer buf, long start, long end,
|
||||
boolean subselect) {
|
||||
buf.append(" LIMIT ").appendValue(start).append(", ");
|
||||
if (end == Long.MAX_VALUE)
|
||||
buf.appendValue(Long.MAX_VALUE);
|
||||
else
|
||||
buf.appendValue(end - start);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Column newColumn(ResultSet colMeta)
|
||||
throws SQLException {
|
||||
Column col = super.newColumn(colMeta);
|
||||
if (col.isNotNull() && "0".equals(col.getDefaultString()))
|
||||
col.setDefaultString(null);
|
||||
return col;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getBlobObject(ResultSet rs, int column, JDBCStore store)
|
||||
throws SQLException {
|
||||
// if the user has set a get-blob strategy explicitly or the driver
|
||||
// does not automatically deserialize, delegate to super
|
||||
if (useGetBytesForBlobs || useGetObjectForBlobs || !driverDeserializesBlobs)
|
||||
return super.getBlobObject(rs, column, store);
|
||||
|
||||
// most mysql drivers deserialize on getObject
|
||||
return rs.getObject(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPreferredType(int type) {
|
||||
if (type == Types.CLOB && !useClobs)
|
||||
return Types.LONGVARCHAR;
|
||||
return super.getPreferredType(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append XML comparison.
|
||||
*
|
||||
* @param buf the SQL buffer to write the comparison
|
||||
* @param op the comparison operation to perform
|
||||
* @param lhs the left hand side of the comparison
|
||||
* @param rhs the right hand side of the comparison
|
||||
* @param lhsxml indicates whether the left operand maps to XML
|
||||
* @param rhsxml indicates whether the right operand maps to XML
|
||||
*/
|
||||
@Override
|
||||
public void appendXmlComparison(SQLBuffer buf, String op, FilterValue lhs,
|
||||
FilterValue rhs, boolean lhsxml, boolean rhsxml) {
|
||||
super.appendXmlComparison(buf, op, lhs, rhs, lhsxml, rhsxml);
|
||||
if (lhsxml)
|
||||
appendXmlValue(buf, lhs);
|
||||
else
|
||||
lhs.appendTo(buf);
|
||||
buf.append(" ").append(op).append(" ");
|
||||
if (rhsxml)
|
||||
appendXmlValue(buf, rhs);
|
||||
else
|
||||
rhs.appendTo(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append XML column value so that it can be used in comparisons.
|
||||
*
|
||||
* @param buf the SQL buffer to write the value
|
||||
* @param val the value to be written
|
||||
*/
|
||||
private void appendXmlValue(SQLBuffer buf, FilterValue val) {
|
||||
buf.append("ExtractValue(").
|
||||
append(val.getColumnAlias(val.getFieldMapping().getColumns()[0])).
|
||||
append(",'/*/");
|
||||
val.appendTo(buf);
|
||||
buf.append("')");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBatchFetchSize(int batchFetchSize) {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if we have set the {@link #SELECT_HINT} in the
|
||||
* fetch configuration, and if so, append the MySQL hint after the
|
||||
* "SELECT" part of the query.
|
||||
*/
|
||||
@Override
|
||||
public String getSelectOperation(JDBCFetchConfiguration fetch) {
|
||||
Object hint = fetch == null ? null : fetch.getHint(SELECT_HINT);
|
||||
String select = "SELECT";
|
||||
if (hint != null)
|
||||
select += " " + hint;
|
||||
return select;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<String> getSelectTableAliases(Select sel) {
|
||||
Set<String> result = new HashSet<String>();
|
||||
List<String> selects = sel.getIdentifierAliases();
|
||||
for (String s : selects) {
|
||||
String tableAlias = s.substring(0, s.indexOf('.'));
|
||||
result.add(tableAlias);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int matchErrorState(Map<Integer,Set<String>> errorStates, SQLException ex) {
|
||||
int state = super.matchErrorState(errorStates, ex);
|
||||
|
||||
if (state == StoreException.GENERAL &&
|
||||
ex.getNextException() != null &&
|
||||
"JZ0002".equalsIgnoreCase(ex.getNextException().getSQLState())) {
|
||||
if (conf != null && conf.getLockTimeout() != -1) {
|
||||
state = StoreException.LOCK;
|
||||
} else {
|
||||
state = StoreException.QUERY;
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFatalException(int subtype, SQLException ex) {
|
||||
if ((subtype == StoreException.LOCK && ex.getErrorCode() == 1205)
|
||||
||(subtype == StoreException.LOCK && "JZ0002".equalsIgnoreCase(ex.getSQLState()))
|
||||
||(subtype == StoreException.QUERY && ex.getErrorCode() == 1317)) {
|
||||
return false;
|
||||
}
|
||||
if (ex.getErrorCode() == 0 && ex.getSQLState() == null)
|
||||
return false;
|
||||
return super.isFatalException(subtype, ex);
|
||||
}
|
||||
|
||||
/**
|
||||
* OPENJPA-740 Special case for MySql special column types,
|
||||
* like LONGTEXT, LONGBLOG etc..
|
||||
* @see org.apache.openjpa.jdbc.sql.DBDictionary#getTypeName(org.apache.openjpa.jdbc.schema.Column)
|
||||
*/
|
||||
@Override
|
||||
public String getTypeName(Column col) {
|
||||
// handle blobs differently, if the DBItentifierType is NULL (e.g. no column definition is set).
|
||||
if (col.getType() == Types.BLOB && col.getTypeIdentifier().getType() == DBIdentifierType.NULL) {
|
||||
if (col.getSize() <= 0) // unknown size
|
||||
return blobTypeName; // return old default of 64KB
|
||||
else if (col.getSize() <= 255)
|
||||
return tinyBlobTypeName;
|
||||
else if (col.getSize() <= 65535)
|
||||
return blobTypeName; // old default of 64KB
|
||||
else if (col.getSize() <= 16777215)
|
||||
return mediumBlobTypeName;
|
||||
else
|
||||
return longBlobTypeName;
|
||||
} else {
|
||||
return super.getTypeName(col);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void indexOf(SQLBuffer buf, FilterValue str, FilterValue find,
|
||||
FilterValue start) {
|
||||
buf.append("LOCATE(");
|
||||
find.appendTo(buf);
|
||||
buf.append(", ");
|
||||
str.appendTo(buf);
|
||||
if (start != null) {
|
||||
buf.append(", ");
|
||||
start.appendTo(buf);
|
||||
}
|
||||
buf.append(")");
|
||||
}
|
||||
}
|
|
@ -206,7 +206,8 @@ ConnectionDriverName-values: org.hsqldb.jdbcDriver,org.hsql.jdbcDriver,\
|
|||
weblogic.jdbc.mssqlserver4.Driver,com.mysql.jdbc.DatabaseMetaData,\
|
||||
org.gjt.mm.mysql.Driver,com.sap.dbtech.jdbc.DriverSapDB,\
|
||||
com.sybase.jdbc2.jdbc.SybDriver,com.sybase.jdbc.SybDriver,\
|
||||
com.internetcds.jdbc.tds.Driver,weblogic.jdbc.pool.Driver
|
||||
com.internetcds.jdbc.tds.Driver,weblogic.jdbc.pool.Driver,\
|
||||
org.mariadb.jdbc.Driver,org.mariadb.jdbc.DatabaseMetaData
|
||||
ConnectionURL-values: jdbc:JSQLConnect://<hostname>/database=<database>,\
|
||||
jdbc:cloudscape:<database>;create=true,\
|
||||
jdbc:twtds:sqlserver://<hostname>/<database>,\
|
||||
|
|
|
@ -162,7 +162,16 @@
|
|||
<optimistic></optimistic>
|
||||
<query>70100</query>
|
||||
</dictionary>
|
||||
|
||||
|
||||
<dictionary class="org.apache.openjpa.jdbc.sql.MariaDBDictionary">
|
||||
<lock>41000</lock>
|
||||
<referential-integrity>630,839,840,893,1062,1169,1215,1216,1217,1451,1452,1557</referential-integrity>
|
||||
<object-exists>23000</object-exists>
|
||||
<object-not-found></object-not-found>
|
||||
<optimistic></optimistic>
|
||||
<query>70100</query>
|
||||
</dictionary>
|
||||
|
||||
<dictionary class="org.apache.openjpa.jdbc.sql.OracleDictionary">
|
||||
<lock>42000,61000,72000</lock>
|
||||
<referential-integrity>1,1400,1722,2291,2292</referential-integrity>
|
||||
|
|
|
@ -118,6 +118,35 @@
|
|||
<dbcp.minIdle>0</dbcp.minIdle>
|
||||
</properties>
|
||||
</profile>
|
||||
|
||||
<!-- Profile for testing with MariaDB DB -->
|
||||
<profile>
|
||||
<id>test-mariadb</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>test-mariadb</name>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>mariadb</groupId>
|
||||
<artifactId>mariadb-connector-java</artifactId>
|
||||
<version>${mariadb.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<connection.driver.name>org.mariadb.jdbc.Driver</connection.driver.name>
|
||||
<!--<connection.url>jdbc:mysql://localhost/OPENJPA</connection.url>-->
|
||||
<connection.url>${openjpa.mariadb.url}</connection.url>
|
||||
<connection.username>${openjpa.mariadb.username}</connection.username>
|
||||
<connection.password>${openjpa.mariadb.password}</connection.password>
|
||||
<jdbc.DBDictionary />
|
||||
<!-- DBCP overrides for MariaDB testing -->
|
||||
<dbcp.maxIdle>0</dbcp.maxIdle>
|
||||
<dbcp.minIdle>0</dbcp.minIdle>
|
||||
</properties>
|
||||
</profile>
|
||||
|
||||
<!-- Profile for testing with PostgreSQL DB -->
|
||||
<profile>
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.apache.openjpa.conf.OpenJPAProductDerivation;
|
|||
import org.apache.openjpa.conf.Specification;
|
||||
import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
|
||||
import org.apache.openjpa.jdbc.kernel.JDBCStoreManager;
|
||||
import org.apache.openjpa.jdbc.sql.MariaDBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MySQLDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.OracleDictionary;
|
||||
import org.apache.openjpa.lib.conf.AbstractProductDerivation;
|
||||
|
@ -127,6 +128,7 @@ public class JDBCPersistenceProductDerivation
|
|||
_hints.add("openjpa.FetchPlan.ResultSetType");
|
||||
_hints.add("openjpa.FetchPlan.SubclassFetchMode");
|
||||
|
||||
_hints.add(MariaDBDictionary.SELECT_HINT);
|
||||
_hints.add(MySQLDictionary.SELECT_HINT);
|
||||
_hints.add(OracleDictionary.SELECT_HINT);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.apache.openjpa.conf;
|
|||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.apache.openjpa.jdbc.sql.MariaDBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MySQLDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.OracleDictionary;
|
||||
import org.apache.openjpa.kernel.QueryHints;
|
||||
|
@ -51,6 +52,7 @@ public class TestQueryHints extends SingleEMFTestCase {
|
|||
public void testSupportedHintsContainProductDerivationHints() {
|
||||
assertSupportedHint(OracleDictionary.SELECT_HINT, true);
|
||||
assertSupportedHint(MySQLDictionary.SELECT_HINT, true);
|
||||
assertSupportedHint(MariaDBDictionary.SELECT_HINT, true);
|
||||
}
|
||||
|
||||
public void testSupportedHintsContainFetchPlanHints() {
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.apache.commons.lang.StringUtils;
|
|||
import org.apache.openjpa.conf.OpenJPAConfiguration;
|
||||
import org.apache.openjpa.datacache.DataCachePCData;
|
||||
import org.apache.openjpa.jdbc.sql.DB2Dictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MariaDBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MySQLDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.OracleDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.SQLServerDictionary;
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
|
|||
import org.apache.openjpa.jdbc.meta.ClassMapping;
|
||||
import org.apache.openjpa.jdbc.schema.Column;
|
||||
import org.apache.openjpa.jdbc.schema.Table;
|
||||
import org.apache.openjpa.jdbc.sql.MariaDBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MySQLDictionary;
|
||||
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
||||
|
||||
|
@ -41,7 +42,7 @@ public class TestBlobColumnType extends SingleEMFTestCase {
|
|||
// need to do this without BlobColumnEntity.class since it contains a column definition which might
|
||||
// not work with all databases.
|
||||
super.setUp((Object) null);
|
||||
if (!(getDBDictionary() instanceof MySQLDictionary)) {
|
||||
if (!(getDBDictionary() instanceof MySQLDictionary || getDBDictionary() instanceof MariaDBDictionary)) {
|
||||
// normal teardown will take care of the EMF.
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -106,6 +106,7 @@ public abstract class AbstractTestCase extends AbstractCachedEMFTestCase {
|
|||
EMPRESS,
|
||||
HYPERSONIC,
|
||||
POSTGRESQL,
|
||||
MARIADB,
|
||||
MYSQL,
|
||||
SQLSERVER,
|
||||
DB2,
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
|
|||
import org.apache.openjpa.jdbc.sql.DBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.DerbyDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.HSQLDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MariaDBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MySQLDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.OracleDictionary;
|
||||
import org.apache.openjpa.lib.jdbc.JDBCListener;
|
||||
|
@ -186,7 +187,7 @@ public abstract class AbstractCriteriaTestCase extends TestCase {
|
|||
cSQL.size());
|
||||
}
|
||||
|
||||
if (!(dict instanceof DerbyDictionary || dict instanceof MySQLDictionary))
|
||||
if (!(dict instanceof DerbyDictionary || dict instanceof MySQLDictionary || dict instanceof MariaDBDictionary))
|
||||
return;
|
||||
|
||||
for (int i = 0; i < jSQL.size(); i++) {
|
||||
|
@ -219,7 +220,7 @@ public abstract class AbstractCriteriaTestCase extends TestCase {
|
|||
fail("JPQL " + jpql + " failed to execute\r\n" + w);
|
||||
}
|
||||
|
||||
if (!(dict instanceof DerbyDictionary || dict instanceof MySQLDictionary))
|
||||
if (!(dict instanceof DerbyDictionary || dict instanceof MySQLDictionary || dict instanceof MariaDBDictionary))
|
||||
return;
|
||||
|
||||
for (int i = 0; i < jSQL.size(); i++) {
|
||||
|
@ -242,7 +243,7 @@ public abstract class AbstractCriteriaTestCase extends TestCase {
|
|||
fail(w.toString());
|
||||
}
|
||||
|
||||
if (!(dict instanceof DerbyDictionary || dict instanceof MySQLDictionary))
|
||||
if (!(dict instanceof DerbyDictionary || dict instanceof MySQLDictionary || dict instanceof MariaDBDictionary))
|
||||
return;
|
||||
|
||||
String jSql = jSQL.get(0).trim();
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.openjpa.persistence.delimited.identifiers.noschema;
|
|||
|
||||
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
|
||||
import org.apache.openjpa.jdbc.sql.DBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MariaDBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MySQLDictionary;
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManager;
|
||||
import org.apache.openjpa.persistence.test.SQLListenerTestCase;
|
||||
|
@ -35,6 +36,7 @@ public class TestNoSchemaManualDelimIdSeqGen extends SQLListenerTestCase {
|
|||
@Override
|
||||
public void setUp() throws Exception {
|
||||
|
||||
setUnsupportedDatabases(MariaDBDictionary.class);
|
||||
setUnsupportedDatabases(MySQLDictionary.class);
|
||||
if (isTestsDisabled())
|
||||
return;
|
||||
|
|
|
@ -24,6 +24,7 @@ import javax.persistence.Query;
|
|||
|
||||
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
|
||||
import org.apache.openjpa.jdbc.sql.DBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MariaDBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MySQLDictionary;
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManager;
|
||||
import org.apache.openjpa.persistence.test.SQLListenerTestCase;
|
||||
|
@ -42,6 +43,7 @@ public class TestNoSchemaManualDelimitedJoinAnnotations extends SQLListenerTestC
|
|||
@Override
|
||||
public void setUp() throws Exception {
|
||||
|
||||
setUnsupportedDatabases(MariaDBDictionary.class);
|
||||
setUnsupportedDatabases(MySQLDictionary.class);
|
||||
if (isTestsDisabled())
|
||||
return;
|
||||
|
|
|
@ -116,6 +116,18 @@ public class TestDynamicSchemas extends SingleEMFTestCase {
|
|||
closeEMF(sqlserverEMF);
|
||||
}
|
||||
|
||||
|
||||
public void testMariaDBDynamicSchema() {
|
||||
OpenJPAEntityManagerFactorySPI mysqlEMF =
|
||||
createEMF(EntityVeryLongNames.class, EntityReservedWords.class,
|
||||
"openjpa.ConnectionURL",
|
||||
"jdbc:mysql://host1:1,host2:2/database?p1=v1&p2=v2",
|
||||
"openjpa.jdbc.SynchronizeMappings", "export",
|
||||
"openjpa.jdbc.SchemaFactory", "dynamic", RETAIN_DATA);
|
||||
validateTableName( mysqlEMF );
|
||||
closeEMF(mysqlEMF);
|
||||
}
|
||||
|
||||
|
||||
public void testMySQLDynamicSchema() {
|
||||
OpenJPAEntityManagerFactorySPI mysqlEMF =
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
|
|||
import org.apache.openjpa.jdbc.sql.DBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.H2Dictionary;
|
||||
import org.apache.openjpa.jdbc.sql.HSQLDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MariaDBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MySQLDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.OracleDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.PostgresDictionary;
|
||||
|
@ -46,6 +47,7 @@ public class TestMultipleSchemaNames extends SingleEMFTestCase {
|
|||
// Need to skip tests on some databases.
|
||||
// See createSchemas() comment at the bottom
|
||||
setUnsupportedDatabases(
|
||||
MariaDBDictionary.class,
|
||||
MySQLDictionary.class,
|
||||
OracleDictionary.class,
|
||||
SQLServerDictionary.class,
|
||||
|
|
|
@ -25,6 +25,7 @@ import javax.persistence.Query;
|
|||
|
||||
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
|
||||
import org.apache.openjpa.jdbc.sql.DBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MariaDBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MySQLDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.OracleDictionary;
|
||||
import org.apache.openjpa.persistence.jdbc.query.domain.TimeKeeper;
|
||||
|
@ -47,9 +48,11 @@ public class TestHintedQuery extends SQLListenerTestCase {
|
|||
em.getTransaction().commit();
|
||||
|
||||
String jpql = "SELECT tk FROM TimeKeeper tk";
|
||||
String mariadbHint = "SQL_NO_CACHE";
|
||||
String mysqlHint = "SQL_NO_CACHE";
|
||||
String oracleHint = "/*+ first_rows(100) */";
|
||||
Query query = em.createQuery(jpql);
|
||||
query.setHint(MariaDBDictionary.SELECT_HINT, mariadbHint);
|
||||
query.setHint(MySQLDictionary.SELECT_HINT, mysqlHint);
|
||||
query.setHint(OracleDictionary.SELECT_HINT, oracleHint);
|
||||
List keepers = query.getResultList();
|
||||
|
@ -59,6 +62,10 @@ public class TestHintedQuery extends SQLListenerTestCase {
|
|||
// Other dictionaries should ignore them.
|
||||
DBDictionary dict = ((JDBCConfiguration) emf.getConfiguration())
|
||||
.getDBDictionaryInstance();
|
||||
if (dict instanceof MariaDBDictionary) {
|
||||
assertContainsSQL("SELECT " + mariadbHint + " ");
|
||||
return;
|
||||
}
|
||||
if (dict instanceof MySQLDictionary) {
|
||||
assertContainsSQL("SELECT " + mysqlHint + " ");
|
||||
return;
|
||||
|
@ -67,6 +74,7 @@ public class TestHintedQuery extends SQLListenerTestCase {
|
|||
assertContainsSQL("SELECT " + oracleHint + " ");
|
||||
return;
|
||||
}
|
||||
assertNotSQL(".*" + mariadbHint + ".*");
|
||||
assertNotSQL(".*" + mysqlHint + ".*");
|
||||
assertNotSQL(".*" + oracleHint + ".*");
|
||||
}
|
||||
|
|
|
@ -56,7 +56,8 @@ public class TestLazySchemaFactory
|
|||
// kodo uses
|
||||
JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
|
||||
_fks = conf.getDBDictionaryInstance().supportsForeignKeys
|
||||
&& getCurrentPlatform() != AbstractTestCase.Platform.MYSQL;
|
||||
&& getCurrentPlatform() != AbstractTestCase.Platform.MYSQL
|
||||
&& getCurrentPlatform() != AbstractTestCase.Platform.MARIADB;
|
||||
|
||||
LazySchemaFactory factory = new LazySchemaFactory();
|
||||
factory.setConfiguration(conf);
|
||||
|
|
|
@ -27,6 +27,7 @@ import javax.persistence.EntityManager;
|
|||
|
||||
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
|
||||
import org.apache.openjpa.jdbc.sql.DBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MariaDBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MySQLDictionary;
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
|
||||
import org.apache.openjpa.persistence.jdbc.SQLSniffer;
|
||||
|
@ -78,7 +79,7 @@ public class TestNamedUniqueConstraint extends SQLListenerTestCase {
|
|||
}
|
||||
|
||||
private String getUniqueConstraint(String unique) {
|
||||
if (dict instanceof MySQLDictionary) {
|
||||
if (dict instanceof MySQLDictionary || dict instanceof MariaDBDictionary) {
|
||||
//CREATE TABLE N_UNIQUE_A (aid INTEGER NOT NULL, f1 INTEGER NOT NULL, f2 INTEGER NOT NULL,
|
||||
//f3 INTEGER NOT NULL, f4 INTEGER NOT NULL, f5 INTEGER, f6 INTEGER, PRIMARY KEY (aid),
|
||||
//UNIQUE U_N_UNQU__F1 (f1),
|
||||
|
|
|
@ -25,6 +25,7 @@ import javax.persistence.EntityManager;
|
|||
|
||||
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
|
||||
import org.apache.openjpa.jdbc.sql.DBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MariaDBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MySQLDictionary;
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
|
||||
import org.apache.openjpa.persistence.jdbc.SQLSniffer;
|
||||
|
@ -79,7 +80,7 @@ public class TestNamedUniqueConstraintWithXMLDescriptor extends SQLListenerTestC
|
|||
}
|
||||
|
||||
private String getUniqueConstraint(String unique) {
|
||||
if (dict instanceof MySQLDictionary) {
|
||||
if (dict instanceof MySQLDictionary || dict instanceof MariaDBDictionary) {
|
||||
//CREATE TABLE N_UNIQUE_A (aid INTEGER NOT NULL, f1 INTEGER NOT NULL, f2 INTEGER NOT NULL,
|
||||
//f3 INTEGER NOT NULL, f4 INTEGER NOT NULL, f5 INTEGER, f6 INTEGER, PRIMARY KEY (aid),
|
||||
//UNIQUE U_N_UNQU__F1 (f1),
|
||||
|
|
|
@ -122,6 +122,7 @@ public class TestSpecialNumbers extends BaseKernelTest {
|
|||
} catch (Exception e) {
|
||||
bug(EnumSet.of(AbstractTestCase.Platform.POSTGRESQL,
|
||||
AbstractTestCase.Platform.DB2,
|
||||
AbstractTestCase.Platform.MARIADB,
|
||||
AbstractTestCase.Platform.MYSQL,
|
||||
AbstractTestCase.Platform.DERBY), 494, e,
|
||||
"Some datastores cannot store Float.MAX_VALUE");
|
||||
|
@ -142,7 +143,7 @@ public class TestSpecialNumbers extends BaseKernelTest {
|
|||
AbstractTestCase.Platform.DERBY), 494, e,
|
||||
"Some databases cannot store Float.MIN_VALUE");
|
||||
} catch (AssertionFailedError e) {
|
||||
bug(EnumSet.of(AbstractTestCase.Platform.MYSQL,
|
||||
bug(EnumSet.of(AbstractTestCase.Platform.MARIADB, AbstractTestCase.Platform.MYSQL,
|
||||
AbstractTestCase.Platform.SQLSERVER), 494, e,
|
||||
"Some databases cannot store Float.MIN_VALUE");
|
||||
}
|
||||
|
@ -167,6 +168,7 @@ public class TestSpecialNumbers extends BaseKernelTest {
|
|||
} catch (Exception e) {
|
||||
bug(EnumSet.of(AbstractTestCase.Platform.POINTBASE,
|
||||
AbstractTestCase.Platform.POSTGRESQL,
|
||||
AbstractTestCase.Platform.MARIADB,
|
||||
AbstractTestCase.Platform.MYSQL,
|
||||
AbstractTestCase.Platform.DB2,
|
||||
AbstractTestCase.Platform.ORACLE,
|
||||
|
@ -186,6 +188,7 @@ public class TestSpecialNumbers extends BaseKernelTest {
|
|||
} catch (Exception e) {
|
||||
bug(EnumSet.of(AbstractTestCase.Platform.POINTBASE,
|
||||
AbstractTestCase.Platform.POSTGRESQL,
|
||||
AbstractTestCase.Platform.MARIADB,
|
||||
AbstractTestCase.Platform.MYSQL,
|
||||
AbstractTestCase.Platform.DB2,
|
||||
AbstractTestCase.Platform.ORACLE,
|
||||
|
@ -204,6 +207,7 @@ public class TestSpecialNumbers extends BaseKernelTest {
|
|||
new Double(Double.MAX_VALUE));
|
||||
} catch (Exception e) {
|
||||
bug(EnumSet.of(AbstractTestCase.Platform.POINTBASE,
|
||||
AbstractTestCase.Platform.MARIADB,
|
||||
AbstractTestCase.Platform.MYSQL,
|
||||
AbstractTestCase.Platform.ORACLE,
|
||||
AbstractTestCase.Platform.POSTGRESQL,
|
||||
|
@ -231,7 +235,7 @@ public class TestSpecialNumbers extends BaseKernelTest {
|
|||
AbstractTestCase.Platform.DERBY), 494, e,
|
||||
"Some databases cannot store Double.MIN_VALUE");
|
||||
} catch (AssertionFailedError e) {
|
||||
bug(AbstractTestCase.Platform.MYSQL, 494, e,
|
||||
bug(EnumSet.of(AbstractTestCase.Platform.MARIADB, AbstractTestCase.Platform.MYSQL), 494, e,
|
||||
"Some databases cannot store Double.MIN_VALUE");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -195,7 +195,7 @@ public class TestSpecialNumbers2 extends BaseKernelTest {
|
|||
AbstractTestCase.Platform.DERBY), 494, e,
|
||||
"Some databases cannot store Double.MIN_VALUE");
|
||||
} catch (AssertionFailedError e) {
|
||||
bug(AbstractTestCase.Platform.MYSQL, 494, e,
|
||||
bug(EnumSet.of(AbstractTestCase.Platform.MARIADB, AbstractTestCase.Platform.MYSQL), 494, e,
|
||||
"Some databases cannot store Double.MIN_VALUE");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ public abstract class GroupingTestCase
|
|||
"from AllFieldTypes o"
|
||||
+ " group by o.intField order by sum(o.shortField) asc");
|
||||
prepareQuery(q);
|
||||
// this might fail in MySQL
|
||||
// this might fail in MySQL/MariaDB
|
||||
List res = q.getResultList();
|
||||
assertEquals(2, res.size());
|
||||
Iterator itr = res.iterator();
|
||||
|
|
|
@ -26,6 +26,7 @@ import javax.persistence.Query;
|
|||
|
||||
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
|
||||
import org.apache.openjpa.jdbc.sql.DBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MariaDBDictionary;
|
||||
import org.apache.openjpa.jdbc.sql.MySQLDictionary;
|
||||
import org.apache.openjpa.persistence.query.Customer.CreditRating;
|
||||
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
||||
|
@ -255,7 +256,7 @@ public class TestSubquery
|
|||
// this at the bottom of the UPDATE documentation(http://dev.mysql.com/doc/refman/5.0/en/update.html):
|
||||
// Currently, you cannot update a table and select from the same table in a subquery.
|
||||
|
||||
if (dict instanceof MySQLDictionary)
|
||||
if (dict instanceof MySQLDictionary || dict instanceof MariaDBDictionary)
|
||||
return;
|
||||
|
||||
em.getTransaction().begin();
|
||||
|
|
|
@ -127,6 +127,34 @@
|
|||
<jdbc.DBDictionary />
|
||||
</properties>
|
||||
</profile>
|
||||
|
||||
<!-- Profile for testing with MariaDB DB -->
|
||||
<profile>
|
||||
<id>test-mariadb</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>test-mariadb</name>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>mariadb</groupId>
|
||||
<artifactId>mariadb-connector-java</artifactId>
|
||||
<version>${mariadb.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<connection.driver.name>org.mariadb.jdbc.Driver</connection.driver.name>
|
||||
<connection.url>${openjpa.mariadb.url}</connection.url>
|
||||
<connection.username>${openjpa.mariadb.username}</connection.username>
|
||||
<connection.password>${openjpa.mariadb.password}</connection.password>
|
||||
<!-- DBCP overrides for MariaDB testing -->
|
||||
<dbcp.maxIdle>0</dbcp.maxIdle>
|
||||
<dbcp.minIdle>0</dbcp.minIdle>
|
||||
<jdbc.DBDictionary />
|
||||
</properties>
|
||||
</profile>
|
||||
|
||||
<!-- Profile for testing with PostgreSQL DB -->
|
||||
<profile>
|
||||
|
|
|
@ -121,8 +121,8 @@ public abstract class LockScopeTestCase extends SQLListenerTestCase {
|
|||
}
|
||||
|
||||
protected enum DBType {
|
||||
access, db2, derby, empress, foxpro, h2, hsql, informix, ingres, jdatastore, mysql, oracle, pointbase, postgres,
|
||||
sqlserver, sybase
|
||||
access, db2, derby, empress, foxpro, h2, hsql, informix, ingres, jdatastore, mariadb, mysql, oracle, pointbase,
|
||||
postgres, sqlserver, sybase
|
||||
};
|
||||
|
||||
protected DBType getDBType(EntityManager em) {
|
||||
|
|
|
@ -1040,8 +1040,8 @@ public abstract class SequencedActionsTest extends SQLListenerTestCase {
|
|||
}
|
||||
|
||||
protected enum DBType {
|
||||
access, db2, derby, empress, foxpro, h2, hsql, informix, ingres, jdatastore, mysql, oracle, pointbase, postgres,
|
||||
sqlserver, sybase
|
||||
access, db2, derby, empress, foxpro, h2, hsql, informix, ingres, jdatastore, mariadb, mysql, oracle, pointbase,
|
||||
postgres, sqlserver, sybase
|
||||
};
|
||||
|
||||
protected DBType getDBType(EntityManager em) {
|
||||
|
|
|
@ -156,6 +156,29 @@
|
|||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
<persistence-unit name="mariadb">
|
||||
<properties>
|
||||
<property name="openjpa.BrokerFactory" value="slice"/>
|
||||
<property name="openjpa.ConnectionDriverName" value="org.mariadb.jdbc.Driver"/>
|
||||
|
||||
<property name="openjpa.slice.Names" value="One,Two"/>
|
||||
<property name="openjpa.slice.DistributionPolicy" value="org.apache.openjpa.slice.policy.UserDistributionPolicy"/>
|
||||
|
||||
<property name="openjpa.ConnectionUserName" value="root"/>
|
||||
<property name="openjpa.ConnectionPassword" value=""/>
|
||||
<property name="openjpa.slice.One.ConnectionDriverName" value="org.mariadb.jdbc.Driver"/>
|
||||
<property name="openjpa.slice.One.ConnectionURL" value="jdbc:mysql://localhost/slice1"/>
|
||||
<property name="openjpa.slice.Two.ConnectionDriverName" value="org.mariadb.jdbc.Driver"/>
|
||||
<property name="openjpa.slice.Two.ConnectionURL" value="jdbc:mysql://localhost/slice2"/>
|
||||
|
||||
<property name="openjpa.Multithreaded" value="false"/>
|
||||
<property name="openjpa.jdbc.SynchronizeMappings" value="refresh"/>
|
||||
<property name="openjpa.jdbc.MappingDefaults" value="DefaultMissingInfo=true"/>
|
||||
<property name="openjpa.RuntimeUnenhancedClasses" value="unsupported"/>
|
||||
<property name="openjpa.DynamicEnhancementAgent" value="false"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
<persistence-unit name="replication">
|
||||
<class>org.apache.openjpa.slice.ReplicatedParent</class>
|
||||
<class>org.apache.openjpa.slice.ReplicatedChild</class>
|
||||
|
@ -231,6 +254,27 @@
|
|||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
<persistence-unit name="car.mariadb">
|
||||
<properties>
|
||||
<property name="openjpa.BrokerFactory" value="slice"/>
|
||||
<property name="openjpa.ConnectionDriverName" value="org.mariadb.jdbc.Driver"/>
|
||||
|
||||
<property name="openjpa.slice.Names" value="BMW,Honda,Ford"/>
|
||||
|
||||
<property name="openjpa.ConnectionUserName" value="root"/>
|
||||
<property name="openjpa.ConnectionPassword" value=""/>
|
||||
<property name="openjpa.slice.BMW.ConnectionURL" value="jdbc:mysql://localhost/bmw"/>
|
||||
<property name="openjpa.slice.Honda.ConnectionURL" value="jdbc:mysql://localhost/ford"/>
|
||||
<property name="openjpa.slice.Ford.ConnectionURL" value="jdbc:mysql://localhost/honda"/>
|
||||
|
||||
<property name="openjpa.Multithreaded" value="false"/>
|
||||
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=native)"/>
|
||||
<property name="openjpa.jdbc.MappingDefaults" value="DefaultMissingInfo=true"/>
|
||||
<property name="openjpa.RuntimeUnenhancedClasses" value="unsupported"/>
|
||||
<property name="openjpa.DynamicEnhancementAgent" value="false"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
<persistence-unit name="perf.mysql.slice">
|
||||
<class>org.apache.openjpa.slice.Person</class>
|
||||
<class>org.apache.openjpa.slice.Address</class>
|
||||
|
@ -277,4 +321,51 @@
|
|||
<property name="openjpa.DynamicEnhancementAgent" value="false"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
<persistence-unit name="perf.mariadb.slice">
|
||||
<class>org.apache.openjpa.slice.Person</class>
|
||||
<class>org.apache.openjpa.slice.Address</class>
|
||||
<class>org.apache.openjpa.slice.Country</class>
|
||||
|
||||
<properties>
|
||||
<property name="openjpa.BrokerFactory" value="slice"/>
|
||||
<property name="openjpa.ConnectionDriverName" value="org.apache.commons.dbcp.BasicDataSource"/>
|
||||
|
||||
<property name="openjpa.slice.Names" value="S1,S2,S3,S4"/>
|
||||
|
||||
<property name="openjpa.ConnectionUserName" value="root"/>
|
||||
<property name="openjpa.ConnectionPassword" value=""/>
|
||||
<property name="openjpa.slice.S1.ConnectionProperties" value="DriverClassName=org.mariadb.jdbc.Driver,Url=jdbc:mysql://localhost/S1,MaxActive=4"/>
|
||||
<property name="openjpa.slice.S2.ConnectionProperties" value="DriverClassName=org.mariadb.jdbc.Driver,Url=jdbc:mysql://localhost/S2,MaxActive=4"/>
|
||||
<property name="openjpa.slice.S3.ConnectionProperties" value="DriverClassName=org.mariadb.jdbc.Driver,Url=jdbc:mysql://localhost/S3,MaxActive=4"/>
|
||||
<property name="openjpa.slice.S4.ConnectionProperties" value="DriverClassName=org.mariadb.jdbc.Driver,Url=jdbc:mysql://localhost/S4,MaxActive=4"/>
|
||||
|
||||
<property name="openjpa.jdbc.DBDictionary" value="mariadb"/>
|
||||
<property name="openjpa.Multithreaded" value="false"/>
|
||||
<property name="openjpa.jdbc.SynchronizeMappings" value="refresh"/>
|
||||
<property name="openjpa.jdbc.MappingDefaults" value="DefaultMissingInfo=true"/>
|
||||
<property name="openjpa.RuntimeUnenhancedClasses" value="unsupported"/>
|
||||
<property name="openjpa.DynamicEnhancementAgent" value="false"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
<persistence-unit name="perf.mariadb.mono">
|
||||
<class>org.apache.openjpa.slice.Person</class>
|
||||
<class>org.apache.openjpa.slice.Address</class>
|
||||
<class>org.apache.openjpa.slice.Country</class>
|
||||
|
||||
<properties>
|
||||
<property name="openjpa.ConnectionDriverName" value="org.apache.commons.dbcp.BasicDataSource"/>
|
||||
|
||||
<property name="openjpa.ConnectionUserName" value="root"/>
|
||||
<property name="openjpa.ConnectionPassword" value=""/>
|
||||
<property name="openjpa.ConnectionProperties" value="DriverClassName=org.mariadb.jdbc.Driver,Url=jdbc:mysql://localhost/S,MaxActive=4"/>
|
||||
|
||||
<property name="openjpa.jdbc.DBDictionary" value="mariadb"/>
|
||||
<property name="openjpa.Multithreaded" value="false"/>
|
||||
<property name="openjpa.jdbc.SynchronizeMappings" value="refresh"/>
|
||||
<property name="openjpa.jdbc.MappingDefaults" value="DefaultMissingInfo=true"/>
|
||||
<property name="openjpa.RuntimeUnenhancedClasses" value="unsupported"/>
|
||||
<property name="openjpa.DynamicEnhancementAgent" value="false"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
</persistence>
|
||||
|
|
Loading…
Reference in New Issue