1 /*
2  * Copyright 2010-2020 Redgate Software Ltd
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *         http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.flywaydb.core.api.configuration;
17
18 import org.flywaydb.core.api.ErrorCode;
19 import org.flywaydb.core.api.FlywayException;
20 import org.flywaydb.core.api.Location;
21 import org.flywaydb.core.api.MigrationVersion;
22 import org.flywaydb.core.api.callback.Callback;
23 import org.flywaydb.core.api.logging.Log;
24 import org.flywaydb.core.api.logging.LogFactory;
25 import org.flywaydb.core.api.migration.JavaMigration;
26 import org.flywaydb.core.api.resolver.MigrationResolver;
27 import org.flywaydb.core.internal.configuration.ConfigUtils;
28 import org.flywaydb.core.internal.jdbc.DriverDataSource;
29 import org.flywaydb.core.internal.license.Edition;
30 import org.flywaydb.core.internal.util.ClassUtils;
31 import org.flywaydb.core.internal.util.Locations;
32 import org.flywaydb.core.internal.util.StringUtils;
33
34 import javax.sql.DataSource;
35 import java.io.File;
36 import java.io.FileNotFoundException;
37 import java.io.FileOutputStream;
38 import java.io.IOException;
39 import java.io.OutputStream;
40 import java.nio.charset.Charset;
41 import java.nio.charset.StandardCharsets;
42 import java.util.ArrayList;
43 import java.util.Arrays;
44 import java.util.HashMap;
45 import java.util.Iterator;
46 import java.util.List;
47 import java.util.Map;
48 import java.util.Properties;
49
50 import static org.flywaydb.core.internal.configuration.ConfigUtils.removeBoolean;
51 import static org.flywaydb.core.internal.configuration.ConfigUtils.removeInteger;
52
53 /**
54  * JavaBean-style configuration for Flyway. This is primarily meant for compatibility with scenarios where the
55  * new FluentConfiguration isn't an easy fit, such as Spring XML bean configuration.
56  * <p>
57  * This configuration can then be passed to Flyway using the <code>new Flyway(Configuration)</code> constructor.
58  * </p>
59  */

60 public class ClassicConfiguration implements Configuration {
61     private static final Log LOG = LogFactory.getLog(ClassicConfiguration.class);
62
63     private String driver;
64     private String url;
65     private String user;
66     private String password;
67
68     /**
69      * The dataSource to use to access the database. Must have the necessary privileges to execute ddl.
70      */

71     private DataSource dataSource;
72
73     /**
74      * The maximum number of retries when attempting to connect to the database. After each failed attempt, Flyway will
75      * wait 1 second before attempting to connect again, up to the maximum number of times specified by connectRetries.
76      * (default: 0)
77      */

78     private int connectRetries;
79
80     /**
81      * The SQL statements to run to initialize a new database connection immediately after opening it.
82      * (default: {@code null})
83      */

84     private String initSql;
85
86     /**
87      * The ClassLoader to use for resolving migrations on the classpath. (default: Thread.currentThread().getContextClassLoader() )
88      */

89     private ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
90
91     /**
92      * The locations to scan recursively for migrations.
93      * <p>The location type is determined by its prefix.
94      * Unprefixed locations or locations starting with {@code classpath:} point to a package on the classpath and may
95      * contain both sql and java-based migrations.
96      * Locations starting with {@code filesystem:} point to a directory on the filesystem and may only contain sql
97      * migrations.</p>
98      * <p>
99      * (default: db/migration)
100      */

101     private Locations locations = new Locations("db/migration");
102
103     /**
104      * The encoding of Sql migrations. (default: UTF-8)
105      */

106     private Charset encoding = StandardCharsets.UTF_8;
107
108     /**
109      * The default schema managed by Flyway. This schema name is case-sensitive. If not specified, but
110      * <i>schemaNames</i> is, Flyway uses the first schema in that list. If that is also not specified, Flyway uses
111      * the default schema for the database connection.
112      * <p>Consequences:</p>
113      * <ul>
114      * <li>This schema will be the one containing the schema history table.</li>
115      * <li>This schema will be the default for the database connection (provided the database supports this concept).</li>
116      * </ul>
117      */

118     private String defaultSchemaName = null;
119
120     /**
121      * The schemas managed by Flyway. These schema names are case-sensitive. If not specified, Flyway uses
122      * the default schema for the database connection. If <i>defaultSchemaName</i> is not specified, then the first of
123      * this list also acts as default schema.
124      * <p>Consequences:</p>
125      * <ul>
126      * <li>Flyway will automatically attempt to create all these schemas, unless they already exist.</li>
127      * <li>The schemas will be cleaned in the order of this list.</li>
128      * <li>If Flyway created them, the schemas themselves will be dropped when cleaning.</li>
129      * </ul>
130      */

131     private String[] schemaNames = {};
132
133     /**
134      * <p>The name of the schema history table that will be used by Flyway. (default: flyway_schema_history)</p><p> By default
135      * (single-schema mode) the schema history table is placed in the default schema for the connection provided by the
136      * datasource. </p> <p>When the <i>flyway.schemas</i> property is set (multi-schema mode), the schema history table is
137      * placed in the first schema of the list. </p>
138      */

139     private String table = "flyway_schema_history";
140
141     /**
142      * <p>The tablespace where to create the schema history table that will be used by Flyway.</p>
143      * <p>If not specified, Flyway uses the default tablespace for the database connection.
144      * This setting is only relevant for databases that do support the notion of tablespaces. Its value is simply
145      * ignored for all others.</p>
146      */

147     private String tablespace;
148
149     /**
150      * The target version up to which Flyway should consider migrations.
151      * Migrations with a higher version number will be ignored. 
152      * Special values:
153      * <ul>
154      * <li>{@code current}: designates the current version of the schema</li>
155      * <li>{@code latest}: the latest version of the schema, as defined by the migration with the highest version</li>
156      * </ul>
157      * Defaults to {@code latest}.
158      */

159     private MigrationVersion target;
160
161     /**
162      * Whether placeholders should be replaced. (defaulttrue)
163      */

164     private boolean placeholderReplacement = true;
165
166     /**
167      * The map of &lt;placeholder, replacementValue&gt; to apply to sql migration scripts.
168      */

169     private Map<String, String> placeholders = new HashMap<>();
170
171     /**
172      * The prefix of every placeholder. (default: ${ )
173      */

174     private String placeholderPrefix = "${";
175
176     /**
177      * The suffix of every placeholder. (default: } )
178      */

179     private String placeholderSuffix = "}";
180
181     /**
182      * The file name prefix for versioned SQL migrations. (default: V)
183      * <p>
184      * <p>Versioned SQL migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
185      * which using the defaults translates to V1_1__My_description.sql</p>
186      */

187     private String sqlMigrationPrefix = "V";
188
189
190
191
192
193
194
195
196
197
198
199
200     /**
201      * The file name prefix for repeatable SQL migrations. (default: R)
202      * <p>
203      * <p>Repeatable sql migrations have the following file name structure: prefixSeparatorDESCRIPTIONsuffix ,
204      * which using the defaults translates to R__My_description.sql</p>
205      */

206     private String repeatableSqlMigrationPrefix = "R";
207
208     /**
209      * The file name separator for sql migrations. (default: __)
210      * <p>
211      * <p>Sql migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
212      * which using the defaults translates to V1_1__My_description.sql</p>
213      */

214     private String sqlMigrationSeparator = "__";
215
216     /**
217      * The file name suffixes for SQL migrations. (default: .sql)
218      * <p>SQL migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
219      * which using the defaults translates to V1_1__My_description.sql</p>
220      * <p>Multiple suffixes (like .sql,.pkg,.pkb) can be specified for easier compatibility with other tools such as
221      * editors with specific file associations.</p>
222      */

223     private String[] sqlMigrationSuffixes = {".sql"};
224
225     /**
226      * The manually added Java-based migrations. These are not Java-based migrations discovered through classpath
227      * scanning and instantiated by Flyway. Instead these are manually added instances of JavaMigration.
228      * This is particularly useful when working with a dependency injection container, where you may want the DI
229      * container to instantiate the class and wire up its dependencies for you. (default: none)
230      */

231     private JavaMigration[] javaMigrations = {};
232
233     /**
234      * Ignore missing migrations when reading the schema history table. These are migrations that were performed by an
235      * older deployment of the application that are no longer available in this version. For example: we have migrations
236      * available on the classpath with versions 1.0 and 3.0. The schema history table indicates that a migration with version 2.0
237      * (unknown to us) has also been applied. Instead of bombing out (fail fast) with an exception, a
238      * warning is logged and Flyway continues normally. This is useful for situations where one must be able to deploy
239      * a newer version of the application even though it doesn't contain migrations included with an older one anymore.
240      * Note that if the most recently applied migration is removed, Flyway has no way to know it is missing and will
241      * mark it as future instead.
242      * <p>
243      * {@code true} to continue normally and log a warning, {@code false} to fail fast with an exception.
244      * (default: {@code false})
245      */

246     private boolean ignoreMissingMigrations;
247
248     /**
249      * Ignore ignored migrations when reading the schema history table. These are migrations that were added in between
250      * already migrated migrations in this version. For example: we have migrations available on the classpath with
251      * versions from 1.0 to 3.0. The schema history table indicates that version 1 was finished on 1.0.15, and the next
252      * one was 2.0.0. But with the next release a new migration was added to version 1: 1.0.16. Such scenario is ignored
253      * by migrate command, but by default is rejected by validate. When ignoreIgnoredMigrations is enabled, such case
254      * will not be reported by validate command. This is useful for situations where one must be able to deliver
255      * complete set of migrations in a delivery package for multiple versions of the product, and allows for further
256      * development of older versions.
257      * <p>
258      * {@code true} to continue normally, {@code false} to fail fast with an exception.
259      * (default: {@code false})
260      */

261     private boolean ignoreIgnoredMigrations;
262
263     /**
264      * Ignore pending migrations when reading the schema history table. These are migrations that are available on the
265      * classpath but have not yet been performed by an application deployment.
266      * This can be useful for verifying that in-development migration changes don't contain any validation-breaking changes
267      * of migrations that have already been applied to a production environment, e.g. as part of a CI/CD process, without
268      * failing because of the existence of new migration versions.
269      * <p>
270      * {@code true} to continue normally, {@code false} to fail fast with an exception.
271      * (default: {@code false})
272      */

273     private boolean ignorePendingMigrations;
274
275     /**
276      * Ignore future migrations when reading the schema history table. These are migrations that were performed by a
277      * newer deployment of the application that are not yet available in this version. For example: we have migrations
278      * available on the classpath up to version 3.0. The schema history table indicates that a migration to version 4.0
279      * (unknown to us) has already been applied. Instead of bombing out (fail fast) with an exception, a
280      * warning is logged and Flyway continues normally. This is useful for situations where one must be able to redeploy
281      * an older version of the application after the database has been migrated by a newer one. (default: {@code true})
282      */

283     private boolean ignoreFutureMigrations = true;
284
285     /**
286      * Whether to validate migrations and callbacks whose scripts do not obey the correct naming convention. A failure can be
287      * useful to check that errors such as case sensitivity in migration prefixes have been corrected.
288      * {@code false} to continue normally, {@code true} to fail fast with an exception. (default: {@code false})
289      */

290     private boolean validateMigrationNaming = false;
291
292     /**
293      * Whether to automatically call validate or not when running migrate. (default: {@code true})
294      */

295     private boolean validateOnMigrate = true;
296
297     /**
298      * Whether to automatically call clean or not when a validation error occurs. (default: {@code false})
299      * <p> This is exclusively intended as a convenience for development. even though we
300      * strongly recommend not to change migration scripts once they have been checked into SCM and run, this provides a
301      * way of dealing with this case in a smooth manner. The database will be wiped clean automatically, ensuring that
302      * the next migration will bring you back to the state checked into SCM.</p>
303      * <p><b>Warning ! Do not enable in production !</b></p>
304      */

305     private boolean cleanOnValidationError;
306
307     /**
308      * Whether to disable clean. (default: {@code false})
309      * <p>This is especially useful for production environments where running clean can be quite a career limiting move.</p>
310      */

311     private boolean cleanDisabled;
312
313     /**
314      * The version to tag an existing schema with when executing baseline. (default: 1)
315      */

316     private MigrationVersion baselineVersion = MigrationVersion.fromVersion("1");
317
318     /**
319      * The description to tag an existing schema with when executing baseline. (default: &lt;&lt; Flyway Baseline &gt;&gt;)
320      */

321     private String baselineDescription = "<< Flyway Baseline >>";
322
323     /**
324      * <p>
325      * Whether to automatically call baseline when migrate is executed against a non-empty schema with no schema history table.
326      * This schema will then be initialized with the {@code baselineVersion} before executing the migrations.
327      * Only migrations above {@code baselineVersion} will then be applied.
328      * </p>
329      * <p>
330      * This is useful for initial Flyway production deployments on projects with an existing DB.
331      * </p>
332      * <p>
333      * Be careful when enabling this as it removes the safety net that ensures
334      * Flyway does not migrate the wrong database in case of a configuration mistake! (default: {@code false})
335      * </p>
336      */

337     private boolean baselineOnMigrate;
338
339     /**
340      * Allows migrations to be run "out of order".
341      * <p>If you already have versions 1 and 3 applied, and now a version 2 is found,
342      * it will be applied too instead of being ignored.</p>
343      * <p>(default: {@code false})</p>
344      */

345     private boolean outOfOrder;
346
347     /**
348      * This is a list of custom callbacks that fire before and after tasks are executed.  You can
349      * add as many custom callbacks as you want. (default: none)
350      */

351     private final List<Callback> callbacks = new ArrayList<>();
352
353     /**
354      * Whether Flyway should skip the default callbacks. If true, only custom callbacks are used.
355      * <p>(defaultfalse)</p>
356      */

357     private boolean skipDefaultCallbacks;
358
359     /**
360      * The custom MigrationResolvers to be used in addition to the built-in ones for resolving Migrations to apply.
361      * <p>(default: none)</p>
362      */

363     private MigrationResolver[] resolvers = new MigrationResolver[0];
364
365     /**
366      * Whether Flyway should skip the default resolvers. If true, only custom resolvers are used.
367      * <p>(defaultfalse)</p>
368      */

369     private boolean skipDefaultResolvers;
370
371     /**
372      * Whether to allow mixing transactional and non-transactional statements within the same migration.
373      * <p>
374      * {@code trueif mixed migrations should be allowed. {@code falseif an error should be thrown instead. (default: {@code false})
375      */

376     private boolean mixed;
377
378     /**
379      * Whether to group all pending migrations together in the same transaction when applying them (only recommended for databases with support for DDL transactions).
380      * <p>
381      * {@code trueif migrations should be grouped. {@code falseif they should be applied individually instead. (default: {@code false})
382      */

383     private boolean group;
384
385     /**
386      * The username that will be recorded in the schema history table as having applied the migration.
387      * <p>
388      * {@code nullfor the current database user of the connection. (default: {@code null}).
389      */

390     private String installedBy;
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467     /**
468      * Creates a new default configuration.
469      */

470     public ClassicConfiguration() {
471         // Nothing to do.
472     }
473
474     /**
475      * Creates a new default configuration with this classloader.
476      *
477      * @param classLoader The ClassLoader to use for loading migrations, resolvers, etc from the classpath. (default: Thread.currentThread().getContextClassLoader() )
478      */

479     public ClassicConfiguration(ClassLoader classLoader) {
480         if (classLoader != null) {
481             this.classLoader = classLoader;
482         }
483     }
484
485     /**
486      * Creates a new configuration with the same values as this existing one.
487      *
488      * @param configuration The configuration to use.
489      */

490     public ClassicConfiguration(Configuration configuration) {
491         this(configuration.getClassLoader());
492         configure(configuration);
493     }
494
495     @Override
496     public Location[] getLocations() {
497         return locations.getLocations().toArray(new Location[0]);
498     }
499
500     @Override
501     public Charset getEncoding() {
502         return encoding;
503     }
504
505     @Override
506     public String getDefaultSchema() { return defaultSchemaName; }
507
508     @Override
509     public String[] getSchemas() { return schemaNames; }
510
511     @Override
512     public String getTable() {
513         return table;
514     }
515
516     @Override
517     public String getTablespace() {
518         return tablespace;
519     }
520
521     @Override
522     public MigrationVersion getTarget() {
523         return target;
524     }
525
526     @Override
527     public boolean isPlaceholderReplacement() {
528         return placeholderReplacement;
529     }
530
531     @Override
532     public Map<String, String> getPlaceholders() {
533         return placeholders;
534     }
535
536     @Override
537     public String getPlaceholderPrefix() {
538         return placeholderPrefix;
539     }
540
541     @Override
542     public String getPlaceholderSuffix() {
543         return placeholderSuffix;
544     }
545
546     @Override
547     public String getSqlMigrationPrefix() {
548         return sqlMigrationPrefix;
549     }
550
551     @Override
552     public String getRepeatableSqlMigrationPrefix() {
553         return repeatableSqlMigrationPrefix;
554     }
555
556     @Override
557     public String getSqlMigrationSeparator() {
558         return sqlMigrationSeparator;
559     }
560
561     @Override
562     public String[] getSqlMigrationSuffixes() {
563         return sqlMigrationSuffixes;
564     }
565
566     @Override
567     public JavaMigration[] getJavaMigrations() {
568         return javaMigrations;
569     }
570
571     @Override
572     public boolean isIgnoreMissingMigrations() {
573         return ignoreMissingMigrations;
574     }
575
576     @Override
577     public boolean isIgnoreIgnoredMigrations() {
578         return ignoreIgnoredMigrations;
579     }
580
581     @Override
582     public boolean isIgnorePendingMigrations() {
583         return ignorePendingMigrations;
584     }
585
586     @Override
587     public boolean isIgnoreFutureMigrations() {
588         return ignoreFutureMigrations;
589     }
590
591     @Override
592     public boolean isValidateMigrationNaming() {
593         return validateMigrationNaming;
594     }
595
596     @Override
597     public boolean isValidateOnMigrate() {
598         return validateOnMigrate;
599     }
600
601     @Override
602     public boolean isCleanOnValidationError() {
603         return cleanOnValidationError;
604     }
605
606     @Override
607     public boolean isCleanDisabled() {
608         return cleanDisabled;
609     }
610
611     @Override
612     public MigrationVersion getBaselineVersion() {
613         return baselineVersion;
614     }
615
616     @Override
617     public String getBaselineDescription() {
618         return baselineDescription;
619     }
620
621     @Override
622     public boolean isBaselineOnMigrate() {
623         return baselineOnMigrate;
624     }
625
626     @Override
627     public boolean isOutOfOrder() {
628         return outOfOrder;
629     }
630
631     @Override
632     public MigrationResolver[] getResolvers() {
633         return resolvers;
634     }
635
636     @Override
637     public boolean isSkipDefaultResolvers() {
638         return skipDefaultResolvers;
639     }
640
641     @Override
642     public DataSource getDataSource() {
643         if (dataSource == null &&
644                 (StringUtils.hasLength(driver) || StringUtils.hasLength(user) || StringUtils.hasLength(password))) {
645             LOG.warn("Discarding INCOMPLETE dataSource configuration! " + ConfigUtils.URL + " must be set.");
646         }
647         return dataSource;
648     }
649
650     @Override
651     public int getConnectRetries() {
652         return connectRetries;
653     }
654
655     @Override
656     public String getInitSql() {
657         return initSql;
658     }
659
660     @Override
661     public ClassLoader getClassLoader() {
662         return classLoader;
663     }
664
665     @Override
666     public boolean isMixed() {
667         return mixed;
668     }
669
670     @Override
671     public String getInstalledBy() {
672         return installedBy;
673     }
674
675     @Override
676     public boolean isGroup() {
677         return group;
678     }
679
680     @Override
681     public String[] getErrorOverrides() {
682
683         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("errorOverrides");
684
685
686
687
688     }
689
690     @Override
691     public OutputStream getDryRunOutput() {
692
693         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("dryRunOutput");
694
695
696
697
698     }
699
700     @Override
701     public String getLicenseKey() {
702
703         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("licenseKey");
704
705
706
707
708     }
709
710     /**
711      * Whether Flyway should output a table with the results of queries when executing migrations.
712      *
713      * <p><i>Flyway Pro and Flyway Enterprise only</i></p>
714      *
715      * @return {@code true} to output the results table (default: {@code true})
716      */

717     @Override
718     public boolean outputQueryResults() {
719
720         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("outputQueryResults");
721
722
723
724
725     }
726
727     /**
728      * Sets the stream where to output the SQL statements of a migration dry run. {@code null} to execute the SQL statements
729      * directly against the database. The stream when be closing when Flyway finishes writing the output.
730      * <p><i>Flyway Pro and Flyway Enterprise only</i></p>
731      *
732      * @param dryRunOutput The output file or {@code null} to execute the SQL statements directly against the database.
733      */

734     public void setDryRunOutput(OutputStream dryRunOutput) {
735
736         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("dryRunOutput");
737
738
739
740
741     }
742
743     /**
744      * Sets the file where to output the SQL statements of a migration dry run. {@code null} to execute the SQL statements
745      * directly against the database. If the file specified is in a non-existent directory, Flyway will create all
746      * directories and parent directories as needed.
747      * <p><i>Flyway Pro and Flyway Enterprise only</i></p>
748      *
749      * @param dryRunOutput The output file or {@code null} to execute the SQL statements directly against the database.
750      */

751     public void setDryRunOutputAsFile(File dryRunOutput) {
752
753         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("dryRunOutput");
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797     }
798
799     /**
800      * Sets the file where to output the SQL statements of a migration dry run. {@code null} to execute the SQL statements
801      * directly against the database. If the file specified is in a non-existent directory, Flyway will create all
802      * directories and parent directories as needed.
803      * <p><i>Flyway Pro and Flyway Enterprise only</i></p>
804      *
805      * @param dryRunOutputFileName The name of the output file or {@code null} to execute the SQL statements directly
806      *                             against the database.
807      */

808     public void setDryRunOutputAsFileName(String dryRunOutputFileName) {
809
810         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("dryRunOutput");
811
812
813
814
815     }
816
817     /**
818      * Rules for the built-in error handler that let you override specific SQL states and errors codes in order to force
819      * specific errors or warnings to be treated as debug messages, info messages, warnings or errors.
820      * <p>Each error override has the following format: {@code STATE:12345:W}.
821      * It is a 5 character SQL state (or * to match all SQL states), a colon,
822      * the SQL error code (or * to match all SQL error codes), a colon and finally
823      * the desired behavior that should override the initial one.</p>
824      * <p>The following behaviors are accepted:</p>
825      * <ul>
826      * <li>{@code D} to force a debug message</li>
827      * <li>{@code D-} to force a debug message, but do not show the original sql state and error code</li>
828      * <li>{@code I} to force an info message</li>
829      * <li>{@code I-} to force an info message, but do not show the original sql state and error code</li>
830      * <li>{@code W} to force a warning</li>
831      * <li>{@code W-} to force a warning, but do not show the original sql state and error code</li>
832      * <li>{@code E} to force an error</li>
833      * <li>{@code E-} to force an error, but do not show the original sql state and error code</li>
834      * </ul>
835      * <p>Example 1: to force Oracle stored procedure compilation issues to produce
836      * errors instead of warnings, the following errorOverride can be used: {@code 99999:17110:E}</p>
837      * <p>Example 2: to force SQL Server PRINT messages to be displayed as info messages (without SQL state and error
838      * code details) instead of warnings, the following errorOverride can be used: {@code S0001:0:I-}</p>
839      * <p>Example 3: to force all errors with SQL error code 123 to be treated as warnings instead,
840      * the following errorOverride can be used: {@code *:123:W}</p>
841      * <p><i>Flyway Pro and Flyway Enterprise only</i></p>
842      *
843      * @param errorOverrides The ErrorOverrides or an empty array if none are defined. (default: none)
844      */

845     public void setErrorOverrides(String... errorOverrides) {
846
847         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("errorOverrides");
848
849
850
851
852     }
853
854     /**
855      * Whether to group all pending migrations together in the same transaction when applying them (only recommended for databases with support for DDL transactions).
856      *
857      * @param group {@code trueif migrations should be grouped. {@code falseif they should be applied individually instead. (default: {@code false})
858      */

859     public void setGroup(boolean group) {
860         this.group = group;
861     }
862
863     /**
864      * The username that will be recorded in the schema history table as having applied the migration.
865      *
866      * @param installedBy The username or {@code nullfor the current database user of the connection. (default: {@code null}).
867      */

868     public void setInstalledBy(String installedBy) {
869         if ("".equals(installedBy)) {
870             installedBy = null;
871         }
872         this.installedBy = installedBy;
873     }
874
875     /**
876      * Whether to allow mixing transactional and non-transactional statements within the same migration. Enabling this
877      * automatically causes the entire affected migration to be run without a transaction.
878      *
879      * <p>Note that this is only applicable for PostgreSQL, Aurora PostgreSQL, SQL Server and SQLite which all have
880      * statements that do not run at all within a transaction.</p>
881      * <p>This is not to be confused with implicit transaction, as they occur in MySQL or Oracle, where even though a
882      * DDL statement was run within a transaction, the database will issue an implicit commit before and after
883      * its execution.</p>
884      *
885      * @param mixed {@code trueif mixed migrations should be allowed. {@code falseif an error should be thrown instead. (default: {@code false})
886      */

887     public void setMixed(boolean mixed) {
888         this.mixed = mixed;
889     }
890
891     /**
892      * Ignore missing migrations when reading the schema history table. These are migrations that were performed by an
893      * older deployment of the application that are no longer available in this version. For example: we have migrations
894      * available on the classpath with versions 1.0 and 3.0. The schema history table indicates that a migration with version 2.0
895      * (unknown to us) has also been applied. Instead of bombing out (fail fast) with an exception, a
896      * warning is logged and Flyway continues normally. This is useful for situations where one must be able to deploy
897      * a newer version of the application even though it doesn't contain migrations included with an older one anymore.
898      * Note that if the most recently applied migration is removed, Flyway has no way to know it is missing and will
899      * mark it as future instead.
900      *
901      * @param ignoreMissingMigrations {@code true} to continue normally and log a warning, {@code false} to fail fast with an exception.
902      *                                (default: {@code false})
903      */

904     public void setIgnoreMissingMigrations(boolean ignoreMissingMigrations) {
905         this.ignoreMissingMigrations = ignoreMissingMigrations;
906     }
907
908     /**
909      * Ignore ignored migrations when reading the schema history table. These are migrations that were added in between
910      * already migrated migrations in this version. For example: we have migrations available on the classpath with
911      * versions from 1.0 to 3.0. The schema history table indicates that version 1 was finished on 1.0.15, and the next
912      * one was 2.0.0. But with the next release a new migration was added to version 1: 1.0.16. Such scenario is ignored
913      * by migrate command, but by default is rejected by validate. When ignoreIgnoredMigrations is enabled, such case
914      * will not be reported by validate command. This is useful for situations where one must be able to deliver
915      * complete set of migrations in a delivery package for multiple versions of the product, and allows for further
916      * development of older versions.
917      *
918      * @param ignoreIgnoredMigrations {@code true} to continue normally, {@code false} to fail fast with an exception.
919      *                                (default: {@code false})
920      */

921     public void setIgnoreIgnoredMigrations(boolean ignoreIgnoredMigrations) {
922         this.ignoreIgnoredMigrations = ignoreIgnoredMigrations;
923     }
924
925     /**
926      * Ignore pending migrations when reading the schema history table. These are migrations that are available
927      * but have not yet been applied. This can be useful for verifying that in-development migration changes
928      * don't contain any validation-breaking changes of migrations that have already been applied to a production
929      * environment, e.g. as part of a CI/CD process, without failing because of the existence of new migration versions.
930      *
931      * @param ignorePendingMigrations {@code true} to continue normally, {@code false} to fail fast with an exception.
932      *                                (default: {@code false})
933      */

934     public void setIgnorePendingMigrations(boolean ignorePendingMigrations) {
935         this.ignorePendingMigrations = ignorePendingMigrations;
936     }
937
938     /**
939      * Whether to ignore future migrations when reading the schema history table. These are migrations that were performed by a
940      * newer deployment of the application that are not yet available in this version. For example: we have migrations
941      * available on the classpath up to version 3.0. The schema history table indicates that a migration to version 4.0
942      * (unknown to us) has already been applied. Instead of bombing out (fail fast) with an exception, a
943      * warning is logged and Flyway continues normally. This is useful for situations where one must be able to redeploy
944      * an older version of the application after the database has been migrated by a newer one.
945      *
946      * @param ignoreFutureMigrations {@code true} to continue normally and log a warning, {@code false} to fail
947      *                               fast with an exception. (default: {@code true})
948      */

949     public void setIgnoreFutureMigrations(boolean ignoreFutureMigrations) {
950         this.ignoreFutureMigrations = ignoreFutureMigrations;
951     }
952
953     /**
954      * Whether to validate migrations and callbacks whose scripts do not obey the correct naming convention. A failure can be
955      * useful to check that errors such as case sensitivity in migration prefixes have been corrected.
956      *
957      * @param validateMigrationNaming {@code false} to continue normally, {@code true} to fail
958      *                                                fast with an exception. (default: {@code false})
959      */

960     public void setValidateMigrationNaming(boolean validateMigrationNaming) {
961         this.validateMigrationNaming = validateMigrationNaming;
962     }
963
964     /**
965      * Whether to automatically call validate or not when running migrate.
966      *
967      * @param validateOnMigrate {@code trueif validate should be called. {@code falseif not. (default: {@code true})
968      */

969     public void setValidateOnMigrate(boolean validateOnMigrate) {
970         this.validateOnMigrate = validateOnMigrate;
971     }
972
973     /**
974      * Whether to automatically call clean or not when a validation error occurs.
975      * <p> This is exclusively intended as a convenience for development. even though we
976      * strongly recommend not to change migration scripts once they have been checked into SCM and run, this provides a
977      * way of dealing with this case in a smooth manner. The database will be wiped clean automatically, ensuring that
978      * the next migration will bring you back to the state checked into SCM.</p>
979      * <p><b>Warning ! Do not enable in production !</b></p>
980      *
981      * @param cleanOnValidationError {@code trueif clean should be called. {@code falseif not. (default: {@code false})
982      */

983     public void setCleanOnValidationError(boolean cleanOnValidationError) {
984         this.cleanOnValidationError = cleanOnValidationError;
985     }
986
987     /**
988      * Whether to disable clean.
989      * <p>This is especially useful for production environments where running clean can be quite a career limiting move.</p>
990      *
991      * @param cleanDisabled {@code true} to disable clean. {@code false} to leave it enabled.  (default: {@code false})
992      */

993     public void setCleanDisabled(boolean cleanDisabled) {
994         this.cleanDisabled = cleanDisabled;
995     }
996
997     /**
998      * Sets the locations to scan recursively for migrations.
999      * <p>The location type is determined by its prefix.
1000      * Unprefixed locations or locations starting with {@code classpath:} point to a package on the classpath and may
1001      * contain both SQL and Java-based migrations.
1002      * Locations starting with {@code filesystem:} point to a directory on the filesystem, may only
1003      * contain SQL migrations and are only scanned recursively down non-hidden directories.</p>
1004      *
1005      * @param locations Locations to scan recursively for migrations. (default: db/migration)
1006      */

1007     public void setLocationsAsStrings(String... locations) {
1008         this.locations = new Locations(locations);
1009     }
1010
1011     /**
1012      * Sets the locations to scan recursively for migrations.
1013      * <p>The location type is determined by its prefix.
1014      * Unprefixed locations or locations starting with {@code classpath:} point to a package on the classpath and may
1015      * contain both SQL and Java-based migrations.
1016      * Locations starting with {@code filesystem:} point to a directory on the filesystem, may only
1017      * contain SQL migrations and are only scanned recursively down non-hidden directories.</p>
1018      *
1019      * @param locations Locations to scan recursively for migrations. (default: db/migration)
1020      */

1021     public void setLocations(Location... locations) {
1022         this.locations = new Locations(Arrays.asList(locations));
1023     }
1024
1025     /**
1026      * Sets the encoding of Sql migrations.
1027      *
1028      * @param encoding The encoding of Sql migrations. (default: UTF-8)
1029      */

1030     public void setEncoding(Charset encoding) {
1031         this.encoding = encoding;
1032     }
1033
1034     /**
1035      * Sets the encoding of Sql migrations.
1036      *
1037      * @param encoding The encoding of Sql migrations. (default: UTF-8)
1038      */

1039     public void setEncodingAsString(String encoding) {
1040         this.encoding = Charset.forName(encoding);
1041     }
1042
1043     /**
1044      * Sets the default schema managed by Flyway. This schema name is case-sensitive. If not specified, but
1045      * <i>Schemas</i> is, Flyway uses the first schema in that list. If that is also not specified, Flyway uses the default
1046      * schema for the database connection.
1047      * <p>Consequences:</p>
1048      * <ul>
1049      * <li>This schema will be the one containing the schema history table.</li>
1050      * <li>This schema will be the default for the database connection (provided the database supports this concept).</li>
1051      * </ul>
1052      *
1053      * @param schema The default schema managed by Flyway.
1054      */

1055     public void setDefaultSchema(String schema) {
1056         this.defaultSchemaName = schema;
1057     }
1058
1059     /**
1060      * Sets the schemas managed by Flyway. These schema names are case-sensitive. If not specified, Flyway uses
1061      * the default schema for the database connection. If <i>defaultSchema</i> is not specified, then the first of
1062      * this list also acts as default schema.
1063      * <p>Consequences:</p>
1064      * <ul>
1065      * <li>Flyway will automatically attempt to create all these schemas, unless they already exist.</li>
1066      * <li>The schemas will be cleaned in the order of this list.</li>
1067      * <li>If Flyway created them, the schemas themselves will be dropped when cleaning.</li>
1068      * </ul>
1069      *
1070      * @param schemas The schemas managed by Flyway. May not be {@code null}. Must contain at least one element.
1071      */

1072     public void setSchemas(String... schemas) {
1073         this.schemaNames = schemas;
1074     }
1075
1076     /**
1077      * <p>Sets the name of the schema history table that will be used by Flyway. </p><p> By default (single-schema mode)
1078      * the schema history table is placed in the default schema for the connection provided by the datasource. </p> <p> When
1079      * the <i>flyway.schemas</i> property is set (multi-schema mode), the schema history table is placed in the first schema
1080      * of the list. </p>
1081      *
1082      * @param table The name of the schema history table that will be used by Flyway. (default: flyway_schema_history)
1083      */

1084     public void setTable(String table) {
1085         this.table = table;
1086     }
1087
1088     /**
1089      * <p>Sets the tablespace where to create the schema history table that will be used by Flyway.</p>
1090      * <p>If not specified, Flyway uses the default tablespace for the database connection.This setting is only relevant
1091      * for databases that do support the notion of tablespaces. Its value is simply
1092      * ignored for all others.</p>
1093      *
1094      * @param tablespace The tablespace where to create the schema history table that will be used by Flyway.
1095      */

1096     public void setTablespace(String tablespace) {
1097         this.tablespace = tablespace;
1098     }
1099
1100     /**
1101      * Sets the target version up to which Flyway should consider migrations.
1102      * Migrations with a higher version number will be ignored. 
1103      * Special values:
1104      * <ul>
1105      * <li>{@code current}: designates the current version of the schema</li>
1106      * <li>{@code latest}: the latest version of the schema, as defined by the migration with the highest version</li>
1107      * </ul>
1108      * Defaults to {@code latest}.
1109      */

1110     public void setTarget(MigrationVersion target) {
1111         this.target = target;
1112     }
1113
1114     /**
1115      * Sets the target version up to which Flyway should consider migrations.
1116      * Migrations with a higher version number will be ignored. 
1117      * Special values:
1118      * <ul>
1119      * <li>{@code current}: designates the current version of the schema</li>
1120      * <li>{@code latest}: the latest version of the schema, as defined by the migration with the highest version</li>
1121      * </ul>
1122      * Defaults to {@code latest}.
1123      */

1124     public void setTargetAsString(String target) {
1125         this.target = MigrationVersion.fromVersion(target);
1126     }
1127
1128     /**
1129      * Sets whether placeholders should be replaced.
1130      *
1131      * @param placeholderReplacement Whether placeholders should be replaced. (defaulttrue)
1132      */

1133     public void setPlaceholderReplacement(boolean placeholderReplacement) {
1134         this.placeholderReplacement = placeholderReplacement;
1135     }
1136
1137     /**
1138      * Sets the placeholders to replace in sql migration scripts.
1139      *
1140      * @param placeholders The map of &lt;placeholder, replacementValue&gt; to apply to sql migration scripts.
1141      */

1142     public void setPlaceholders(Map<String, String> placeholders) {
1143         this.placeholders = placeholders;
1144     }
1145
1146     /**
1147      * Sets the prefix of every placeholder.
1148      *
1149      * @param placeholderPrefix The prefix of every placeholder. (default: ${ )
1150      */

1151     public void setPlaceholderPrefix(String placeholderPrefix) {
1152         if (!StringUtils.hasLength(placeholderPrefix)) {
1153             throw new FlywayException("placeholderPrefix cannot be empty!", ErrorCode.CONFIGURATION);
1154         }
1155         this.placeholderPrefix = placeholderPrefix;
1156     }
1157
1158     /**
1159      * Sets the suffix of every placeholder.
1160      *
1161      * @param placeholderSuffix The suffix of every placeholder. (default: } )
1162      */

1163     public void setPlaceholderSuffix(String placeholderSuffix) {
1164         if (!StringUtils.hasLength(placeholderSuffix)) {
1165             throw new FlywayException("placeholderSuffix cannot be empty!", ErrorCode.CONFIGURATION);
1166         }
1167         this.placeholderSuffix = placeholderSuffix;
1168     }
1169
1170     /**
1171      * Sets the file name prefix for sql migrations.
1172      * <p>Sql migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
1173      * which using the defaults translates to V1_1__My_description.sql</p>
1174      *
1175      * @param sqlMigrationPrefix The file name prefix for sql migrations (default: V)
1176      */

1177     public void setSqlMigrationPrefix(String sqlMigrationPrefix) {
1178         this.sqlMigrationPrefix = sqlMigrationPrefix;
1179     }
1180
1181     @Override
1182     public String getUndoSqlMigrationPrefix() {
1183
1184         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("undoSqlMigrationPrefix");
1185
1186
1187
1188
1189     }
1190
1191     /**
1192      * Sets the file name prefix for undo SQL migrations. (default: U)
1193      * <p>Undo SQL migrations are responsible for undoing the effects of the versioned migration with the same version.</p>
1194      * <p>They have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
1195      * which using the defaults translates to U1.1__My_description.sql</p>
1196      * <p><i>Flyway Pro and Flyway Enterprise only</i></p>
1197      *
1198      * @param undoSqlMigrationPrefix The file name prefix for undo SQL migrations. (default: U)
1199      */

1200     public void setUndoSqlMigrationPrefix(String undoSqlMigrationPrefix) {
1201
1202         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("undoSqlMigrationPrefix");
1203
1204
1205
1206
1207     }
1208
1209     /**
1210      * The manually added Java-based migrations. These are not Java-based migrations discovered through classpath
1211      * scanning and instantiated by Flyway. Instead these are manually added instances of JavaMigration.
1212      * This is particularly useful when working with a dependency injection container, where you may want the DI
1213      * container to instantiate the class and wire up its dependencies for you.
1214      *
1215      * @param javaMigrations The manually added Java-based migrations. An empty array if none. (default: none)
1216      */

1217     public void setJavaMigrations(JavaMigration... javaMigrations) {
1218         if (javaMigrations == null) {
1219             throw new FlywayException("javaMigrations cannot be null", ErrorCode.CONFIGURATION);
1220         }
1221         this.javaMigrations = javaMigrations;
1222     }
1223
1224     @Override
1225     public boolean isStream() {
1226
1227         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("stream");
1228
1229
1230
1231
1232     }
1233
1234     /**
1235      * Whether to stream SQL migrations when executing them. Streaming doesn't load the entire migration in memory at
1236      * once. Instead each statement is loaded individually. This is particularly useful for very large SQL migrations
1237      * composed of multiple MB or even GB of reference data, as this dramatically reduces Flyway's memory consumption.
1238      * <p><i>Flyway Pro and Flyway Enterprise only</i></p>
1239      *
1240      * @param stream {@code true} to stream SQL migrations. {@code false} to fully loaded them in memory instead. (default: {@code false})
1241      */

1242     public void setStream(boolean stream) {
1243
1244         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("stream");
1245
1246
1247
1248
1249     }
1250
1251     @Override
1252     public boolean isBatch() {
1253
1254         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("batch");
1255
1256
1257
1258
1259     }
1260
1261     /**
1262      * Whether to batch SQL statements when executing them. Batching can save up to 99 percent of network roundtrips by
1263      * sending up to 100 statements at once over the network to the database, instead of sending each statement
1264      * individually. This is particularly useful for very large SQL migrations composed of multiple MB or even GB of
1265      * reference data, as this can dramatically reduce the network overhead. This is supported for INSERT, UPDATE,
1266      * DELETE, MERGE and UPSERT statements. All other statements are automatically executed without batching.
1267      * <p><i>Flyway Pro and Flyway Enterprise only</i></p>
1268      *
1269      * @param batch {@code true} to batch SQL statements. {@code false} to execute them individually instead. (default: {@code false})
1270      */

1271     public void setBatch(boolean batch) {
1272
1273         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("batch");
1274
1275
1276
1277
1278     }
1279
1280     /**
1281      * Sets the file name prefix for repeatable sql migrations.
1282      * <p>Repeatable sql migrations have the following file name structure: prefixSeparatorDESCRIPTIONsuffix ,
1283      * which using the defaults translates to R__My_description.sql</p>
1284      *
1285      * @param repeatableSqlMigrationPrefix The file name prefix for repeatable sql migrations (default: R)
1286      */

1287     public void setRepeatableSqlMigrationPrefix(String repeatableSqlMigrationPrefix) {
1288         this.repeatableSqlMigrationPrefix = repeatableSqlMigrationPrefix;
1289     }
1290
1291     /**
1292      * Sets the file name separator for sql migrations.
1293      * <p>Sql migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
1294      * which using the defaults translates to V1_1__My_description.sql</p>
1295      *
1296      * @param sqlMigrationSeparator The file name separator for sql migrations (default: __)
1297      */

1298     public void setSqlMigrationSeparator(String sqlMigrationSeparator) {
1299         if (!StringUtils.hasLength(sqlMigrationSeparator)) {
1300             throw new FlywayException("sqlMigrationSeparator cannot be empty!", ErrorCode.CONFIGURATION);
1301         }
1302
1303         this.sqlMigrationSeparator = sqlMigrationSeparator;
1304     }
1305
1306     /**
1307      * The file name suffixes for SQL migrations. (default: .sql)
1308      * <p>SQL migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
1309      * which using the defaults translates to V1_1__My_description.sql</p>
1310      * <p>Multiple suffixes (like .sql,.pkg,.pkb) can be specified for easier compatibility with other tools such as
1311      * editors with specific file associations.</p>
1312      *
1313      * @param sqlMigrationSuffixes The file name suffixes for SQL migrations.
1314      */

1315     public void setSqlMigrationSuffixes(String... sqlMigrationSuffixes) {
1316         this.sqlMigrationSuffixes = sqlMigrationSuffixes;
1317     }
1318
1319     /**
1320      * Sets the datasource to use. Must have the necessary privileges to execute ddl.
1321      *
1322      * @param dataSource The datasource to use. Must have the necessary privileges to execute ddl.
1323      */

1324     public void setDataSource(DataSource dataSource) {
1325         driver = null;
1326         url = null;
1327         user = null;
1328         password = null;
1329         this.dataSource = dataSource;
1330     }
1331
1332     /**
1333      * Sets the datasource to use. Must have the necessary privileges to execute ddl.
1334      * <p>To use a custom ClassLoader, setClassLoader() must be called prior to calling this method.</p>
1335      *
1336      * @param url      The JDBC URL of the database.
1337      * @param user     The user of the database.
1338      * @param password The password of the database.
1339      */

1340     public void setDataSource(String url, String user, String password) {
1341         this.dataSource = new DriverDataSource(classLoader, null, url, user, password);
1342     }
1343
1344     /**
1345      * The maximum number of retries when attempting to connect to the database. After each failed attempt, Flyway will
1346      * wait 1 second before attempting to connect again, up to the maximum number of times specified by connectRetries.
1347      *
1348      * @param connectRetries The maximum number of retries (default: 0).
1349      */

1350     public void setConnectRetries(int connectRetries) {
1351         if (connectRetries < 0) {
1352             throw new FlywayException("Invalid number of connectRetries (must be 0 or greater): " + connectRetries, ErrorCode.CONFIGURATION);
1353         }
1354         this.connectRetries = connectRetries;
1355     }
1356
1357     /**
1358      * The SQL statements to run to initialize a new database connection immediately after opening it.
1359      *
1360      * @param initSql The SQL statements. (default: {@code null})
1361      */

1362     public void setInitSql(String initSql) {
1363         this.initSql = initSql;
1364     }
1365
1366     /**
1367      * Sets the version to tag an existing schema with when executing baseline.
1368      *
1369      * @param baselineVersion The version to tag an existing schema with when executing baseline. (default: 1)
1370      */

1371     public void setBaselineVersion(MigrationVersion baselineVersion) {
1372         this.baselineVersion = baselineVersion;
1373     }
1374
1375     /**
1376      * Sets the version to tag an existing schema with when executing baseline.
1377      *
1378      * @param baselineVersion The version to tag an existing schema with when executing baseline. (default: 1)
1379      */

1380     public void setBaselineVersionAsString(String baselineVersion) {
1381         this.baselineVersion = MigrationVersion.fromVersion(baselineVersion);
1382     }
1383
1384     /**
1385      * Sets the description to tag an existing schema with when executing baseline.
1386      *
1387      * @param baselineDescription The description to tag an existing schema with when executing baseline. (default: &lt;&lt; Flyway Baseline &gt;&gt;)
1388      */

1389     public void setBaselineDescription(String baselineDescription) {
1390         this.baselineDescription = baselineDescription;
1391     }
1392
1393     /**
1394      * <p>
1395      * Whether to automatically call baseline when migrate is executed against a non-empty schema with no schema history table.
1396      * This schema will then be baselined with the {@code baselineVersion} before executing the migrations.
1397      * Only migrations above {@code baselineVersion} will then be applied.
1398      * </p>
1399      * <p>
1400      * This is useful for initial Flyway production deployments on projects with an existing DB.
1401      * </p>
1402      * <p>
1403      * Be careful when enabling this as it removes the safety net that ensures
1404      * Flyway does not migrate the wrong database in case of a configuration mistake!
1405      * </p>
1406      *
1407      * @param baselineOnMigrate {@code trueif baseline should be called on migrate for non-empty schemas, {@code falseif not. (default: {@code false})
1408      */

1409     public void setBaselineOnMigrate(boolean baselineOnMigrate) {
1410         this.baselineOnMigrate = baselineOnMigrate;
1411     }
1412
1413     /**
1414      * Allows migrations to be run "out of order".
1415      * <p>If you already have versions 1 and 3 applied, and now a version 2 is found,
1416      * it will be applied too instead of being ignored.</p>
1417      *
1418      * @param outOfOrder {@code trueif outOfOrder migrations should be applied, {@code falseif not. (default: {@code false})
1419      */

1420     public void setOutOfOrder(boolean outOfOrder) {
1421         this.outOfOrder = outOfOrder;
1422     }
1423
1424     /**
1425      * Gets the callbacks for lifecycle notifications.
1426      *
1427      * @return The callbacks for lifecycle notifications. An empty array if none. (default: none)
1428      */

1429     @Override
1430     public Callback[] getCallbacks() {
1431         return callbacks.toArray(new Callback[0]);
1432     }
1433
1434     @Override
1435     public boolean isSkipDefaultCallbacks() {
1436         return skipDefaultCallbacks;
1437     }
1438
1439     /**
1440      * Set the callbacks for lifecycle notifications.
1441      *
1442      * @param callbacks The callbacks for lifecycle notifications. (default: none)
1443      */

1444     public void setCallbacks(Callback... callbacks) {
1445         this.callbacks.clear();
1446         this.callbacks.addAll(Arrays.asList(callbacks));
1447     }
1448
1449     /**
1450      * Set the callbacks for lifecycle notifications.
1451      *
1452      * @param callbacks The fully qualified class names of the callbacks for lifecycle notifications. (default: none)
1453      */

1454     public void setCallbacksAsClassNames(String... callbacks) {
1455         this.callbacks.clear();
1456         for (String callback : callbacks) {
1457             Object o = ClassUtils.instantiate(callback, classLoader);
1458             if (o instanceof Callback) {
1459                 this.callbacks.add((Callback) o);
1460             } else {
1461                 throw new FlywayException("Invalid callback: " + callback + " (must implement org.flywaydb.core.api.callback.Callback)", ErrorCode.CONFIGURATION);
1462             }
1463         }
1464     }
1465
1466     /**
1467      * Whether Flyway should skip the default callbacks. If true, only custom callbacks are used.
1468      *
1469      * @param skipDefaultCallbacks Whether default built-in callbacks should be skipped. <p>(defaultfalse)</p>
1470      */

1471     public void setSkipDefaultCallbacks(boolean skipDefaultCallbacks) {
1472         this.skipDefaultCallbacks = skipDefaultCallbacks;
1473     }
1474
1475     /**
1476      * Sets custom MigrationResolvers to be used in addition to the built-in ones for resolving Migrations to apply.
1477      *
1478      * @param resolvers The custom MigrationResolvers to be used in addition to the built-in ones for resolving Migrations to apply. (default: empty list)
1479      */

1480     public void setResolvers(MigrationResolver... resolvers) {
1481         this.resolvers = resolvers;
1482     }
1483
1484     /**
1485      * Sets custom MigrationResolvers to be used in addition to the built-in ones for resolving Migrations to apply.
1486      *
1487      * @param resolvers The fully qualified class names of the custom MigrationResolvers to be used in addition to the built-in ones for resolving Migrations to apply. (default: empty list)
1488      */

1489     public void setResolversAsClassNames(String... resolvers) {
1490         List<MigrationResolver> resolverList = ClassUtils.instantiateAll(resolvers, classLoader);
1491         setResolvers(resolverList.toArray(new MigrationResolver[resolvers.length]));
1492     }
1493
1494     /**
1495      * Whether Flyway should skip the default resolvers. If true, only custom resolvers are used.
1496      *
1497      * @param skipDefaultResolvers Whether default built-in resolvers should be skipped. <p>(defaultfalse)</p>
1498      */

1499     public void setSkipDefaultResolvers(boolean skipDefaultResolvers) {
1500         this.skipDefaultResolvers = skipDefaultResolvers;
1501     }
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520     @Override
1521     public boolean isOracleSqlplus() {
1522
1523         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("oracle.sqlplus");
1524
1525
1526
1527
1528     }
1529
1530     /**
1531      * Whether to Flyway's support for Oracle SQL*Plus commands should be activated.
1532      * <p><i>Flyway Pro and Flyway Enterprise only</i></p>
1533      *
1534      * @param oracleSqlplus {@code true} to active SQL*Plus support. {@code false} to fail fast instead. (default: {@code false})
1535      */

1536     public void setOracleSqlplus(boolean oracleSqlplus) {
1537
1538         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("oracle.sqlplus");
1539
1540
1541
1542
1543     }
1544
1545     @Override
1546     public boolean isOracleSqlplusWarn() {
1547
1548         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("oracle.sqlplusWarn");
1549
1550
1551
1552
1553     }
1554
1555     /**
1556      * Whether Flyway should issue a warning instead of an error whenever it encounters an Oracle SQL*Plus statement
1557      * it doesn't yet support.
1558      *
1559      * <p><i>Flyway Pro and Flyway Enterprise only</i></p>
1560      *
1561      * @param oracleSqlplusWarn  {@code true} to issue a warning. {@code false} to fail fast instead. (default: {@code false})
1562      */

1563     public void setOracleSqlplusWarn(boolean oracleSqlplusWarn) {
1564
1565         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("oracle.sqlplusWarn");
1566
1567
1568
1569
1570     }
1571
1572     /**
1573      * Your Flyway license key (FL01...). Not yet a Flyway Pro or Enterprise Edition customer?
1574      * Request your <a href="https://flywaydb.org/download/">Flyway trial license key</a>
1575      * to try out Flyway Pro and Enterprise Edition features free for 30 days.
1576      *
1577      * <p><i>Flyway Pro and Flyway Enterprise only</i></p>
1578      *
1579      * @param licenseKey Your Flyway license key.
1580      */

1581     public void setLicenseKey(String licenseKey) {
1582
1583           LOG.warn(Edition.PRO + " or " + Edition.ENTERPRISE + " upgrade required: " + licenseKey
1584             + " is not supported by " + Edition.COMMUNITY + ".");
1585
1586
1587
1588
1589     }
1590
1591     /**
1592      * Configure with the same values as this existing configuration.
1593      *
1594      * @param configuration The configuration to use.
1595      */

1596     public void configure(Configuration configuration) {
1597         setBaselineDescription(configuration.getBaselineDescription());
1598         setBaselineOnMigrate(configuration.isBaselineOnMigrate());
1599         setBaselineVersion(configuration.getBaselineVersion());
1600         setCallbacks(configuration.getCallbacks());
1601         setCleanDisabled(configuration.isCleanDisabled());
1602         setCleanOnValidationError(configuration.isCleanOnValidationError());
1603         setDataSource(configuration.getDataSource());
1604         setConnectRetries(configuration.getConnectRetries());
1605         setInitSql(configuration.getInitSql());
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617         setEncoding(configuration.getEncoding());
1618         setGroup(configuration.isGroup());
1619         setValidateMigrationNaming(configuration.isValidateMigrationNaming());
1620         setIgnoreFutureMigrations(configuration.isIgnoreFutureMigrations());
1621         setIgnoreMissingMigrations(configuration.isIgnoreMissingMigrations());
1622         setIgnoreIgnoredMigrations(configuration.isIgnoreIgnoredMigrations());
1623         setIgnorePendingMigrations(configuration.isIgnorePendingMigrations());
1624         setInstalledBy(configuration.getInstalledBy());
1625         setJavaMigrations(configuration.getJavaMigrations());
1626         setLocations(configuration.getLocations());
1627         setMixed(configuration.isMixed());
1628         setOutOfOrder(configuration.isOutOfOrder());
1629         setPlaceholderPrefix(configuration.getPlaceholderPrefix());
1630         setPlaceholderReplacement(configuration.isPlaceholderReplacement());
1631         setPlaceholders(configuration.getPlaceholders());
1632         setPlaceholderSuffix(configuration.getPlaceholderSuffix());
1633         setRepeatableSqlMigrationPrefix(configuration.getRepeatableSqlMigrationPrefix());
1634         setResolvers(configuration.getResolvers());
1635         setDefaultSchema(configuration.getDefaultSchema());
1636         setSchemas(configuration.getSchemas());
1637         setSkipDefaultCallbacks(configuration.isSkipDefaultCallbacks());
1638         setSkipDefaultResolvers(configuration.isSkipDefaultResolvers());
1639         setSqlMigrationPrefix(configuration.getSqlMigrationPrefix());
1640         setSqlMigrationSeparator(configuration.getSqlMigrationSeparator());
1641         setSqlMigrationSuffixes(configuration.getSqlMigrationSuffixes());
1642         setTable(configuration.getTable());
1643         setTablespace(configuration.getTablespace());
1644         setTarget(configuration.getTarget());
1645         setValidateOnMigrate(configuration.isValidateOnMigrate());
1646     }
1647
1648     /**
1649      * Whether Flyway should output a table with the results of queries when executing migrations.
1650      *
1651      * <p><i>Flyway Pro and Flyway Enterprise only</i></p>
1652      *
1653      * @return {@code true} to output the results table (default: {@code true})
1654      */

1655     private void setOutputQueryResults(boolean outputQueryResults) {
1656
1657         throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("outputQueryResults");
1658
1659
1660
1661
1662     }
1663
1664     /**
1665      * Configures Flyway with these properties. This overwrites any existing configuration. Property names are
1666      * documented in the flyway maven plugin.
1667      * <p>To use a custom ClassLoader, setClassLoader() must be called prior to calling this method.</p>
1668      *
1669      * @param properties Properties used for configuration.
1670      * @throws FlywayException when the configuration failed.
1671      */

1672     public void configure(Properties properties) {
1673         configure(ConfigUtils.propertiesToMap(properties));
1674     }
1675
1676     /**
1677      * Configures Flyway with these properties. This overwrites any existing configuration. Property names are
1678      * documented in the flyway maven plugin.
1679      * <p>To use a custom ClassLoader, it must be passed to the Flyway constructor prior to calling this method.</p>
1680      *
1681      * @param props Properties used for configuration.
1682      * @throws FlywayException when the configuration failed.
1683      */

1684     public void configure(Map<String, String> props) {
1685         // Make copy to prevent removing elements from the original.
1686         props = new HashMap<>(props);
1687
1688         String driverProp = props.remove(ConfigUtils.DRIVER);
1689         if (driverProp != null) {
1690             dataSource = null;
1691             driver = driverProp;
1692         }
1693         String urlProp = props.remove(ConfigUtils.URL);
1694         if (urlProp != null) {
1695             dataSource = null;
1696             url = urlProp;
1697         }
1698         String userProp = props.remove(ConfigUtils.USER);
1699         if (userProp != null) {
1700             dataSource = null;
1701             user = userProp;
1702         }
1703         String passwordProp = props.remove(ConfigUtils.PASSWORD);
1704         if (passwordProp != null) {
1705             dataSource = null;
1706             password = passwordProp;
1707         }
1708         if (StringUtils.hasText(url) && (StringUtils.hasText(urlProp) ||
1709                 StringUtils.hasText(driverProp) || StringUtils.hasText(userProp) || StringUtils.hasText(passwordProp))) {
1710             setDataSource(new DriverDataSource(classLoader, driver, url, user, password));
1711         }
1712         Integer connectRetriesProp = removeInteger(props, ConfigUtils.CONNECT_RETRIES);
1713         if (connectRetriesProp != null) {
1714             setConnectRetries(connectRetriesProp);
1715         }
1716         String initSqlProp = props.remove(ConfigUtils.INIT_SQL);
1717         if (initSqlProp != null) {
1718             setInitSql(initSqlProp);
1719         }
1720         String locationsProp = props.remove(ConfigUtils.LOCATIONS);
1721         if (locationsProp != null) {
1722             setLocationsAsStrings(StringUtils.tokenizeToStringArray(locationsProp, ","));
1723         }
1724         Boolean placeholderReplacementProp = removeBoolean(props, ConfigUtils.PLACEHOLDER_REPLACEMENT);
1725         if (placeholderReplacementProp != null) {
1726             setPlaceholderReplacement(placeholderReplacementProp);
1727         }
1728         String placeholderPrefixProp = props.remove(ConfigUtils.PLACEHOLDER_PREFIX);
1729         if (placeholderPrefixProp != null) {
1730             setPlaceholderPrefix(placeholderPrefixProp);
1731         }
1732         String placeholderSuffixProp = props.remove(ConfigUtils.PLACEHOLDER_SUFFIX);
1733         if (placeholderSuffixProp != null) {
1734             setPlaceholderSuffix(placeholderSuffixProp);
1735         }
1736         String sqlMigrationPrefixProp = props.remove(ConfigUtils.SQL_MIGRATION_PREFIX);
1737         if (sqlMigrationPrefixProp != null) {
1738             setSqlMigrationPrefix(sqlMigrationPrefixProp);
1739         }
1740         String undoSqlMigrationPrefixProp = props.remove(ConfigUtils.UNDO_SQL_MIGRATION_PREFIX);
1741         if (undoSqlMigrationPrefixProp != null) {
1742             setUndoSqlMigrationPrefix(undoSqlMigrationPrefixProp);
1743         }
1744         String repeatableSqlMigrationPrefixProp = props.remove(ConfigUtils.REPEATABLE_SQL_MIGRATION_PREFIX);
1745         if (repeatableSqlMigrationPrefixProp != null) {
1746             setRepeatableSqlMigrationPrefix(repeatableSqlMigrationPrefixProp);
1747         }
1748         String sqlMigrationSeparatorProp = props.remove(ConfigUtils.SQL_MIGRATION_SEPARATOR);
1749         if (sqlMigrationSeparatorProp != null) {
1750             setSqlMigrationSeparator(sqlMigrationSeparatorProp);
1751         }
1752         String sqlMigrationSuffixesProp = props.remove(ConfigUtils.SQL_MIGRATION_SUFFIXES);
1753         if (sqlMigrationSuffixesProp != null) {
1754             setSqlMigrationSuffixes(StringUtils.tokenizeToStringArray(sqlMigrationSuffixesProp, ","));
1755         }
1756         String encodingProp = props.remove(ConfigUtils.ENCODING);
1757         if (encodingProp != null) {
1758             setEncodingAsString(encodingProp);
1759         }
1760         String defaultSchemaProp = props.remove(ConfigUtils.DEFAULT_SCHEMA);
1761         if (defaultSchemaProp != null) {
1762             setDefaultSchema(defaultSchemaProp);
1763         }
1764         String schemasProp = props.remove(ConfigUtils.SCHEMAS);
1765         if (schemasProp != null) {
1766             setSchemas(StringUtils.tokenizeToStringArray(schemasProp, ","));
1767         }
1768         String tableProp = props.remove(ConfigUtils.TABLE);
1769         if (tableProp != null) {
1770             setTable(tableProp);
1771         }
1772         String tablespaceProp = props.remove(ConfigUtils.TABLESPACE);
1773         if (tablespaceProp != null) {
1774             setTablespace(tablespaceProp);
1775         }
1776         Boolean cleanOnValidationErrorProp = removeBoolean(props, ConfigUtils.CLEAN_ON_VALIDATION_ERROR);
1777         if (cleanOnValidationErrorProp != null) {
1778             setCleanOnValidationError(cleanOnValidationErrorProp);
1779         }
1780         Boolean cleanDisabledProp = removeBoolean(props, ConfigUtils.CLEAN_DISABLED);
1781         if (cleanDisabledProp != null) {
1782             setCleanDisabled(cleanDisabledProp);
1783         }
1784         Boolean validateOnMigrateProp = removeBoolean(props, ConfigUtils.VALIDATE_ON_MIGRATE);
1785         if (validateOnMigrateProp != null) {
1786             setValidateOnMigrate(validateOnMigrateProp);
1787         }
1788         String baselineVersionProp = props.remove(ConfigUtils.BASELINE_VERSION);
1789         if (baselineVersionProp != null) {
1790             setBaselineVersion(MigrationVersion.fromVersion(baselineVersionProp));
1791         }
1792         String baselineDescriptionProp = props.remove(ConfigUtils.BASELINE_DESCRIPTION);
1793         if (baselineDescriptionProp != null) {
1794             setBaselineDescription(baselineDescriptionProp);
1795         }
1796         Boolean baselineOnMigrateProp = removeBoolean(props, ConfigUtils.BASELINE_ON_MIGRATE);
1797         if (baselineOnMigrateProp != null) {
1798             setBaselineOnMigrate(baselineOnMigrateProp);
1799         }
1800         Boolean ignoreMissingMigrationsProp = removeBoolean(props, ConfigUtils.IGNORE_MISSING_MIGRATIONS);
1801         if (ignoreMissingMigrationsProp != null) {
1802             setIgnoreMissingMigrations(ignoreMissingMigrationsProp);
1803         }
1804         Boolean ignoreIgnoredMigrationsProp = removeBoolean(props, ConfigUtils.IGNORE_IGNORED_MIGRATIONS);
1805         if (ignoreIgnoredMigrationsProp != null) {
1806             setIgnoreIgnoredMigrations(ignoreIgnoredMigrationsProp);
1807         }
1808         Boolean ignorePendingMigrationsProp = removeBoolean(props, ConfigUtils.IGNORE_PENDING_MIGRATIONS);
1809         if (ignorePendingMigrationsProp != null) {
1810             setIgnorePendingMigrations(ignorePendingMigrationsProp);
1811         }
1812         Boolean ignoreFutureMigrationsProp = removeBoolean(props, ConfigUtils.IGNORE_FUTURE_MIGRATIONS);
1813         if (ignoreFutureMigrationsProp != null) {
1814             setIgnoreFutureMigrations(ignoreFutureMigrationsProp);
1815         }
1816         Boolean validateMigrationNamingProp = removeBoolean(props, ConfigUtils.VALIDATE_MIGRATION_NAMING);
1817         if (validateMigrationNamingProp != null) {
1818             setValidateMigrationNaming(validateMigrationNamingProp);
1819         }
1820         String targetProp = props.remove(ConfigUtils.TARGET);
1821         if (targetProp != null) {
1822             setTarget(MigrationVersion.fromVersion(targetProp));
1823         }
1824         Boolean outOfOrderProp = removeBoolean(props, ConfigUtils.OUT_OF_ORDER);
1825         if (outOfOrderProp != null) {
1826             setOutOfOrder(outOfOrderProp);
1827         }
1828         Boolean outputQueryResultsProp = removeBoolean(props, ConfigUtils.OUTPUT_QUERY_RESULTS);
1829         if (outputQueryResultsProp != null) {
1830             setOutputQueryResults(outputQueryResultsProp);
1831         }
1832         String resolversProp = props.remove(ConfigUtils.RESOLVERS);
1833         if (StringUtils.hasLength(resolversProp)) {
1834             setResolversAsClassNames(StringUtils.tokenizeToStringArray(resolversProp, ","));
1835         }
1836         Boolean skipDefaultResolversProp = removeBoolean(props, ConfigUtils.SKIP_DEFAULT_RESOLVERS);
1837         if (skipDefaultResolversProp != null) {
1838             setSkipDefaultResolvers(skipDefaultResolversProp);
1839         }
1840         String callbacksProp = props.remove(ConfigUtils.CALLBACKS);
1841         if (StringUtils.hasLength(callbacksProp)) {
1842             setCallbacksAsClassNames(StringUtils.tokenizeToStringArray(callbacksProp, ","));
1843         }
1844         Boolean skipDefaultCallbacksProp = removeBoolean(props, ConfigUtils.SKIP_DEFAULT_CALLBACKS);
1845         if (skipDefaultCallbacksProp != null) {
1846             setSkipDefaultCallbacks(skipDefaultCallbacksProp);
1847         }
1848
1849         Map<String, String> placeholdersFromProps = new HashMap<>(getPlaceholders());
1850         Iterator<Map.Entry<String, String>> iterator = props.entrySet().iterator();
1851         while (iterator.hasNext()) {
1852             Map.Entry<String, String> entry = iterator.next();
1853             String propertyName = entry.getKey();
1854
1855             if (propertyName.startsWith(ConfigUtils.PLACEHOLDERS_PROPERTY_PREFIX)
1856                     && propertyName.length() > ConfigUtils.PLACEHOLDERS_PROPERTY_PREFIX.length()) {
1857                 String placeholderName = propertyName.substring(ConfigUtils.PLACEHOLDERS_PROPERTY_PREFIX.length());
1858                 String placeholderValue = entry.getValue();
1859                 placeholdersFromProps.put(placeholderName, placeholderValue);
1860                 iterator.remove();
1861             }
1862         }
1863         setPlaceholders(placeholdersFromProps);
1864
1865         Boolean mixedProp = removeBoolean(props, ConfigUtils.MIXED);
1866         if (mixedProp != null) {
1867             setMixed(mixedProp);
1868         }
1869
1870         Boolean groupProp = removeBoolean(props, ConfigUtils.GROUP);
1871         if (groupProp != null) {
1872             setGroup(groupProp);
1873         }
1874
1875         String installedByProp = props.remove(ConfigUtils.INSTALLED_BY);
1876         if (installedByProp != null) {
1877             setInstalledBy(installedByProp);
1878         }
1879
1880         String dryRunOutputProp = props.remove(ConfigUtils.DRYRUN_OUTPUT);
1881         if (dryRunOutputProp != null) {
1882             setDryRunOutputAsFileName(dryRunOutputProp);
1883         }
1884
1885         String errorOverridesProp = props.remove(ConfigUtils.ERROR_OVERRIDES);
1886         if (errorOverridesProp != null) {
1887             setErrorOverrides(StringUtils.tokenizeToStringArray(errorOverridesProp, ","));
1888         }
1889
1890         Boolean streamProp = removeBoolean(props, ConfigUtils.STREAM);
1891         if (streamProp != null) {
1892             setStream(streamProp);
1893         }
1894
1895         Boolean batchProp = removeBoolean(props, ConfigUtils.BATCH);
1896         if (batchProp != null) {
1897             setBatch(batchProp);
1898         }
1899
1900         Boolean oracleSqlplusProp = removeBoolean(props, ConfigUtils.ORACLE_SQLPLUS);
1901         if (oracleSqlplusProp != null) {
1902             setOracleSqlplus(oracleSqlplusProp);
1903         }
1904
1905         Boolean oracleSqlplusWarnProp = removeBoolean(props, ConfigUtils.ORACLE_SQLPLUS_WARN);
1906         if (oracleSqlplusWarnProp != null) {
1907             setOracleSqlplusWarn(oracleSqlplusWarnProp);
1908         }
1909
1910         String licenseKeyProp = props.remove(ConfigUtils.LICENSE_KEY);
1911         if (licenseKeyProp != null) {
1912             setLicenseKey(licenseKeyProp);
1913         }
1914
1915         ConfigUtils.checkConfigurationForUnrecognisedProperties(props, "flyway.");
1916     }
1917
1918     /**
1919      * Configures Flyway using FLYWAY_* environment variables.
1920      */

1921     public void configureUsingEnvVars() {
1922         configure(ConfigUtils.environmentVariablesToPropertyMap());
1923     }
1924 }