001package io.ebean.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 boolean skipChecksum; 023 024 private Map<String, String> runPlaceholderMap; 025 026 private ClassLoader classLoader; 027 028 private String dbUsername; 029 private String dbPassword; 030 private String dbDriver; 031 private String dbUrl; 032 033 private String dbSchema; 034 private boolean createSchemaIfNotExists; 035 private String platformName; 036 037 /** 038 * Return the name of the migration table. 039 */ 040 public String getMetaTable() { 041 return metaTable; 042 } 043 044 /** 045 * Set the name of the migration table. 046 */ 047 public void setMetaTable(String metaTable) { 048 this.metaTable = metaTable; 049 } 050 051 /** 052 * Return true if checksum check should be skipped (during development). 053 */ 054 public boolean isSkipChecksum() { 055 return skipChecksum; 056 } 057 058 /** 059 * Set to true to skip the checksum check. 060 * <p> 061 * This is intended for use during development only. 062 * </p> 063 */ 064 public void setSkipChecksum(boolean skipChecksum) { 065 this.skipChecksum = skipChecksum; 066 } 067 068 /** 069 * Return a Comma and equals delimited key/value placeholders to replace in DDL scripts. 070 */ 071 public String getRunPlaceholders() { 072 return runPlaceholders; 073 } 074 075 /** 076 * Set a Comma and equals delimited key/value placeholders to replace in DDL scripts. 077 */ 078 public void setRunPlaceholders(String runPlaceholders) { 079 this.runPlaceholders = runPlaceholders; 080 } 081 082 /** 083 * Return a map of name/value pairs that can be expressions replaced in migration scripts. 084 */ 085 public Map<String, String> getRunPlaceholderMap() { 086 return runPlaceholderMap; 087 } 088 089 /** 090 * Set a map of name/value pairs that can be expressions replaced in migration scripts. 091 */ 092 public void setRunPlaceholderMap(Map<String, String> runPlaceholderMap) { 093 this.runPlaceholderMap = runPlaceholderMap; 094 } 095 096 /** 097 * Return the root path used to find migrations. 098 */ 099 public String getMigrationPath() { 100 return migrationPath; 101 } 102 103 /** 104 * Set the root path used to find migrations. 105 */ 106 public void setMigrationPath(String migrationPath) { 107 this.migrationPath = migrationPath; 108 } 109 110 /** 111 * Return the suffix for migration resources (defaults to .sql). 112 */ 113 public String getApplySuffix() { 114 return applySuffix; 115 } 116 117 /** 118 * Set the suffix for migration resources. 119 */ 120 public void setApplySuffix(String applySuffix) { 121 this.applySuffix = applySuffix; 122 } 123 124 /** 125 * Return the DB username. 126 * <p> 127 * Used when a Connection to run the migration is not supplied. 128 * </p> 129 */ 130 public String getDbUsername() { 131 return dbUsername; 132 } 133 134 /** 135 * Set the DB username. 136 * <p> 137 * Used when a Connection to run the migration is not supplied. 138 * </p> 139 */ 140 public void setDbUsername(String dbUsername) { 141 this.dbUsername = dbUsername; 142 } 143 144 /** 145 * Return the DB password. 146 * <p> 147 * Used when creating a Connection to run the migration. 148 * </p> 149 */ 150 public String getDbPassword() { 151 return dbPassword; 152 } 153 154 /** 155 * Set the DB password. 156 * <p> 157 * Used when creating a Connection to run the migration. 158 * </p> 159 */ 160 public void setDbPassword(String dbPassword) { 161 this.dbPassword = dbPassword; 162 } 163 164 /** 165 * Return the DB Driver. 166 * <p> 167 * Used when creating a Connection to run the migration. 168 * </p> 169 */ 170 public String getDbDriver() { 171 return dbDriver; 172 } 173 174 /** 175 * Set the DB Driver. 176 * <p> 177 * Used when creating a Connection to run the migration. 178 * </p> 179 */ 180 public void setDbDriver(String dbDriver) { 181 this.dbDriver = dbDriver; 182 } 183 184 /** 185 * Return the DB connection URL. 186 * <p> 187 * Used when creating a Connection to run the migration. 188 * </p> 189 */ 190 public String getDbUrl() { 191 return dbUrl; 192 } 193 194 /** 195 * Set the DB connection URL. 196 * <p> 197 * Used when creating a Connection to run the migration. 198 * </p> 199 */ 200 public void setDbUrl(String dbUrl) { 201 this.dbUrl = dbUrl; 202 } 203 204 /** 205 * Return the DB connection Schema. 206 * <p> 207 * Used when creating a Connection to run the migration. 208 * </p> 209 */ 210 public String getDbSchema() { 211 return dbSchema; 212 } 213 214 /** 215 * Set the DB connection Schema. 216 * <p> 217 * Used when creating a Connection to run the migration. 218 * </p> 219 */ 220 public void setDbSchema(String dbSchema) { 221 this.dbSchema = dbSchema; 222 } 223 224 /** 225 * Return true if migration should create the schema if it does not exist. 226 */ 227 public boolean isCreateSchemaIfNotExists() { 228 return createSchemaIfNotExists; 229 } 230 231 /** 232 * Set to create Schema if it does not exist. 233 */ 234 public void setCreateSchemaIfNotExists(boolean createSchemaIfNotExists) { 235 this.createSchemaIfNotExists = createSchemaIfNotExists; 236 } 237 238 /** 239 * Return the DB platform name (used for platform create table and select for update syntax). 240 */ 241 public String getPlatformName() { 242 return platformName; 243 } 244 245 /** 246 * Set a DB platform name (to load specific create table and select for update syntax). 247 */ 248 public void setPlatformName(String platformName) { 249 this.platformName = platformName; 250 } 251 252 /** 253 * Return the ClassLoader to use to load resources. 254 */ 255 public ClassLoader getClassLoader() { 256 if (classLoader == null) { 257 classLoader = Thread.currentThread().getContextClassLoader(); 258 if (classLoader == null) { 259 classLoader = this.getClass().getClassLoader(); 260 } 261 } 262 return classLoader; 263 } 264 265 /** 266 * Set the ClassLoader to use when loading resources. 267 */ 268 public void setClassLoader(ClassLoader classLoader) { 269 this.classLoader = classLoader; 270 } 271 272 /** 273 * Load configuration from standard properties. 274 */ 275 public void load(Properties props) { 276 277 dbUsername = props.getProperty("dbmigration.username", dbUsername); 278 dbPassword = props.getProperty("dbmigration.password", dbPassword); 279 dbDriver = props.getProperty("dbmigration.driver", dbDriver); 280 dbUrl = props.getProperty("dbmigration.url", dbUrl); 281 282 String skip = props.getProperty("dbmigration.skipchecksum"); 283 if (skip != null) { 284 skipChecksum = Boolean.parseBoolean(skip); 285 } 286 platformName = props.getProperty("dbmigration.platformName", platformName); 287 applySuffix = props.getProperty("dbmigration.applySuffix", applySuffix); 288 metaTable = props.getProperty("dbmigration.metaTable", metaTable); 289 migrationPath = props.getProperty("dbmigration.migrationPath", migrationPath); 290 runPlaceholders = props.getProperty("dbmigration.placeholders", runPlaceholders); 291 } 292 293 /** 294 * Create a Connection to the database using the configured driver, url, username etc. 295 * <p> 296 * Used when an existing DataSource or Connection is not supplied. 297 * </p> 298 */ 299 public Connection createConnection() { 300 301 if (dbUsername == null) throw new MigrationException("Database username is null?"); 302 if (dbPassword == null) throw new MigrationException("Database password is null?"); 303 if (dbDriver == null) throw new MigrationException("Database Driver is null?"); 304 if (dbUrl == null) throw new MigrationException("Database connection URL is null?"); 305 306 loadDriver(); 307 308 try { 309 Properties props = new Properties(); 310 props.setProperty("user", dbUsername); 311 props.setProperty("password", dbPassword); 312 return DriverManager.getConnection(dbUrl, props); 313 314 } catch (SQLException e) { 315 throw new MigrationException("Error trying to create Connection", e); 316 } 317 } 318 319 private void loadDriver() { 320 try { 321 ClassLoader contextLoader = getClassLoader(); 322 Class.forName(dbDriver, true, contextLoader); 323 } catch (Throwable e) { 324 throw new MigrationException("Problem loading Database Driver [" + dbDriver + "]: " + e.getMessage(), e); 325 } 326 } 327 328}