001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.spring.jpa;
016    
017    import com.liferay.portal.kernel.dao.db.DB;
018    import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
019    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.util.GetterUtil;
023    import com.liferay.portal.kernel.util.StringBundler;
024    import com.liferay.portal.kernel.util.Validator;
025    import com.liferay.portal.util.PropsValues;
026    
027    import java.sql.Connection;
028    import java.sql.DatabaseMetaData;
029    
030    import javax.sql.DataSource;
031    
032    import org.springframework.orm.jpa.vendor.Database;
033    
034    /**
035     * @author Prashant Dighe
036     * @author Brian Wing Shun Chan
037     */
038    public class DatabaseDetector {
039    
040            public static Database determineDatabase(DataSource dataSource) {
041                    Database database = null;
042                    String type = null;
043    
044                    Connection connection = null;
045    
046                    try {
047                            connection = dataSource.getConnection();
048    
049                            DatabaseMetaData databaseMetaData = connection.getMetaData();
050    
051                            String dbName = databaseMetaData.getDatabaseProductName();
052                            int dbMajorVersion = databaseMetaData.getDatabaseMajorVersion();
053    
054                            if (_log.isInfoEnabled()) {
055                                    _log.info(
056                                            "Determining DB type for " + dbName + " " + dbMajorVersion);
057                            }
058    
059                            if (dbName.equals("Apache Derby")) {
060                                    database = Database.DERBY;
061                                    type = DB.TYPE_DERBY;
062                            }
063                            else if (dbName.startsWith("DB2/")) {
064                                    database = Database.DB2;
065                                    type = DB.TYPE_DB2;
066                            }
067                            else if (dbName.equals("HSQL Database Engine")) {
068                                    if (_log.isWarnEnabled()) {
069                                            StringBundler sb = new StringBundler(6);
070    
071                                            sb.append("Liferay is configured to use Hypersonic as ");
072                                            sb.append("its database. Do NOT use Hypersonic in ");
073                                            sb.append("production. Hypersonic is an embedded ");
074                                            sb.append("database useful for development and demo'ing ");
075                                            sb.append("purposes. The database settings can be ");
076                                            sb.append("changed in portal-ext.properties.");
077    
078                                            _log.warn(sb.toString());
079                                    }
080    
081                                    database = Database.HSQL;
082                                    type = DB.TYPE_HYPERSONIC;
083                            }
084                            else if (dbName.equals("Informix Dynamic Server")) {
085                                    database = Database.INFORMIX;
086                                    type = DB.TYPE_INFORMIX;
087                            }
088                            else if (dbName.startsWith("Microsoft SQL Server")) {
089                                    database = Database.SQL_SERVER;
090                                    type = DB.TYPE_SQLSERVER;
091                            }
092                            else if (dbName.equals("MySQL")) {
093                                    database = Database.MYSQL;
094                                    type = DB.TYPE_MYSQL;
095                            }
096                            else if (dbName.equals("Oracle")) {
097                                    database = Database.ORACLE;
098                                    type = DB.TYPE_ORACLE;
099                            }
100                            else if (dbName.equals("PostgreSQL")) {
101                                    database = Database.POSTGRESQL;
102                                    type = DB.TYPE_POSTGRESQL;
103                            }
104                            else if (dbName.equals("Sybase SQL Server")) {
105                                    database = Database.SYBASE;
106                                    type = DB.TYPE_SYBASE;
107                            }
108    
109                            if (dbName.equals("ASE") && (dbMajorVersion == 15)) {
110                                    database = Database.SYBASE;
111                                    type = DB.TYPE_SYBASE;
112                            }
113                    }
114                    catch (Exception e) {
115                            String msg = GetterUtil.getString(e.getMessage());
116    
117                            if (msg.contains("explicitly set for database: DB2")) {
118                                    database = Database.DB2;
119    
120                                    type = DB.TYPE_DB2;
121                            }
122                            else {
123                                    _log.error(e, e);
124                            }
125                    }
126                    finally {
127                            DataAccess.cleanUp(connection);
128                    }
129    
130                    if (database == null) {
131                            throw new RuntimeException("Unable to detect the database");
132                    }
133    
134                    if (_log.isInfoEnabled()) {
135                            _log.info("Detected database " + database.toString());
136                    }
137    
138                    if (Validator.isNotNull(PropsValues.JPA_DATABASE_TYPE)) {
139                            DBFactoryUtil.setDB(PropsValues.JPA_DATABASE_TYPE);
140                    }
141                    else {
142                            DBFactoryUtil.setDB(type);
143                    }
144    
145                    return database;
146            }
147    
148            private static Log _log = LogFactoryUtil.getLog(DatabaseDetector.class);
149    
150    }