/**
* 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.spring.hibernate;
import com.liferay.portal.dao.orm.hibernate.DB2Dialect;
import com.liferay.portal.dao.orm.hibernate.HSQLDialect;
import com.liferay.portal.dao.orm.hibernate.SQLServer2005Dialect;
import com.liferay.portal.dao.orm.hibernate.SQLServer2008Dialect;
import com.liferay.portal.dao.orm.hibernate.SybaseASE157Dialect;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import javax.sql.DataSource;
import org.hibernate.dialect.DB2400Dialect;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.Oracle10gDialect;
import org.hibernate.dialect.resolver.DialectFactory;
/**
* @author Brian Wing Shun Chan
*/
public class DialectDetector {
public static Dialect getDialect(DataSource dataSource) {
String dialectKey = null;
Dialect dialect = null;
try (Connection connection = dataSource.getConnection()) {
DatabaseMetaData databaseMetaData = connection.getMetaData();
String dbName = databaseMetaData.getDatabaseProductName();
int dbMajorVersion = databaseMetaData.getDatabaseMajorVersion();
int dbMinorVersion = databaseMetaData.getDatabaseMinorVersion();
StringBundler sb = new StringBundler(5);
sb.append(dbName);
sb.append(StringPool.COLON);
sb.append(dbMajorVersion);
sb.append(StringPool.COLON);
sb.append(dbMinorVersion);
dialectKey = sb.toString();
dialect = _dialects.get(dialectKey);
if (dialect != null) {
return dialect;
}
if (_log.isInfoEnabled()) {
_log.info(
"Determine dialect for " + dbName + " " + dbMajorVersion +
"." + dbMinorVersion);
}
if (dbName.startsWith("HSQL")) {
dialect = new HSQLDialect();
if (_log.isWarnEnabled()) {
sb = new StringBundler(6);
sb.append("Liferay is configured to use Hypersonic as ");
sb.append("its database. Do NOT use Hypersonic in ");
sb.append("production. Hypersonic is an embedded ");
sb.append("database useful for development and ");
sb.append("demonstration purposes. The database settings ");
sb.append("can be changed in portal-ext.properties.");
_log.warn(sb.toString());
}
}
else if (dbName.equals("Adaptive Server Enterprise") &&
(dbMajorVersion >= 15)) {
dialect = new SybaseASE157Dialect();
}
else if (dbName.equals("ASE")) {
throw new RuntimeException(
"jTDS is no longer suppported. Please use the Sybase " +
"JDBC driver to connect to Sybase.");
}
else if (dbName.startsWith("DB2") && (dbMajorVersion >= 9)) {
dialect = new DB2Dialect();
}
else if (dbName.startsWith("Microsoft") && (dbMajorVersion == 9)) {
dialect = new SQLServer2005Dialect();
}
else if (dbName.startsWith("Microsoft") && (dbMajorVersion == 10)) {
dialect = new SQLServer2008Dialect();
}
else if (dbName.startsWith("Oracle") && (dbMajorVersion >= 10)) {
dialect = new Oracle10gDialect();
}
else {
dialect = DialectFactory.buildDialect(
new Properties(), connection);
}
}
catch (Exception e) {
String msg = GetterUtil.getString(e.getMessage());
if (msg.contains("explicitly set for database: DB2")) {
dialect = new DB2400Dialect();
if (_log.isWarnEnabled()) {
_log.warn(
"DB2400Dialect was dynamically chosen as the " +
"Hibernate dialect for DB2. This can be " +
"overriden in portal.properties");
}
}
else {
_log.error(e, e);
}
}
if (dialect == null) {
throw new RuntimeException("No dialect found");
}
else if (dialectKey != null) {
if (_log.isInfoEnabled()) {
Class<?> clazz = dialect.getClass();
_log.info("Found dialect " + clazz.getName());
}
_dialects.put(dialectKey, dialect);
}
return dialect;
}
private static final Log _log = LogFactoryUtil.getLog(
DialectDetector.class);
private static final Map<String, Dialect> _dialects =
new ConcurrentHashMap<>();
}