package io.ebeaninternal.server.core; import io.ebean.config.ServerConfig; import io.ebean.config.dbplatform.db2.DB2Platform; import io.ebean.config.dbplatform.DatabasePlatform; import io.ebean.config.dbplatform.h2.H2Platform; import io.ebean.config.dbplatform.hsqldb.HsqldbPlatform; import io.ebean.config.dbplatform.sqlserver.SqlServerPlatform; import io.ebean.config.dbplatform.mysql.MySqlPlatform; import io.ebean.config.dbplatform.oracle.OraclePlatform; import io.ebean.config.dbplatform.postgres.Postgres8Platform; import io.ebean.config.dbplatform.postgres.PostgresPlatform; import io.ebean.config.dbplatform.sqlite.SQLitePlatform; import io.ebean.config.dbplatform.sqlanywhere.SqlAnywherePlatform; import io.ebean.dbmigration.DbOffline; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.persistence.PersistenceException; import javax.sql.DataSource; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.SQLException; /** * Create a DatabasePlatform from the configuration. * <p> * Will used platform name or use the meta data from the JDBC driver to * determine the platform automatically. * </p> */ public class DatabasePlatformFactory { private static final Logger logger = LoggerFactory.getLogger(DatabasePlatformFactory.class); /** * Create the appropriate database specific platform. */ public DatabasePlatform create(ServerConfig serverConfig) { try { String offlinePlatform = DbOffline.getPlatform(); if (offlinePlatform != null) { logger.info("offline platform [{}]", offlinePlatform); return byDatabaseName(offlinePlatform); } if (serverConfig.getDatabasePlatformName() != null) { // choose based on dbName return byDatabaseName(serverConfig.getDatabasePlatformName()); } if (serverConfig.getDataSourceConfig().isOffline()) { String m = "You must specify a DatabasePlatformName when you are offline"; throw new PersistenceException(m); } // guess using meta data from driver return byDataSource(serverConfig.getDataSource()); } catch (Exception ex) { throw new PersistenceException(ex); } } /** * Lookup the platform by name. */ private DatabasePlatform byDatabaseName(String dbName) { dbName = dbName.toLowerCase(); if (dbName.equals("h2")) { return new H2Platform(); } if (dbName.equals("mysql")) { return new MySqlPlatform(); } if (dbName.equals("postgres") || dbName.equals("postgres9")) { return new PostgresPlatform(); } if (dbName.equals("postgres8") || dbName.equals("postgres83")) { return new Postgres8Platform(); } if (dbName.equals("oracle") || dbName.equals("oracle10") || dbName.equals("oracle9")) { return new OraclePlatform(); } if (dbName.equals("sqlserver")) { return new SqlServerPlatform(); } if (dbName.equals("sqlanywhere")) { return new SqlAnywherePlatform(); } if (dbName.equals("db2")) { return new DB2Platform(); } if (dbName.equals("sqlite")) { return new SQLitePlatform(); } throw new RuntimeException("database platform " + dbName + " is not known?"); } /** * Use JDBC DatabaseMetaData to determine the platform. */ private DatabasePlatform byDataSource(DataSource dataSource) { Connection conn = null; try { conn = dataSource.getConnection(); DatabaseMetaData metaData = conn.getMetaData(); return byDatabaseMeta(metaData); } catch (SQLException ex) { throw new PersistenceException(ex); } finally { try { if (conn != null) { conn.close(); } } catch (SQLException ex) { logger.error(null, ex); } } } /** * Find the platform by the metaData.getDatabaseProductName(). */ private DatabasePlatform byDatabaseMeta(DatabaseMetaData metaData) throws SQLException { String dbProductName = metaData.getDatabaseProductName(); dbProductName = dbProductName.toLowerCase(); int majorVersion = metaData.getDatabaseMajorVersion(); if (dbProductName.contains("oracle")) { return new OraclePlatform(); } else if (dbProductName.contains("microsoft")) { return new SqlServerPlatform(); } else if (dbProductName.contains("mysql")) { return new MySqlPlatform(); } else if (dbProductName.contains("h2")) { return new H2Platform(); } else if (dbProductName.contains("hsql database engine")) { return new HsqldbPlatform(); } else if (dbProductName.contains("postgres")) { return new PostgresPlatform(); } else if (dbProductName.contains("sqlite")) { return new SQLitePlatform(); } else if (dbProductName.contains("db2")) { return new DB2Platform(); } else if (dbProductName.contains("sql anywhere")) { return new SqlAnywherePlatform(); } // use the standard one return new DatabasePlatform(); } }