001/*
002 * Copyright 2015-2018 Transmogrify LLC.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.pyranid;
018
019import static java.util.Objects.requireNonNull;
020
021import java.sql.Connection;
022import java.sql.DatabaseMetaData;
023import java.sql.SQLException;
024
025import javax.sql.DataSource;
026
027/**
028 * Identifies different types of databases, which allows for special platform-specific handling.
029 * 
030 * @author <a href="http://revetkn.com">Mark Allen</a>
031 * @since 1.0.0
032 */
033public enum DatabaseType {
034  /**
035   * A database which requires no special handling.
036   */
037  GENERIC,
038  /**
039   * An Oracle database.
040   */
041  ORACLE;
042
043  /**
044   * Determines the type of database to which the given {@code dataSource} connects.
045   * <p>
046   * Note: this will establish a {@link Connection} to the database.
047   * 
048   * @param dataSource
049   *          the database connection factory
050   * @return the type of database
051   * @throws DatabaseException
052   *           if an exception occurs while attempting to read database metadata
053   */
054  public static DatabaseType fromDataSource(DataSource dataSource) {
055    requireNonNull(dataSource);
056
057    DatabaseType databaseType = DatabaseType.GENERIC;
058
059    try {
060      try (Connection connection = dataSource.getConnection()) {
061        DatabaseMetaData databaseMetaData = connection.getMetaData();
062        String databaseProductName = databaseMetaData.getDatabaseProductName();
063        if (databaseProductName != null && databaseProductName.startsWith("Oracle"))
064          databaseType = DatabaseType.ORACLE;
065      }
066    } catch (SQLException e) {
067      throw new DatabaseException("Unable to connect to database to determine its type", e);
068    }
069
070    return databaseType;
071  }
072}