com.liferay.portal.dao.db.BaseDB Maven / Gradle / Ivy
/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.dao.db;
import com.liferay.petra.function.UnsafeConsumer;
import com.liferay.petra.string.CharPool;
import com.liferay.petra.string.StringBundler;
import com.liferay.petra.string.StringPool;
import com.liferay.portal.dao.orm.common.SQLTransformer;
import com.liferay.portal.db.partition.DBPartitionUtil;
import com.liferay.portal.kernel.configuration.Filter;
import com.liferay.portal.kernel.dao.db.DB;
import com.liferay.portal.kernel.dao.db.DBInspector;
import com.liferay.portal.kernel.dao.db.DBType;
import com.liferay.portal.kernel.dao.db.Index;
import com.liferay.portal.kernel.dao.db.IndexMetadata;
import com.liferay.portal.kernel.dao.db.IndexMetadataFactoryUtil;
import com.liferay.portal.kernel.dao.jdbc.DataAccess;
import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.MapUtil;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.PropsUtil;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.naming.NamingException;
/**
* @author Alexander Chow
* @author Ganesh Ram
* @author Brian Wing Shun Chan
* @author Daniel Kocsis
*/
public abstract class BaseDB implements DB {
@Override
public void addIndexes(
Connection connection, List indexMetadatas)
throws IOException, SQLException {
DatabaseMetaData databaseMetaData = connection.getMetaData();
DBInspector dbInspector = new DBInspector(connection);
Map> columnTableSizes = new HashMap<>();
for (IndexMetadata indexMetadata : indexMetadatas) {
String normalizedTabledName = dbInspector.normalizeName(
indexMetadata.getTableName(), databaseMetaData);
if (columnTableSizes.get(normalizedTabledName) == null) {
try (ResultSet resultSet = databaseMetaData.getColumns(
dbInspector.getCatalog(), dbInspector.getSchema(),
normalizedTabledName, null)) {
Map columnSizes = new HashMap<>();
while (resultSet.next()) {
int columnType = resultSet.getInt("DATA_TYPE");
if (!ArrayUtil.contains(
SQL_VARCHAR_TYPES, columnType)) {
continue;
}
columnSizes.put(
dbInspector.normalizeName(
resultSet.getString("COLUMN_NAME"),
databaseMetaData),
resultSet.getInt("COLUMN_SIZE"));
}
columnTableSizes.put(normalizedTabledName, columnSizes);
}
}
String[] columnNames = indexMetadata.getColumnNames();
int[] columnSizes = new int[columnNames.length];
for (int i = 0; i < columnNames.length; i++) {
columnSizes[i] = MapUtil.getInteger(
columnTableSizes.get(normalizedTabledName), columnNames[i],
0);
}
runSQL(
_applyMaxStringIndexLengthLimitation(
indexMetadata.getCreateSQL(columnSizes)));
}
}
public void alterColumnName(
Connection connection, String tableName, String oldColumnName,
String newColumnDefinition)
throws Exception {
StringBundler sb = new StringBundler(6);
sb.append("alter_column_name ");
sb.append(tableName);
sb.append(StringPool.SPACE);
sb.append(oldColumnName);
sb.append(StringPool.SPACE);
sb.append(newColumnDefinition);
runSQL(connection, sb.toString());
}
public void alterColumnType(
Connection connection, String tableName, String columnName,
String newColumnType)
throws Exception {
StringBundler sb = new StringBundler(6);
sb.append("alter_column_type ");
sb.append(tableName);
sb.append(StringPool.SPACE);
sb.append(columnName);
sb.append(StringPool.SPACE);
sb.append(newColumnType);
runSQL(connection, sb.toString());
}
public void alterTableAddColumn(
Connection connection, String tableName, String columnName,
String columnType)
throws Exception {
StringBundler sb = new StringBundler(6);
sb.append("alter table ");
sb.append(tableName);
sb.append(" add ");
sb.append(columnName);
sb.append(StringPool.SPACE);
sb.append(columnType);
runSQL(connection, sb.toString());
}
public void alterTableDropColumn(
Connection connection, String tableName, String columnName)
throws Exception {
StringBundler sb = new StringBundler(4);
sb.append("alter table ");
sb.append(tableName);
sb.append(" drop column ");
sb.append(columnName);
runSQL(connection, sb.toString());
}
@Override
public abstract String buildSQL(String template)
throws IOException, SQLException;
@Override
public List dropIndexes(
Connection connection, String tableName, String columnName)
throws IOException, SQLException {
List indexMetadatas = getIndexes(
connection, tableName, columnName, false);
for (IndexMetadata indexMetadata : indexMetadatas) {
runSQL(connection, indexMetadata.getDropSQL());
}
return indexMetadatas;
}
@Override
public DBType getDBType() {
return _dbType;
}
@Override
public List getIndexes(Connection connection) throws SQLException {
List indexes = getIndexes(connection, null, null, false);
Stream stream = indexes.stream();
return stream.map(
index -> new Index(
index.getIndexName(), index.getTableName(), index.isUnique())
).collect(
Collectors.toList()
);
}
@Override
public ResultSet getIndexResultSet(Connection connection, String tableName)
throws SQLException {
DatabaseMetaData databaseMetaData = connection.getMetaData();
DBInspector dbInspector = new DBInspector(connection);
return databaseMetaData.getIndexInfo(
dbInspector.getCatalog(), dbInspector.getSchema(), tableName, false,
false);
}
@Override
public int getMajorVersion() {
return _majorVersion;
}
@Override
public int getMinorVersion() {
return _minorVersion;
}
@Override
public String[] getPrimaryKeyColumnNames(
Connection connection, String tableName)
throws SQLException {
DatabaseMetaData databaseMetaData = connection.getMetaData();
DBInspector dbInspector = new DBInspector(connection);
String normalizedTableName = dbInspector.normalizeName(
tableName, databaseMetaData);
String[] columnNames = new String[0];
try (ResultSet resultSet = databaseMetaData.getPrimaryKeys(
dbInspector.getCatalog(), dbInspector.getSchema(),
normalizedTableName)) {
while (resultSet.next()) {
columnNames = ArrayUtil.append(
columnNames,
dbInspector.normalizeName(
resultSet.getString("COLUMN_NAME"), databaseMetaData));
}
}
return columnNames;
}
@Override
public Integer getSQLType(String templateType) {
return _sqlTypes.get(templateType);
}
@Override
public Integer getSQLVarcharSize(String templateType) {
return _sqlVarcharSizes.get(templateType);
}
@Override
public String getTemplateBlob() {
return getTemplate()[5];
}
@Override
public String getTemplateFalse() {
return getTemplate()[2];
}
@Override
public String getTemplateTrue() {
return getTemplate()[1];
}
@Override
public String getVersionString() {
return _majorVersion + StringPool.PERIOD + _minorVersion;
}
@Override
public boolean isSupportsAlterColumnName() {
return _SUPPORTS_ALTER_COLUMN_NAME;
}
@Override
public boolean isSupportsAlterColumnType() {
return _SUPPORTS_ALTER_COLUMN_TYPE;
}
@Override
public boolean isSupportsInlineDistinct() {
return _SUPPORTS_INLINE_DISTINCT;
}
@Override
public boolean isSupportsQueryingAfterException() {
return _SUPPORTS_QUERYING_AFTER_EXCEPTION;
}
@Override
public boolean isSupportsScrollableResults() {
return _SUPPORTS_SCROLLABLE_RESULTS;
}
@Override
public boolean isSupportsStringCaseSensitiveQuery() {
return _supportsStringCaseSensitiveQuery;
}
@Override
public boolean isSupportsUpdateWithInnerJoin() {
return _SUPPORTS_UPDATE_WITH_INNER_JOIN;
}
@Override
public void process(UnsafeConsumer unsafeConsumer)
throws Exception {
DBPartitionUtil.forEachCompanyId(unsafeConsumer);
}
@Override
public void removePrimaryKey(Connection connection, String tableName)
throws Exception {
DatabaseMetaData databaseMetaData = connection.getMetaData();
DBInspector dbInspector = new DBInspector(connection);
String normalizedTableName = dbInspector.normalizeName(
tableName, databaseMetaData);
runSQL(
StringBundler.concat(
"alter table ", normalizedTableName, " drop primary key"));
}
@Override
public void runSQL(Connection connection, String sql)
throws IOException, SQLException {
runSQL(connection, new String[] {sql});
}
@Override
public void runSQL(Connection connection, String[] sqls)
throws IOException, SQLException {
try (Statement s = connection.createStatement()) {
for (String sql : sqls) {
sql = buildSQL(sql);
if (Validator.isNull(sql)) {
continue;
}
sql = SQLTransformer.transform(sql.trim());
if (sql.endsWith(";")) {
sql = sql.substring(0, sql.length() - 1);
}
if (sql.endsWith("\ngo")) {
sql = sql.substring(0, sql.length() - 3);
}
if (sql.endsWith("\n/")) {
sql = sql.substring(0, sql.length() - 2);
}
if (_log.isDebugEnabled()) {
_log.debug(sql);
}
try {
s.executeUpdate(sql);
}
catch (SQLException sqlException) {
if (_log.isDebugEnabled()) {
_log.debug(
StringBundler.concat(
"SQL: ", sql, "\nSQL state: ",
sqlException.getSQLState(), "\nVendor: ",
getDBType(), "\nVendor error code: ",
sqlException.getErrorCode(),
"\nVendor error message: ",
sqlException.getMessage()));
}
throw sqlException;
}
}
}
}
@Override
public void runSQL(String sql) throws IOException, SQLException {
runSQL(new String[] {sql});
}
@Override
public void runSQL(String[] sqls) throws IOException, SQLException {
try (Connection connection = DataAccess.getConnection()) {
runSQL(connection, sqls);
}
}
@Override
public void runSQLTemplateString(
Connection connection, String template, boolean failOnError)
throws IOException, NamingException, SQLException {
template = StringUtil.trim(template);
if ((template == null) || template.isEmpty()) {
return;
}
if (!template.endsWith(StringPool.SEMICOLON)) {
template += StringPool.SEMICOLON;
}
try (UnsyncBufferedReader unsyncBufferedReader =
new UnsyncBufferedReader(new UnsyncStringReader(template))) {
StringBundler sb = new StringBundler();
String line = null;
Thread currentThread = Thread.currentThread();
ClassLoader classLoader = currentThread.getContextClassLoader();
while ((line = unsyncBufferedReader.readLine()) != null) {
if (line.isEmpty() || line.startsWith("##")) {
continue;
}
if (line.startsWith("@include ")) {
int pos = line.indexOf(" ");
int end = line.length();
if (StringUtil.endsWith(line, StringPool.SEMICOLON)) {
end -= 1;
}
String includeFileName = line.substring(pos + 1, end);
InputStream inputStream = classLoader.getResourceAsStream(
"com/liferay/portal/tools/sql/dependencies/" +
includeFileName);
if (inputStream == null) {
inputStream = classLoader.getResourceAsStream(
includeFileName);
}
String include = StringUtil.read(inputStream);
include = replaceTemplate(include);
runSQLTemplateString(include, true);
}
else {
sb.append(line);
sb.append(StringPool.NEW_LINE);
if (line.endsWith(";")) {
String sql = sb.toString();
sb.setIndex(0);
try {
if (!sql.equals("COMMIT_TRANSACTION;\n")) {
runSQL(connection, sql);
}
else {
if (_log.isDebugEnabled()) {
_log.debug("Skip commit sql");
}
}
}
catch (IOException ioException) {
if (failOnError) {
throw ioException;
}
else if (_log.isWarnEnabled()) {
_log.warn(ioException);
}
}
catch (SecurityException securityException) {
if (failOnError) {
throw securityException;
}
else if (_log.isWarnEnabled()) {
_log.warn(securityException);
}
}
catch (SQLException sqlException) {
if (failOnError) {
throw sqlException;
}
String message = GetterUtil.getString(
sqlException.getMessage());
if (!message.startsWith("Duplicate key name") &&
_log.isWarnEnabled()) {
_log.warn(message + ": " + buildSQL(sql));
}
if (message.startsWith("Duplicate entry") ||
message.startsWith(
"Specified key was too long")) {
_log.error(line);
}
}
}
}
}
}
}
@Override
public void runSQLTemplateString(String template, boolean failOnError)
throws IOException, NamingException, SQLException {
try (Connection connection = DataAccess.getConnection()) {
runSQLTemplateString(connection, template, failOnError);
}
}
@Override
public void setSupportsStringCaseSensitiveQuery(
boolean supportsStringCaseSensitiveQuery) {
if (_log.isDebugEnabled()) {
if (supportsStringCaseSensitiveQuery) {
_log.debug("Database supports case sensitive queries");
}
else {
_log.debug("Database does not support case sensitive queries");
}
}
_supportsStringCaseSensitiveQuery = supportsStringCaseSensitiveQuery;
SQLTransformer.reloadSQLTransformer();
}
@Override
public void updateIndexes(
Connection connection, String tablesSQL, String indexesSQL,
boolean dropIndexes)
throws Exception {
List indexes = getIndexes(connection);
Set validIndexNames = null;
if (dropIndexes) {
validIndexNames = dropIndexes(
connection, tablesSQL, indexesSQL, indexes);
}
else {
validIndexNames = new HashSet<>();
for (Index index : indexes) {
String indexName = StringUtil.toUpperCase(index.getIndexName());
validIndexNames.add(indexName);
}
}
_addIndexes(
connection, _applyMaxStringIndexLengthLimitation(indexesSQL),
validIndexNames);
}
protected BaseDB(DBType dbType, int majorVersion, int minorVersion) {
_dbType = dbType;
_majorVersion = majorVersion;
_minorVersion = minorVersion;
String[] actual = getTemplate();
for (int i = 0; i < TEMPLATE.length; i++) {
_templates.put(TEMPLATE[i], actual[i]);
}
String[] templateTypes = ArrayUtil.clone(TEMPLATE, 5, 15);
for (int i = 0; i < templateTypes.length; i++) {
_sqlTypes.put(StringUtil.trim(templateTypes[i]), getSQLTypes()[i]);
}
String[] sqlTypeStringAndText = ArrayUtil.clone(TEMPLATE, 12, 14);
for (int i = 0; i < sqlTypeStringAndText.length; i++) {
_sqlVarcharSizes.put(
StringUtil.trim(sqlTypeStringAndText[i]),
getSQLVarcharSizes()[i]);
}
}
protected void addPrimaryKey(
Connection connection, String tableName, String[] columnNames)
throws IOException, SQLException {
DatabaseMetaData databaseMetaData = connection.getMetaData();
DBInspector dbInspector = new DBInspector(connection);
StringBundler sb = new StringBundler();
sb.append("alter table ");
sb.append(dbInspector.normalizeName(tableName, databaseMetaData));
sb.append(" add primary key (");
for (String columnName : columnNames) {
sb.append(columnName);
sb.append(", ");
}
sb.setIndex(sb.index() - 1);
sb.append(")");
runSQL(sb.toString());
}
protected String[] buildColumnNameTokens(String line) {
String[] words = StringUtil.split(line, CharPool.SPACE);
String nullable = "";
if (words.length == 7) {
nullable = "not null;";
}
return new String[] {words[1], words[2], words[3], words[4], nullable};
}
protected String[] buildColumnTypeTokens(String line) {
String[] words = StringUtil.split(line, CharPool.SPACE);
String nullable = "";
if (words.length == 6) {
nullable = "not null";
}
else if (words.length == 5) {
nullable = "null";
}
else if (words.length == 4) {
if (words[3].endsWith(";")) {
words[3] = words[3].substring(0, words[3].length() - 1);
}
}
return new String[] {words[1], words[2], "", words[3], nullable};
}
protected String[] buildTableNameTokens(String line) {
String[] words = StringUtil.split(line, CharPool.SPACE);
return new String[] {words[1], words[2]};
}
protected Set dropIndexes(
Connection connection, String tablesSQL, String indexesSQL,
List indexes)
throws IOException, SQLException {
if (_log.isInfoEnabled()) {
_log.info("Dropping stale indexes");
}
Set validIndexNames = new HashSet<>();
if (indexes.isEmpty()) {
return validIndexNames;
}
String tablesSQLLowerCase = StringUtil.toLowerCase(tablesSQL);
String indexesSQLLowerCase = StringUtil.toLowerCase(indexesSQL);
String[] lines = StringUtil.splitLines(indexesSQL);
Set indexNames = new HashSet<>();
for (String line : lines) {
if (Validator.isNull(line)) {
continue;
}
IndexMetadata indexMetadata =
IndexMetadataFactoryUtil.createIndexMetadata(line);
indexNames.add(
StringUtil.toLowerCase(indexMetadata.getIndexName()));
}
for (Index index : indexes) {
String indexNameUpperCase = StringUtil.toUpperCase(
index.getIndexName());
String indexNameLowerCase = StringUtil.toLowerCase(
indexNameUpperCase);
String tableName = index.getTableName();
String tableNameLowerCase = StringUtil.toLowerCase(tableName);
validIndexNames.add(indexNameUpperCase);
if (indexNames.contains(indexNameLowerCase)) {
boolean unique = index.isUnique();
if (unique &&
indexesSQLLowerCase.contains(
"create unique index " + indexNameLowerCase + " ")) {
continue;
}
if (!unique &&
indexesSQLLowerCase.contains(
"create index " + indexNameLowerCase + " ")) {
continue;
}
}
else if (!tablesSQLLowerCase.contains(
CREATE_TABLE + tableNameLowerCase + " (")) {
continue;
}
validIndexNames.remove(indexNameUpperCase);
String sql = StringBundler.concat(
"drop index ", indexNameUpperCase, " on ", tableName);
if (_log.isInfoEnabled()) {
_log.info(sql);
}
runSQL(connection, sql);
}
return validIndexNames;
}
protected List getIndexes(
Connection connection, String tableName, String columnName,
boolean onlyUnique)
throws SQLException {
List indexMetadatas = new ArrayList<>();
DatabaseMetaData databaseMetaData = connection.getMetaData();
DBInspector dbInspector = new DBInspector(connection);
String catalog = dbInspector.getCatalog();
String schema = dbInspector.getSchema();
String normalizedTableName = tableName;
if (normalizedTableName != null) {
normalizedTableName = dbInspector.normalizeName(
tableName, databaseMetaData);
}
String normalizedColumnName = columnName;
if (normalizedColumnName != null) {
normalizedColumnName = dbInspector.normalizeName(
columnName, databaseMetaData);
}
try (ResultSet tableResultSet = databaseMetaData.getTables(
catalog, schema, normalizedTableName, new String[] {"TABLE"})) {
while (tableResultSet.next()) {
normalizedTableName = dbInspector.normalizeName(
tableResultSet.getString("TABLE_NAME"), databaseMetaData);
try (ResultSet indexResultSet = databaseMetaData.getIndexInfo(
catalog, schema, normalizedTableName, onlyUnique,
false)) {
boolean unique = false;
String[] columnNames = new String[0];
String previousIndexName = null;
while (indexResultSet.next()) {
String indexName = indexResultSet.getString(
"INDEX_NAME");
if (indexName == null) {
continue;
}
String lowerCaseIndexName = StringUtil.toLowerCase(
indexName);
if (!lowerCaseIndexName.startsWith("liferay_") &&
!lowerCaseIndexName.startsWith("ix_")) {
continue;
}
if ((previousIndexName != null) &&
!previousIndexName.equals(indexName)) {
if ((normalizedColumnName == null) ||
ArrayUtil.contains(
columnNames, normalizedColumnName)) {
indexMetadatas.add(
new IndexMetadata(
previousIndexName, normalizedTableName,
unique, columnNames));
}
columnNames = new String[0];
}
previousIndexName = indexName;
unique = !indexResultSet.getBoolean("NON_UNIQUE");
columnNames = ArrayUtil.append(
columnNames,
dbInspector.normalizeName(
indexResultSet.getString("COLUMN_NAME"),
databaseMetaData));
}
if ((previousIndexName != null) &&
((normalizedColumnName == null) ||
ArrayUtil.contains(
columnNames, normalizedColumnName))) {
indexMetadatas.add(
new IndexMetadata(
previousIndexName, normalizedTableName, unique,
columnNames));
}
}
}
}
return new ArrayList<>(indexMetadatas);
}
protected abstract int[] getSQLTypes();
protected int[] getSQLVarcharSizes() {
return new int[] {-1, -1};
}
protected abstract String[] getTemplate();
protected String limitColumnLength(String column, int length) {
return StringBundler.concat(column, "\\(", length, "\\)");
}
protected String replaceTemplate(String template) {
if (Validator.isNull(template)) {
return null;
}
StringBundler sb = null;
int endIndex = 0;
Matcher matcher = _templatePattern.matcher(template);
while (matcher.find()) {
int startIndex = matcher.start();
if (sb == null) {
sb = new StringBundler();
}
sb.append(template.substring(endIndex, startIndex));
endIndex = matcher.end();
String matched = template.substring(startIndex, endIndex);
sb.append(_templates.get(matched));
}
if (sb == null) {
return _applyMaxStringIndexLengthLimitation(template);
}
if (template.length() > endIndex) {
sb.append(template.substring(endIndex));
}
return _applyMaxStringIndexLengthLimitation(sb.toString());
}
protected abstract String reword(String data)
throws IOException, SQLException;
protected static final String ALTER_COLUMN_NAME = "alter_column_name ";
protected static final String ALTER_COLUMN_TYPE = "alter_column_type ";
protected static final String ALTER_TABLE_NAME = "alter_table_name ";
protected static final String CREATE_TABLE = "create table ";
protected static final String DROP_INDEX = "drop index";
protected static final String DROP_PRIMARY_KEY = "drop primary key";
protected static final String[] RENAME_TABLE_TEMPLATE = {
"@old-table@", "@new-table@"
};
protected static final String[] REWORD_TEMPLATE = {
"@table@", "@old-column@", "@new-column@", "@type@", "@nullable@"
};
protected static final int[] SQL_VARCHAR_TYPES = {
Types.LONGNVARCHAR, Types.LONGVARCHAR, Types.NVARCHAR, Types.VARCHAR
};
protected static final String[] TEMPLATE = {
"##", "TRUE", "FALSE", "'01/01/1970'", "CURRENT_TIMESTAMP", " BLOB",
" SBLOB", " BOOLEAN", " DATE", " DOUBLE", " INTEGER", " LONG",
" STRING", " TEXT", " VARCHAR", " IDENTITY", "COMMIT_TRANSACTION"
};
protected static final Pattern columnTypePattern = Pattern.compile(
"(^\\w+)", Pattern.CASE_INSENSITIVE);
private void _addIndexes(
Connection connection, String indexesSQL,
Set validIndexNames)
throws Exception {
if (_log.isInfoEnabled()) {
_log.info("Adding indexes");
}
try (UnsyncBufferedReader unsyncBufferedReader =
new UnsyncBufferedReader(new UnsyncStringReader(indexesSQL))) {
String sql = null;
while ((sql = unsyncBufferedReader.readLine()) != null) {
if (Validator.isNull(sql)) {
continue;
}
int y = sql.indexOf(" on ");
int x = sql.lastIndexOf(" ", y - 1);
String indexName = sql.substring(x + 1, y);
if (validIndexNames.contains(indexName)) {
continue;
}
if (_log.isInfoEnabled()) {
_log.info(sql);
}
try {
runSQL(connection, sql);
}
catch (Exception exception) {
if (_log.isWarnEnabled()) {
_log.warn(exception.getMessage() + ": " + sql);
}
}
}
}
}
private String _applyMaxStringIndexLengthLimitation(String template) {
if (!template.contains("[$COLUMN_LENGTH:")) {
return template;
}
DBType dbType = getDBType();
int stringIndexMaxLength = GetterUtil.getInteger(
PropsUtil.get(
PropsKeys.DATABASE_STRING_INDEX_MAX_LENGTH,
new Filter(dbType.getName())),
-1);
Matcher matcher = _columnLengthPattern.matcher(template);
if (stringIndexMaxLength < 0) {
return matcher.replaceAll("$1");
}
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
int length = Integer.valueOf(matcher.group(2));
if (length > stringIndexMaxLength) {
matcher.appendReplacement(
sb,
limitColumnLength(matcher.group(1), stringIndexMaxLength));
}
else {
matcher.appendReplacement(sb, matcher.group(1));
}
}
matcher.appendTail(sb);
return sb.toString();
}
private static final boolean _SUPPORTS_ALTER_COLUMN_NAME = true;
private static final boolean _SUPPORTS_ALTER_COLUMN_TYPE = true;
private static final boolean _SUPPORTS_INLINE_DISTINCT = true;
private static final boolean _SUPPORTS_QUERYING_AFTER_EXCEPTION = true;
private static final boolean _SUPPORTS_SCROLLABLE_RESULTS = true;
private static final boolean _SUPPORTS_UPDATE_WITH_INNER_JOIN = true;
private static final Log _log = LogFactoryUtil.getLog(BaseDB.class);
private static final Pattern _columnLengthPattern = Pattern.compile(
"([^,(\\s]+)\\[\\$COLUMN_LENGTH:(\\d+)\\$\\]");
private static final Pattern _templatePattern;
static {
StringBundler sb = new StringBundler((TEMPLATE.length * 5) - 6);
for (int i = 0; i < TEMPLATE.length; i++) {
String variable = TEMPLATE[i];
if (variable.equals("##") || variable.equals("'01/01/1970'")) {
sb.append(variable);
}
else {
sb.append("(? _sqlTypes = new HashMap<>();
private final Map _sqlVarcharSizes = new HashMap<>();
private boolean _supportsStringCaseSensitiveQuery = true;
private final Map _templates = new HashMap<>();
} © 2015 - 2025 Weber Informatics LLC | Privacy Policy