001package org.avaje.dbmigration; 002 003import java.sql.Connection; 004import java.sql.DriverManager; 005import java.sql.SQLException; 006import java.util.Map; 007import java.util.Properties; 008 009/** 010 * Configuration used to run the migration. 011 */ 012public class MigrationConfig { 013 014 private String migrationPath = "dbmigration"; 015 016 private String metaTable = "db_migration"; 017 018 private String applySuffix = ".sql"; 019 020 private String runPlaceholders; 021 022 private Map<String, String> runPlaceholderMap; 023 024 private ClassLoader classLoader; 025 026 private String dbUsername; 027 private String dbPassword; 028 private String dbDriver; 029 private String dbUrl; 030 031 /** 032 * Return the name of the migration table. 033 */ 034 public String getMetaTable() { 035 return metaTable; 036 } 037 038 /** 039 * Set the name of the migration table. 040 */ 041 public void setMetaTable(String metaTable) { 042 this.metaTable = metaTable; 043 } 044 045 /** 046 * Return a Comma and equals delimited key/value placeholders to replace in DDL scripts. 047 */ 048 public String getRunPlaceholders() { 049 return runPlaceholders; 050 } 051 052 /** 053 * Set a Comma and equals delimited key/value placeholders to replace in DDL scripts. 054 */ 055 public void setRunPlaceholders(String runPlaceholders) { 056 this.runPlaceholders = runPlaceholders; 057 } 058 059 /** 060 * Return a map of name/value pairs that can be expressions replaced in migration scripts. 061 */ 062 public Map<String, String> getRunPlaceholderMap() { 063 return runPlaceholderMap; 064 } 065 066 /** 067 * Set a map of name/value pairs that can be expressions replaced in migration scripts. 068 */ 069 public void setRunPlaceholderMap(Map<String, String> runPlaceholderMap) { 070 this.runPlaceholderMap = runPlaceholderMap; 071 } 072 073 /** 074 * Return the root path used to find migrations. 075 */ 076 public String getMigrationPath() { 077 return migrationPath; 078 } 079 080 /** 081 * Set the root path used to find migrations. 082 */ 083 public void setMigrationPath(String migrationPath) { 084 this.migrationPath = migrationPath; 085 } 086 087 /** 088 * Return the suffix for migration resources (defaults to .sql). 089 */ 090 public String getApplySuffix() { 091 return applySuffix; 092 } 093 094 /** 095 * Set the suffix for migration resources. 096 */ 097 public void setApplySuffix(String applySuffix) { 098 this.applySuffix = applySuffix; 099 } 100 101 /** 102 * Return the DB username. 103 * <p> 104 * Used when a Connection to run the migration is not supplied. 105 * </p> 106 */ 107 public String getDbUsername() { 108 return dbUsername; 109 } 110 111 /** 112 * Set the DB username. 113 * <p> 114 * Used when a Connection to run the migration is not supplied. 115 * </p> 116 */ 117 public void setDbUsername(String dbUsername) { 118 this.dbUsername = dbUsername; 119 } 120 121 /** 122 * Return the DB password. 123 * <p> 124 * Used when creating a Connection to run the migration. 125 * </p> 126 */ 127 public String getDbPassword() { 128 return dbPassword; 129 } 130 131 /** 132 * Set the DB password. 133 * <p> 134 * Used when creating a Connection to run the migration. 135 * </p> 136 */ 137 public void setDbPassword(String dbPassword) { 138 this.dbPassword = dbPassword; 139 } 140 141 /** 142 * Return the DB Driver. 143 * <p> 144 * Used when creating a Connection to run the migration. 145 * </p> 146 */ 147 public String getDbDriver() { 148 return dbDriver; 149 } 150 151 /** 152 * Set the DB Driver. 153 * <p> 154 * Used when creating a Connection to run the migration. 155 * </p> 156 */ 157 public void setDbDriver(String dbDriver) { 158 this.dbDriver = dbDriver; 159 } 160 161 /** 162 * Return the DB connection URL. 163 * <p> 164 * Used when creating a Connection to run the migration. 165 * </p> 166 */ 167 public String getDbUrl() { 168 return dbUrl; 169 } 170 171 /** 172 * Set the DB connection URL. 173 * <p> 174 * Used when creating a Connection to run the migration. 175 * </p> 176 */ 177 public void setDbUrl(String dbUrl) { 178 this.dbUrl = dbUrl; 179 } 180 181 /** 182 * Return the ClassLoader to use to load resources. 183 */ 184 public ClassLoader getClassLoader() { 185 if (classLoader == null) { 186 classLoader = Thread.currentThread().getContextClassLoader(); 187 if (classLoader == null) { 188 classLoader = this.getClass().getClassLoader(); 189 } 190 } 191 return classLoader; 192 } 193 194 /** 195 * Set the ClassLoader to use when loading resources. 196 */ 197 public void setClassLoader(ClassLoader classLoader) { 198 this.classLoader = classLoader; 199 } 200 201 /** 202 * Load configuration from standard properties. 203 */ 204 public void load(Properties props) { 205 206 dbUsername = props.getProperty("dbmigration.username", dbUsername); 207 dbPassword = props.getProperty("dbmigration.password", dbPassword); 208 dbDriver = props.getProperty("dbmigration.driver", dbDriver); 209 dbUrl = props.getProperty("dbmigration.url", dbUrl); 210 211 applySuffix = props.getProperty("dbmigration.applySuffix", applySuffix); 212 metaTable = props.getProperty("dbmigration.metaTable", metaTable); 213 migrationPath = props.getProperty("dbmigration.migrationPath", migrationPath); 214 runPlaceholders = props.getProperty("dbmigration.placeholders", runPlaceholders); 215 } 216 217 /** 218 * Create a Connection to the database using the configured driver, url, username etc. 219 * <p> 220 * Used when an existing DataSource or Connection is not supplied. 221 * </p> 222 */ 223 public Connection createConnection() { 224 225 if (dbUsername == null) throw new MigrationException("Database username is null?"); 226 if (dbPassword == null) throw new MigrationException("Database password is null?"); 227 if (dbDriver == null) throw new MigrationException("Database Driver is null?"); 228 if (dbUrl == null) throw new MigrationException("Database connection URL is null?"); 229 230 loadDriver(); 231 232 try { 233 Properties props = new Properties(); 234 props.setProperty("user", dbUsername); 235 props.setProperty("password", dbPassword); 236 return DriverManager.getConnection(dbUrl, props); 237 238 } catch (SQLException e) { 239 throw new MigrationException("Error trying to create Connection", e); 240 } 241 } 242 243 private void loadDriver() { 244 try { 245 ClassLoader contextLoader = getClassLoader(); 246 Class.forName(dbDriver, true, contextLoader); 247 } catch (Throwable e) { 248 throw new MigrationException("Problem loading Database Driver [" + dbDriver + "]: " + e.getMessage(), e); 249 } 250 } 251 252}