001package io.ebean.dbmigration;
002
003import io.ebean.EbeanServer;
004import io.ebean.annotation.Platform;
005import io.ebean.config.ServerConfig;
006import io.ebean.config.dbplatform.DatabasePlatform;
007
008import java.io.IOException;
009import java.util.Iterator;
010import java.util.List;
011import java.util.ServiceLoader;
012
013/**
014 * Generates DDL migration scripts based on changes to the current model.
015 *
016 * <p>
017 * Typically this is run as a main method in src/test once a developer is happy
018 * with the next set of changes to the model.
019 * </p>
020 *
021 * <h3>Example: Run for a single specific platform</h3>
022 *
023 * <pre>{@code
024 *
025 *    // optionally specify the version and name
026 *    //System.setProperty("ddl.migration.version", "1.1");
027 *    //System.setProperty("ddl.migration.name", "add bars");
028 *
029 *    // generate a migration using drops from a prior version
030 *    //System.setProperty("ddl.migration.pendingDropsFor", "1.2");
031 *
032 *    DbMigration migration = DbMigration.create();
033 *
034 *    migration.setPlatform(Platform.POSTGRES);
035 *    migration.generateMigration();
036 *
037 * }</pre>
038 */
039public interface DbMigration {
040
041  /**
042   * Create a DbMigration implementation to use.
043   */
044  static DbMigration create() {
045
046    Iterator<DbMigration> loader = ServiceLoader.load(DbMigration.class).iterator();
047    if (loader.hasNext()) {
048      return loader.next();
049    }
050    throw new IllegalStateException("No service implementation found for DbMigration?");
051  }
052
053  /**
054   * Set to false to suppress logging to System out.
055   */
056  void setLogToSystemOut(boolean logToSystemOut);
057
058  /**
059   * Set the path from the current working directory to the application resources.
060   * <p>
061   * This defaults to maven style 'src/main/resources'.
062   */
063  void setPathToResources(String pathToResources);
064
065  /**
066   * Set the server to use to determine the current model.
067   * Typically this is not called explicitly.
068   */
069  void setServer(EbeanServer ebeanServer);
070
071  /**
072   * Set the serverConfig to use. Typically this is not called explicitly.
073   */
074  void setServerConfig(ServerConfig config);
075
076  /**
077   * Set the specific platform to generate DDL for.
078   * <p>
079   * If not set this defaults to the platform of the default server.
080   * </p>
081   */
082  void setPlatform(Platform platform);
083
084  /**
085   * Set the specific platform to generate DDL for.
086   * <p>
087   * If not set this defaults to the platform of the default server.
088   * </p>
089   */
090  void setPlatform(DatabasePlatform databasePlatform);
091
092  /**
093   * Set to false to turn off strict mode.
094   * <p>
095   * Strict mode checks that a column changed to non-null on an existing table via DB migration has a default
096   * value specified. Set this to false if that isn't the case but it is known that all the existing rows have
097   * a value specified (there are no existing null values for the column).
098   * </p>
099   */
100  void setStrictMode(boolean strictMode);
101
102  /**
103   * Set to true to include a generated header comment in the DDL script.
104   */
105  void setIncludeGeneratedFileComment(boolean includeGeneratedFileComment);
106
107  /**
108   * Set this to false to exclude the builtin support for table partitioning (with @DbPartition).
109   */
110  void setIncludeBuiltInPartitioning(boolean includeBuiltInPartitioning);
111
112  /**
113   * Set the header that is included in the generated DDL script.
114   */
115  void setHeader(String header);
116
117  /**
118   * Set the prefix for the version. Set this to "V" for use with Flyway.
119   */
120  void setApplyPrefix(String applyPrefix);
121
122  /**
123   * Set the version of the migration to be generated.
124   */
125  void setVersion(String version);
126
127  /**
128   * Set the name of the migration to be generated.
129   */
130  void setName(String name);
131
132  /**
133   * Generate a migration for the version specified that contains pending drops.
134   *
135   * @param generatePendingDrop The version of a prior migration that holds pending drops.
136   */
137  void setGeneratePendingDrop(String generatePendingDrop);
138
139  /**
140   * Add an additional platform to write the migration DDL.
141   * <p>
142   * Use this when you want to generate sql scripts for multiple database platforms
143   * from the migration (e.g. generate migration sql for MySql, Postgres and Oracle).
144   * </p>
145   */
146  void addPlatform(Platform platform, String prefix);
147
148  /**
149   * Add an additional databasePlatform to write the migration DDL.
150   * <p>
151   * Use this when you want to add preconfigured database platforms.
152   * </p>
153   */
154  void addDatabasePlatform(DatabasePlatform databasePlatform, String prefix);
155
156  /**
157   * Return the list of versions that contain pending drops.
158   */
159  List<String> getPendingDrops();
160
161  /**
162   * Generate the next migration sql script and associated model xml.
163   * <p>
164   * This does not run the migration or ddl scripts but just generates them.
165   * </p>
166   * <h3>Example: Run for a single specific platform</h3>
167   * <pre>{@code
168   *
169   *   DbMigration migration = DbMigration.create();
170   *   migration.setPlatform(Platform.POSTGRES);
171   *
172   *   migration.generateMigration();
173   *
174   * }</pre>
175   * <p>
176   * <h3>Example: Run migration generating DDL for multiple platforms</h3>
177   * <pre>{@code
178   *
179   *   DbMigration migration = DbMigration.create();
180   *
181   *   migration.setPathToResources("src/main/resources");
182   *
183   *   migration.addPlatform(Platform.POSTGRES, "pg");
184   *   migration.addPlatform(Platform.MYSQL, "mysql");
185   *   migration.addPlatform(Platform.ORACLE, "oracle");
186   *
187   *   migration.generateMigration();
188   *
189   * }</pre>
190   *
191   * @return the version of the generated migration or null
192   */
193  String generateMigration() throws IOException;
194
195  /**
196   * Generate an "init" migration which has all changes.
197   * <p>
198   * An "init" migration can only be executed and used on a database that has had no
199   * prior migrations run on it.
200   * </p>
201   * @return the version of the generated migration
202   */
203  String generateInitMigration() throws IOException;
204
205}