mirror of https://github.com/apache/openjpa.git
[OPENJPA-2567] various MySql and MariaDB text types support is added - thanks @solomax - This closes #18
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1839940 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
6c4c77aa78
commit
9a98d6a2bf
|
@ -14,7 +14,7 @@
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
* KIND, either express or implied. See the License for the
|
* KIND, either express or implied. See the License for the
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.openjpa.jdbc.sql;
|
package org.apache.openjpa.jdbc.sql;
|
||||||
|
|
||||||
|
@ -30,7 +30,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.openjpa.lib.util.StringUtil;
|
|
||||||
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
|
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
|
||||||
import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
|
import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
|
||||||
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
|
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
|
||||||
|
@ -41,17 +40,18 @@ import org.apache.openjpa.jdbc.schema.ForeignKey;
|
||||||
import org.apache.openjpa.jdbc.schema.Index;
|
import org.apache.openjpa.jdbc.schema.Index;
|
||||||
import org.apache.openjpa.jdbc.schema.PrimaryKey;
|
import org.apache.openjpa.jdbc.schema.PrimaryKey;
|
||||||
import org.apache.openjpa.jdbc.schema.Table;
|
import org.apache.openjpa.jdbc.schema.Table;
|
||||||
|
import org.apache.openjpa.lib.util.StringUtil;
|
||||||
import org.apache.openjpa.util.StoreException;
|
import org.apache.openjpa.util.StoreException;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dictionary for MariaDB, based off the MySQLDictionary.
|
* Dictionary for MariaDB, based off the MySQLDictionary.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class MariaDBDictionary extends DBDictionary {
|
public class MariaDBDictionary extends DBDictionary {
|
||||||
public static final String SELECT_HINT = "openjpa.hint.MariaDBSelectHint";
|
public static final String SELECT_HINT = "openjpa.hint.MariaDBSelectHint";
|
||||||
|
|
||||||
public static final String DELIMITER_BACK_TICK = "`";
|
public static final String DELIMITER_BACK_TICK = "`";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The MySQL table type to use when creating tables; defaults to innodb.
|
* The MySQL table type to use when creating tables; defaults to innodb.
|
||||||
*/
|
*/
|
||||||
|
@ -69,8 +69,8 @@ public class MariaDBDictionary extends DBDictionary {
|
||||||
public boolean driverDeserializesBlobs = false;
|
public boolean driverDeserializesBlobs = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to inline multi-table bulk-delete operations into MySQL's
|
* Whether to inline multi-table bulk-delete operations into MySQL's
|
||||||
* combined <code>DELETE FROM foo, bar, baz</code> syntax.
|
* combined <code>DELETE FROM foo, bar, baz</code> syntax.
|
||||||
* Defaults to false, since this may fail in the presence of InnoDB tables
|
* Defaults to false, since this may fail in the presence of InnoDB tables
|
||||||
* with foreign keys.
|
* with foreign keys.
|
||||||
* @see http://dev.mysql.com/doc/refman/5.0/en/delete.html
|
* @see http://dev.mysql.com/doc/refman/5.0/en/delete.html
|
||||||
|
@ -80,6 +80,9 @@ public class MariaDBDictionary extends DBDictionary {
|
||||||
public static final String tinyBlobTypeName = "TINYBLOB";
|
public static final String tinyBlobTypeName = "TINYBLOB";
|
||||||
public static final String mediumBlobTypeName = "MEDIUMBLOB";
|
public static final String mediumBlobTypeName = "MEDIUMBLOB";
|
||||||
public static final String longBlobTypeName = "LONGBLOB";
|
public static final String longBlobTypeName = "LONGBLOB";
|
||||||
|
public static final String tinyTextTypeName = "TINYTEXT";
|
||||||
|
public static final String mediumTextTypeName = "MEDIUMTEXT";
|
||||||
|
public static final String longTextTypeName = "LONGTEXT";
|
||||||
|
|
||||||
public MariaDBDictionary() {
|
public MariaDBDictionary() {
|
||||||
platform = "MariaDB";
|
platform = "MariaDB";
|
||||||
|
@ -120,15 +123,15 @@ public class MariaDBDictionary extends DBDictionary {
|
||||||
reservedWordSet.addAll(Arrays.asList(new String[]{
|
reservedWordSet.addAll(Arrays.asList(new String[]{
|
||||||
"AUTO_INCREMENT", "BINARY", "BLOB", "CHANGE", "ENUM", "INFILE",
|
"AUTO_INCREMENT", "BINARY", "BLOB", "CHANGE", "ENUM", "INFILE",
|
||||||
"INT1", "INT2", "INT4", "FLOAT1", "FLOAT2", "FLOAT4", "LOAD",
|
"INT1", "INT2", "INT4", "FLOAT1", "FLOAT2", "FLOAT4", "LOAD",
|
||||||
"MEDIUMINT", "OUTFILE", "REPLACE", "STARTING", "TEXT", "UNSIGNED",
|
"MEDIUMINT", "OUTFILE", "REPLACE", "STARTING", "TEXT", "UNSIGNED",
|
||||||
"ZEROFILL", "INDEX",
|
"ZEROFILL", "INDEX",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// reservedWordSet subset that CANNOT be used as valid column names
|
// reservedWordSet subset that CANNOT be used as valid column names
|
||||||
// (i.e., without surrounding them with double-quotes)
|
// (i.e., without surrounding them with double-quotes)
|
||||||
invalidColumnWordSet.addAll(Arrays.asList(new String[]{
|
invalidColumnWordSet.addAll(Arrays.asList(new String[]{
|
||||||
"ADD", "ALL", "ALTER", "AND", "AS", "ASC", "BETWEEN", "BINARY",
|
"ADD", "ALL", "ALTER", "AND", "AS", "ASC", "BETWEEN", "BINARY",
|
||||||
"BLOB", "BOTH", "BY", "CASCADE", "CASE", "CHANGE", "CHAR",
|
"BLOB", "BOTH", "BY", "CASCADE", "CASE", "CHANGE", "CHAR",
|
||||||
"CHARACTER", "CHECK", "COLLATE", "COLUMN", "CONSTRAINT", "CONTINUE",
|
"CHARACTER", "CHECK", "COLLATE", "COLUMN", "CONSTRAINT", "CONTINUE",
|
||||||
"CONVERT", "CREATE", "CROSS", "CURRENT_DATE", "CURRENT_TIME",
|
"CONVERT", "CREATE", "CROSS", "CURRENT_DATE", "CURRENT_TIME",
|
||||||
"CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", "DEC", "DECIMAL",
|
"CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", "DEC", "DECIMAL",
|
||||||
|
@ -145,7 +148,7 @@ public class MariaDBDictionary extends DBDictionary {
|
||||||
"STARTING", "TABLE", "THEN", "TO", "TRAILING", "TRUE", "UNION",
|
"STARTING", "TABLE", "THEN", "TO", "TRAILING", "TRUE", "UNION",
|
||||||
"UNIQUE", "UNSIGNED", "UPDATE", "USAGE", "USING", "VALUES",
|
"UNIQUE", "UNSIGNED", "UPDATE", "USAGE", "USING", "VALUES",
|
||||||
"VARCHAR", "VARYING", "WHEN", "WHERE", "WITH", "WRITE", "ZEROFILL",
|
"VARCHAR", "VARYING", "WHEN", "WHERE", "WITH", "WRITE", "ZEROFILL",
|
||||||
"INDEX",
|
"INDEX",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
requiresSearchStringEscapeForLike = true;
|
requiresSearchStringEscapeForLike = true;
|
||||||
|
@ -157,7 +160,7 @@ public class MariaDBDictionary extends DBDictionary {
|
||||||
|
|
||||||
setLeadingDelimiter(DELIMITER_BACK_TICK);
|
setLeadingDelimiter(DELIMITER_BACK_TICK);
|
||||||
setTrailingDelimiter(DELIMITER_BACK_TICK);
|
setTrailingDelimiter(DELIMITER_BACK_TICK);
|
||||||
|
|
||||||
fixedSizeTypeNameSet.remove("NUMERIC");
|
fixedSizeTypeNameSet.remove("NUMERIC");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,10 +183,11 @@ public class MariaDBDictionary extends DBDictionary {
|
||||||
if (log.isWarnEnabled())
|
if (log.isWarnEnabled())
|
||||||
log.warn(e.toString(), e);
|
log.warn(e.toString(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
supportsXMLColumn = true;
|
supportsXMLColumn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void setDelimitedCase(DatabaseMetaData metaData) {
|
protected void setDelimitedCase(DatabaseMetaData metaData) {
|
||||||
// Determination of case sensitivity is not accurate; MariaDB JIRA CONJ-55
|
// Determination of case sensitivity is not accurate; MariaDB JIRA CONJ-55
|
||||||
delimitedCase = SCHEMA_CASE_PRESERVE;
|
delimitedCase = SCHEMA_CASE_PRESERVE;
|
||||||
|
@ -194,7 +198,7 @@ public class MariaDBDictionary extends DBDictionary {
|
||||||
conn = super.decorate(conn);
|
conn = super.decorate(conn);
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int[] getMajorMinorVersions(String versionStr)
|
private static int[] getMajorMinorVersions(String versionStr)
|
||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
int beginIndex = 0;
|
int beginIndex = 0;
|
||||||
|
@ -263,7 +267,7 @@ public class MariaDBDictionary extends DBDictionary {
|
||||||
new String[]{ "ALTER TABLE "
|
new String[]{ "ALTER TABLE "
|
||||||
+ getFullName(fk.getTable(), false)
|
+ getFullName(fk.getTable(), false)
|
||||||
+ " DROP FOREIGN KEY " + toDBName(fkName) };
|
+ " DROP FOREIGN KEY " + toDBName(fkName) };
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
return new String[]{ "ALTER TABLE "
|
return new String[]{ "ALTER TABLE "
|
||||||
+ getFullName(fk.getTable(), false)
|
+ getFullName(fk.getTable(), false)
|
||||||
|
@ -288,7 +292,7 @@ public class MariaDBDictionary extends DBDictionary {
|
||||||
System.arraycopy(sql, 0, ret, cols.length, sql.length);
|
System.arraycopy(sql, 0, ret, cols.length, sql.length);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getDeleteTableContentsSQL(Table[] tables,Connection conn) {
|
public String[] getDeleteTableContentsSQL(Table[] tables,Connection conn) {
|
||||||
// mysql >= 4 supports more-optimal delete syntax
|
// mysql >= 4 supports more-optimal delete syntax
|
||||||
|
@ -343,10 +347,10 @@ public class MariaDBDictionary extends DBDictionary {
|
||||||
return Types.LONGVARCHAR;
|
return Types.LONGVARCHAR;
|
||||||
return super.getPreferredType(type);
|
return super.getPreferredType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append XML comparison.
|
* Append XML comparison.
|
||||||
*
|
*
|
||||||
* @param buf the SQL buffer to write the comparison
|
* @param buf the SQL buffer to write the comparison
|
||||||
* @param op the comparison operation to perform
|
* @param op the comparison operation to perform
|
||||||
* @param lhs the left hand side of the comparison
|
* @param lhs the left hand side of the comparison
|
||||||
|
@ -368,10 +372,10 @@ public class MariaDBDictionary extends DBDictionary {
|
||||||
else
|
else
|
||||||
rhs.appendTo(buf);
|
rhs.appendTo(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append XML column value so that it can be used in comparisons.
|
* Append XML column value so that it can be used in comparisons.
|
||||||
*
|
*
|
||||||
* @param buf the SQL buffer to write the value
|
* @param buf the SQL buffer to write the value
|
||||||
* @param val the value to be written
|
* @param val the value to be written
|
||||||
*/
|
*/
|
||||||
|
@ -382,7 +386,7 @@ public class MariaDBDictionary extends DBDictionary {
|
||||||
val.appendTo(buf);
|
val.appendTo(buf);
|
||||||
buf.append("')");
|
buf.append("')");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBatchFetchSize(int batchFetchSize) {
|
public int getBatchFetchSize(int batchFetchSize) {
|
||||||
return Integer.MIN_VALUE;
|
return Integer.MIN_VALUE;
|
||||||
|
@ -401,10 +405,10 @@ public class MariaDBDictionary extends DBDictionary {
|
||||||
select += " " + hint;
|
select += " " + hint;
|
||||||
return select;
|
return select;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Collection<String> getSelectTableAliases(Select sel) {
|
protected Collection<String> getSelectTableAliases(Select sel) {
|
||||||
Set<String> result = new HashSet<String>();
|
Set<String> result = new HashSet<>();
|
||||||
List<String> selects = sel.getIdentifierAliases();
|
List<String> selects = sel.getIdentifierAliases();
|
||||||
for (String s : selects) {
|
for (String s : selects) {
|
||||||
String tableAlias = s.substring(0, s.indexOf('.'));
|
String tableAlias = s.substring(0, s.indexOf('.'));
|
||||||
|
@ -412,12 +416,12 @@ public class MariaDBDictionary extends DBDictionary {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int matchErrorState(Map<Integer,Set<String>> errorStates, SQLException ex) {
|
protected int matchErrorState(Map<Integer,Set<String>> errorStates, SQLException ex) {
|
||||||
int state = super.matchErrorState(errorStates, ex);
|
int state = super.matchErrorState(errorStates, ex);
|
||||||
|
|
||||||
if (state == StoreException.GENERAL &&
|
if (state == StoreException.GENERAL &&
|
||||||
ex.getNextException() != null &&
|
ex.getNextException() != null &&
|
||||||
"JZ0002".equalsIgnoreCase(ex.getNextException().getSQLState())) {
|
"JZ0002".equalsIgnoreCase(ex.getNextException().getSQLState())) {
|
||||||
if (conf != null && conf.getLockTimeout() != -1) {
|
if (conf != null && conf.getLockTimeout() != -1) {
|
||||||
|
@ -449,7 +453,7 @@ public class MariaDBDictionary extends DBDictionary {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getTypeName(Column col) {
|
public String getTypeName(Column col) {
|
||||||
// handle blobs differently, if the DBItentifierType is NULL (e.g. no column definition is set).
|
// 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.getType() == Types.BLOB && col.getTypeIdentifier().getType() == DBIdentifierType.NULL) {
|
||||||
if (col.getSize() <= 0) // unknown size
|
if (col.getSize() <= 0) // unknown size
|
||||||
return blobTypeName; // return old default of 64KB
|
return blobTypeName; // return old default of 64KB
|
||||||
|
@ -461,6 +465,17 @@ public class MariaDBDictionary extends DBDictionary {
|
||||||
return mediumBlobTypeName;
|
return mediumBlobTypeName;
|
||||||
else
|
else
|
||||||
return longBlobTypeName;
|
return longBlobTypeName;
|
||||||
|
} else if (col.getType() == Types.CLOB && col.getTypeIdentifier().getType() == DBIdentifierType.NULL) {
|
||||||
|
if (col.getSize() <= 0) // unknown size
|
||||||
|
return clobTypeName; // return old default of 64KB
|
||||||
|
else if (col.getSize() <= 255)
|
||||||
|
return tinyTextTypeName;
|
||||||
|
else if (col.getSize() <= 65535)
|
||||||
|
return clobTypeName; // old default of 64KB
|
||||||
|
else if (col.getSize() <= 16777215)
|
||||||
|
return mediumTextTypeName;
|
||||||
|
else
|
||||||
|
return longTextTypeName;
|
||||||
} else {
|
} else {
|
||||||
return super.getTypeName(col);
|
return super.getTypeName(col);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
* KIND, either express or implied. See the License for the
|
* KIND, either express or implied. See the License for the
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.openjpa.jdbc.sql;
|
package org.apache.openjpa.jdbc.sql;
|
||||||
|
|
||||||
|
@ -30,7 +30,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.openjpa.lib.util.StringUtil;
|
|
||||||
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
|
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
|
||||||
import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
|
import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
|
||||||
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
|
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
|
||||||
|
@ -41,6 +40,7 @@ import org.apache.openjpa.jdbc.schema.ForeignKey;
|
||||||
import org.apache.openjpa.jdbc.schema.Index;
|
import org.apache.openjpa.jdbc.schema.Index;
|
||||||
import org.apache.openjpa.jdbc.schema.PrimaryKey;
|
import org.apache.openjpa.jdbc.schema.PrimaryKey;
|
||||||
import org.apache.openjpa.jdbc.schema.Table;
|
import org.apache.openjpa.jdbc.schema.Table;
|
||||||
|
import org.apache.openjpa.lib.util.StringUtil;
|
||||||
import org.apache.openjpa.util.StoreException;
|
import org.apache.openjpa.util.StoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,7 +52,7 @@ public class MySQLDictionary
|
||||||
public static final String SELECT_HINT = "openjpa.hint.MySQLSelectHint";
|
public static final String SELECT_HINT = "openjpa.hint.MySQLSelectHint";
|
||||||
|
|
||||||
public static final String DELIMITER_BACK_TICK = "`";
|
public static final String DELIMITER_BACK_TICK = "`";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The MySQL table type to use when creating tables; defaults to innodb.
|
* The MySQL table type to use when creating tables; defaults to innodb.
|
||||||
*/
|
*/
|
||||||
|
@ -70,8 +70,8 @@ public class MySQLDictionary
|
||||||
public boolean driverDeserializesBlobs = false;
|
public boolean driverDeserializesBlobs = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to inline multi-table bulk-delete operations into MySQL's
|
* Whether to inline multi-table bulk-delete operations into MySQL's
|
||||||
* combined <code>DELETE FROM foo, bar, baz</code> syntax.
|
* combined <code>DELETE FROM foo, bar, baz</code> syntax.
|
||||||
* Defaults to false, since this may fail in the presence of InnoDB tables
|
* Defaults to false, since this may fail in the presence of InnoDB tables
|
||||||
* with foreign keys.
|
* with foreign keys.
|
||||||
* @see http://dev.mysql.com/doc/refman/5.0/en/delete.html
|
* @see http://dev.mysql.com/doc/refman/5.0/en/delete.html
|
||||||
|
@ -81,6 +81,9 @@ public class MySQLDictionary
|
||||||
public static final String tinyBlobTypeName = "TINYBLOB";
|
public static final String tinyBlobTypeName = "TINYBLOB";
|
||||||
public static final String mediumBlobTypeName = "MEDIUMBLOB";
|
public static final String mediumBlobTypeName = "MEDIUMBLOB";
|
||||||
public static final String longBlobTypeName = "LONGBLOB";
|
public static final String longBlobTypeName = "LONGBLOB";
|
||||||
|
public static final String tinyTextTypeName = "TINYTEXT";
|
||||||
|
public static final String mediumTextTypeName = "MEDIUMTEXT";
|
||||||
|
public static final String longTextTypeName = "LONGTEXT";
|
||||||
|
|
||||||
public MySQLDictionary() {
|
public MySQLDictionary() {
|
||||||
platform = "MySQL";
|
platform = "MySQL";
|
||||||
|
@ -121,15 +124,15 @@ public class MySQLDictionary
|
||||||
reservedWordSet.addAll(Arrays.asList(new String[]{
|
reservedWordSet.addAll(Arrays.asList(new String[]{
|
||||||
"AUTO_INCREMENT", "BINARY", "BLOB", "CHANGE", "ENUM", "INFILE",
|
"AUTO_INCREMENT", "BINARY", "BLOB", "CHANGE", "ENUM", "INFILE",
|
||||||
"INT1", "INT2", "INT4", "FLOAT1", "FLOAT2", "FLOAT4", "LOAD",
|
"INT1", "INT2", "INT4", "FLOAT1", "FLOAT2", "FLOAT4", "LOAD",
|
||||||
"MEDIUMINT", "OUTFILE", "REPLACE", "STARTING", "TEXT", "UNSIGNED",
|
"MEDIUMINT", "OUTFILE", "REPLACE", "STARTING", "TEXT", "UNSIGNED",
|
||||||
"ZEROFILL", "INDEX",
|
"ZEROFILL", "INDEX",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// reservedWordSet subset that CANNOT be used as valid column names
|
// reservedWordSet subset that CANNOT be used as valid column names
|
||||||
// (i.e., without surrounding them with double-quotes)
|
// (i.e., without surrounding them with double-quotes)
|
||||||
invalidColumnWordSet.addAll(Arrays.asList(new String[]{
|
invalidColumnWordSet.addAll(Arrays.asList(new String[]{
|
||||||
"ADD", "ALL", "ALTER", "AND", "AS", "ASC", "BETWEEN", "BINARY",
|
"ADD", "ALL", "ALTER", "AND", "AS", "ASC", "BETWEEN", "BINARY",
|
||||||
"BLOB", "BOTH", "BY", "CASCADE", "CASE", "CHANGE", "CHAR",
|
"BLOB", "BOTH", "BY", "CASCADE", "CASE", "CHANGE", "CHAR",
|
||||||
"CHARACTER", "CHECK", "COLLATE", "COLUMN", "CONSTRAINT", "CONTINUE",
|
"CHARACTER", "CHECK", "COLLATE", "COLUMN", "CONSTRAINT", "CONTINUE",
|
||||||
"CONVERT", "CREATE", "CROSS", "CURRENT_DATE", "CURRENT_TIME",
|
"CONVERT", "CREATE", "CROSS", "CURRENT_DATE", "CURRENT_TIME",
|
||||||
"CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", "DEC", "DECIMAL",
|
"CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", "DEC", "DECIMAL",
|
||||||
|
@ -146,7 +149,7 @@ public class MySQLDictionary
|
||||||
"STARTING", "TABLE", "THEN", "TO", "TRAILING", "TRUE", "UNION",
|
"STARTING", "TABLE", "THEN", "TO", "TRAILING", "TRUE", "UNION",
|
||||||
"UNIQUE", "UNSIGNED", "UPDATE", "USAGE", "USING", "VALUES",
|
"UNIQUE", "UNSIGNED", "UPDATE", "USAGE", "USING", "VALUES",
|
||||||
"VARCHAR", "VARYING", "WHEN", "WHERE", "WITH", "WRITE", "ZEROFILL",
|
"VARCHAR", "VARYING", "WHEN", "WHERE", "WITH", "WRITE", "ZEROFILL",
|
||||||
"INDEX",
|
"INDEX",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
requiresSearchStringEscapeForLike = true;
|
requiresSearchStringEscapeForLike = true;
|
||||||
|
@ -158,7 +161,7 @@ public class MySQLDictionary
|
||||||
|
|
||||||
setLeadingDelimiter(DELIMITER_BACK_TICK);
|
setLeadingDelimiter(DELIMITER_BACK_TICK);
|
||||||
setTrailingDelimiter(DELIMITER_BACK_TICK);
|
setTrailingDelimiter(DELIMITER_BACK_TICK);
|
||||||
|
|
||||||
fixedSizeTypeNameSet.remove("NUMERIC");
|
fixedSizeTypeNameSet.remove("NUMERIC");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,7 +209,7 @@ public class MySQLDictionary
|
||||||
conn.setReadOnly(true);
|
conn.setReadOnly(true);
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int[] getMajorMinorVersions(String versionStr)
|
private static int[] getMajorMinorVersions(String versionStr)
|
||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
int beginIndex = 0;
|
int beginIndex = 0;
|
||||||
|
@ -275,7 +278,7 @@ public class MySQLDictionary
|
||||||
new String[]{ "ALTER TABLE "
|
new String[]{ "ALTER TABLE "
|
||||||
+ getFullName(fk.getTable(), false)
|
+ getFullName(fk.getTable(), false)
|
||||||
+ " DROP FOREIGN KEY " + toDBName(fkName) };
|
+ " DROP FOREIGN KEY " + toDBName(fkName) };
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
return new String[]{ "ALTER TABLE "
|
return new String[]{ "ALTER TABLE "
|
||||||
+ getFullName(fk.getTable(), false)
|
+ getFullName(fk.getTable(), false)
|
||||||
|
@ -300,7 +303,7 @@ public class MySQLDictionary
|
||||||
System.arraycopy(sql, 0, ret, cols.length, sql.length);
|
System.arraycopy(sql, 0, ret, cols.length, sql.length);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getDeleteTableContentsSQL(Table[] tables,Connection conn) {
|
public String[] getDeleteTableContentsSQL(Table[] tables,Connection conn) {
|
||||||
// mysql >= 4 supports more-optimal delete syntax
|
// mysql >= 4 supports more-optimal delete syntax
|
||||||
|
@ -356,10 +359,10 @@ public class MySQLDictionary
|
||||||
return Types.LONGVARCHAR;
|
return Types.LONGVARCHAR;
|
||||||
return super.getPreferredType(type);
|
return super.getPreferredType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append XML comparison.
|
* Append XML comparison.
|
||||||
*
|
*
|
||||||
* @param buf the SQL buffer to write the comparison
|
* @param buf the SQL buffer to write the comparison
|
||||||
* @param op the comparison operation to perform
|
* @param op the comparison operation to perform
|
||||||
* @param lhs the left hand side of the comparison
|
* @param lhs the left hand side of the comparison
|
||||||
|
@ -381,10 +384,10 @@ public class MySQLDictionary
|
||||||
else
|
else
|
||||||
rhs.appendTo(buf);
|
rhs.appendTo(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append XML column value so that it can be used in comparisons.
|
* Append XML column value so that it can be used in comparisons.
|
||||||
*
|
*
|
||||||
* @param buf the SQL buffer to write the value
|
* @param buf the SQL buffer to write the value
|
||||||
* @param val the value to be written
|
* @param val the value to be written
|
||||||
*/
|
*/
|
||||||
|
@ -395,7 +398,7 @@ public class MySQLDictionary
|
||||||
val.appendTo(buf);
|
val.appendTo(buf);
|
||||||
buf.append("')");
|
buf.append("')");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBatchFetchSize(int batchFetchSize) {
|
public int getBatchFetchSize(int batchFetchSize) {
|
||||||
return Integer.MIN_VALUE;
|
return Integer.MIN_VALUE;
|
||||||
|
@ -414,10 +417,10 @@ public class MySQLDictionary
|
||||||
select += " " + hint;
|
select += " " + hint;
|
||||||
return select;
|
return select;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Collection<String> getSelectTableAliases(Select sel) {
|
protected Collection<String> getSelectTableAliases(Select sel) {
|
||||||
Set<String> result = new HashSet<String>();
|
Set<String> result = new HashSet<>();
|
||||||
List<String> selects = sel.getIdentifierAliases();
|
List<String> selects = sel.getIdentifierAliases();
|
||||||
for (String s : selects) {
|
for (String s : selects) {
|
||||||
String tableAlias = s.substring(0, s.indexOf('.'));
|
String tableAlias = s.substring(0, s.indexOf('.'));
|
||||||
|
@ -425,7 +428,7 @@ public class MySQLDictionary
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int matchErrorState(Map<Integer,Set<String>> errorStates, SQLException ex) {
|
protected int matchErrorState(Map<Integer,Set<String>> errorStates, SQLException ex) {
|
||||||
int state = super.matchErrorState(errorStates, ex);
|
int state = super.matchErrorState(errorStates, ex);
|
||||||
|
@ -462,7 +465,7 @@ public class MySQLDictionary
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getTypeName(Column col) {
|
public String getTypeName(Column col) {
|
||||||
// handle blobs differently, if the DBItentifierType is NULL (e.g. no column definition is set).
|
// 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.getType() == Types.BLOB && col.getTypeIdentifier().getType() == DBIdentifierType.NULL) {
|
||||||
if (col.getSize() <= 0) // unknown size
|
if (col.getSize() <= 0) // unknown size
|
||||||
return blobTypeName; // return old default of 64KB
|
return blobTypeName; // return old default of 64KB
|
||||||
|
@ -474,6 +477,17 @@ public class MySQLDictionary
|
||||||
return mediumBlobTypeName;
|
return mediumBlobTypeName;
|
||||||
else
|
else
|
||||||
return longBlobTypeName;
|
return longBlobTypeName;
|
||||||
|
} else if (col.getType() == Types.CLOB && col.getTypeIdentifier().getType() == DBIdentifierType.NULL) {
|
||||||
|
if (col.getSize() <= 0) // unknown size
|
||||||
|
return clobTypeName; // return old default of 64KB
|
||||||
|
else if (col.getSize() <= 255)
|
||||||
|
return tinyTextTypeName;
|
||||||
|
else if (col.getSize() <= 65535)
|
||||||
|
return clobTypeName; // old default of 64KB
|
||||||
|
else if (col.getSize() <= 16777215)
|
||||||
|
return mediumTextTypeName;
|
||||||
|
else
|
||||||
|
return longTextTypeName;
|
||||||
} else {
|
} else {
|
||||||
return super.getTypeName(col);
|
return super.getTypeName(col);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* 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.persistence.blob.mysql;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Lob;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class ClobColumnEntity {
|
||||||
|
@Id
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
@Lob
|
||||||
|
@Column(length = 20)
|
||||||
|
protected String smallLob;
|
||||||
|
|
||||||
|
@Lob
|
||||||
|
@Column(length = 66000)
|
||||||
|
protected String medLob;
|
||||||
|
|
||||||
|
@Lob
|
||||||
|
@Column(length = 16777216)
|
||||||
|
protected String longLob;
|
||||||
|
|
||||||
|
@Lob
|
||||||
|
protected String defaultLob;
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSmallLob() {
|
||||||
|
return smallLob;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSmallLob(String smallLob) {
|
||||||
|
this.smallLob = smallLob;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMedLob() {
|
||||||
|
return medLob;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMedLob(String medLob) {
|
||||||
|
this.medLob = medLob;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLongLob() {
|
||||||
|
return longLob;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLongLob(String longLob) {
|
||||||
|
this.longLob = longLob;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDefaultLob() {
|
||||||
|
return defaultLob;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultLob(String defaultLob) {
|
||||||
|
this.defaultLob = defaultLob;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* 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.persistence.blob.mysql;
|
||||||
|
|
||||||
|
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testcase for MySQL Blob types. OPENJPA-740 introduced intelligent column type for BLOBs, OPENJPA-1870 refined it a
|
||||||
|
* bit.
|
||||||
|
*/
|
||||||
|
public class TestClobColumnType extends SingleEMFTestCase {
|
||||||
|
|
||||||
|
private static boolean _firstRun=true;
|
||||||
|
private boolean _runTest = false; // only test with MySQL
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
|
||||||
|
// create EMF solely to obtain a DBDictionary.
|
||||||
|
// need to do this without ClobColumnEntity.class since it contains a column definition which might
|
||||||
|
// not work with all databases.
|
||||||
|
super.setUp((Object) null);
|
||||||
|
if (!(getDBDictionary() instanceof MySQLDictionary || getDBDictionary() instanceof MariaDBDictionary)) {
|
||||||
|
// normal teardown will take care of the EMF.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove the EMF
|
||||||
|
tearDown();
|
||||||
|
|
||||||
|
_runTest = true;
|
||||||
|
super.setUp(ClobColumnEntity.class, DROP_TABLES, "openjpa.jdbc.SchemaFactory", "native");
|
||||||
|
|
||||||
|
if(_firstRun) {
|
||||||
|
emf.createEntityManager().close(); // trigger table creation.
|
||||||
|
_firstRun = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Column getCol(String name) {
|
||||||
|
ClassMapping mapping = getMapping(ClobColumnEntity.class);
|
||||||
|
|
||||||
|
Table t = mapping.getTable();
|
||||||
|
Column col = t.getColumn(DBIdentifier.newIdentifier(name, DBIdentifierType.COLUMN, true));
|
||||||
|
assertNotNull(col);
|
||||||
|
return col;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSmallLob() {
|
||||||
|
if (_runTest) {
|
||||||
|
assertEquals(MySQLDictionary.tinyTextTypeName, getCol("smallLob").getTypeIdentifier().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMedLob() {
|
||||||
|
if (_runTest) {
|
||||||
|
assertEquals(MySQLDictionary.mediumTextTypeName, getCol("medLob").getTypeIdentifier().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testLongBlob() {
|
||||||
|
if (_runTest) {
|
||||||
|
assertEquals(MySQLDictionary.longTextTypeName, getCol("longLob").getTypeIdentifier().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDefaultLob() {
|
||||||
|
if (_runTest) {
|
||||||
|
assertEquals(getDBDictionary().blobTypeName, getCol("defaultLob").getTypeIdentifier().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue