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}