001/* 002 * Copyright 2006-2007 the original author or authors. 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 * https://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 org.springframework.batch.support; 018 019import org.springframework.jdbc.support.JdbcUtils; 020import org.springframework.jdbc.support.MetaDataAccessException; 021import org.springframework.util.StringUtils; 022 023import javax.sql.DataSource; 024import java.util.HashMap; 025import java.util.Map; 026 027 028/** 029 * Enum representing a database type, such as DB2 or oracle. The type also 030 * contains a product name, which is expected to be the same as the product name 031 * provided by the database driver's metadata. 032 * 033 * @author Lucas Ward 034 * @since 2.0 035 */ 036public enum DatabaseType { 037 038 DERBY("Apache Derby"), 039 DB2("DB2"), 040 DB2VSE("DB2VSE"), 041 DB2ZOS("DB2ZOS"), 042 DB2AS400("DB2AS400"), 043 HSQL("HSQL Database Engine"), 044 SQLSERVER("Microsoft SQL Server"), 045 MYSQL("MySQL"), 046 ORACLE("Oracle"), 047 POSTGRES("PostgreSQL"), 048 SYBASE("Sybase"), 049 H2("H2"), 050 SQLITE("SQLite"); 051 052 private static final Map<String, DatabaseType> nameMap; 053 054 static{ 055 nameMap = new HashMap<String, DatabaseType>(); 056 for(DatabaseType type: values()){ 057 nameMap.put(type.getProductName(), type); 058 } 059 } 060 //A description is necessary due to the nature of database descriptions 061 //in metadata. 062 private final String productName; 063 064 private DatabaseType(String productName) { 065 this.productName = productName; 066 } 067 068 public String getProductName() { 069 return productName; 070 } 071 072 /** 073 * Static method to obtain a DatabaseType from the provided product name. 074 * 075 * @param productName {@link String} containing the product name. 076 * @return the {@link DatabaseType} for given product name. 077 * 078 * @throws IllegalArgumentException if none is found. 079 */ 080 public static DatabaseType fromProductName(String productName){ 081 if(productName.equals("MariaDB")) 082 productName = "MySQL"; 083 if(!nameMap.containsKey(productName)){ 084 throw new IllegalArgumentException("DatabaseType not found for product name: [" + 085 productName + "]"); 086 } 087 else{ 088 return nameMap.get(productName); 089 } 090 } 091 092 /** 093 * Convenience method that pulls a database product name from the DataSource's metadata. 094 * 095 * @param dataSource {@link DataSource} to the database to be used. 096 * @return {@link DatabaseType} for the {@link DataSource} specified. 097 * 098 * @throws MetaDataAccessException thrown if error occured during Metadata lookup. 099 */ 100 public static DatabaseType fromMetaData(DataSource dataSource) throws MetaDataAccessException { 101 String databaseProductName = 102 JdbcUtils.extractDatabaseMetaData(dataSource, "getDatabaseProductName").toString(); 103 if (StringUtils.hasText(databaseProductName) && databaseProductName.startsWith("DB2")) { 104 String databaseProductVersion = 105 JdbcUtils.extractDatabaseMetaData(dataSource, "getDatabaseProductVersion").toString(); 106 if (databaseProductVersion.startsWith("ARI")) { 107 databaseProductName = "DB2VSE"; 108 } 109 else if (databaseProductVersion.startsWith("DSN")) { 110 databaseProductName = "DB2ZOS"; 111 } 112 else if (databaseProductName.indexOf("AS") != -1 && (databaseProductVersion.startsWith("QSQ") || 113 databaseProductVersion.substring(databaseProductVersion.indexOf('V')).matches("V\\dR\\d[mM]\\d"))) { 114 databaseProductName = "DB2AS400"; 115 } 116 else { 117 databaseProductName = JdbcUtils.commonDatabaseName(databaseProductName); 118 } 119 } 120 else { 121 databaseProductName = JdbcUtils.commonDatabaseName(databaseProductName); 122 } 123 return fromProductName(databaseProductName); 124 } 125}