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}