diff --git b/.gitattributes a/.gitattributes
new file mode 100644
index 0000000..a54bdaf
--- /dev/null
+++ a/.gitattributes
@@ -0,0 +1,10 @@
+* text eol=lf
+
+*.ico binary
+*.png binary
+*.gif binary
+*.jar binary
+*.nofilter binary
+*.kdbx binary
+*.exe binary
+*.dll binary
\ No newline at end of file
diff --git b/.gitignore a/.gitignore
new file mode 100644
index 0000000..7aaf979
--- /dev/null
+++ a/.gitignore
@@ -0,0 +1,21 @@
+bin
+build
+target
+*.iml
+*.ipr
+*.iws
+*.ids
+.project
+.classpath
+.settings
+.metadata
+.gradle
+*.h2.db
+.DS_Store
+
+**/.idea/**
+!**/.idea/runConfigurations/
+!**/.idea/runConfigurations/*
+!**/.idea/codeStyles/
+!**/.idea/codeStyles/*
+flyway-core/SPOOLEDCONTENTS.SQL
diff --git b/.travis.yml a/.travis.yml
new file mode 100644
index 0000000..ce3679e
--- /dev/null
+++ a/.travis.yml
@@ -0,0 +1,13 @@
+language: minimal
+
+env:
+ matrix:
+ - JDK_VERSION=10
+ - JDK_VERSION=11
+ - JDK_VERSION=12
+ - JDK_VERSION=13
+
+install: skip
+
+script:
+ - docker run -it --rm -v "$PWD":/usr/src/flyway -w /usr/src/flyway maven:3-jdk-$JDK_VERSION mvn install -e
\ No newline at end of file
diff --git b/CONTRIBUTING.md a/CONTRIBUTING.md
new file mode 100644
index 0000000..c6f8bb7
--- /dev/null
+++ a/CONTRIBUTING.md
@@ -0,0 +1,8 @@
+Contribute
+==========
+
+So you've got an awesome idea to throw into Flyway. Great! Please keep the following in mind:
+
+* **Use http://stackoverflow.com/questions/tagged/flyway for Flyway questions that are not bugs.**
+* **Contributions must include the necessary documentation updates.**
+* **Make sure to read https://flywaydb.org/documentation/contribute/ first**
\ No newline at end of file
diff --git b/ISSUE_TEMPLATE.md a/ISSUE_TEMPLATE.md
new file mode 100644
index 0000000..4745099
--- /dev/null
+++ a/ISSUE_TEMPLATE.md
@@ -0,0 +1,31 @@
+###### Which version and edition of Flyway are you using?
+
+
+
+###### If this is not the latest version, can you reproduce the issue with the latest one as well?
+(Many bugs are fixed in newer releases and upgrading will often resolve the issue)
+
+
+
+###### Which client are you using? (Command-line, Java API, Maven plugin, Gradle plugin)
+
+
+
+###### Which database are you using (type & version)?
+
+
+
+###### Which operating system are you using?
+
+
+
+###### What did you do?
+(Please include the content causing the issue, any relevant configuration settings, the SQL statement that failed (if relevant) and the command you ran.)
+
+
+
+###### What did you expect to see?
+
+
+
+###### What did you see instead?
diff --git b/LICENSE a/LICENSE
new file mode 100644
index 0000000..fb87ce6
--- /dev/null
+++ a/LICENSE
@@ -0,0 +1,191 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright
+owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities
+that control, are controlled by, or are under common control with that entity.
+For the purposes of this definition, "control" means (i) the power, direct or
+indirect, to cause the direction or management of such entity, whether by
+contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
+outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising
+permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including
+but not limited to software source code, documentation source, and configuration
+files.
+
+"Object" form shall mean any form resulting from mechanical transformation or
+translation of a Source form, including but not limited to compiled object code,
+generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made
+available under the License, as indicated by a copyright notice that is included
+in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that
+is based on (or derived from) the Work and for which the editorial revisions,
+annotations, elaborations, or other modifications represent, as a whole, an
+original work of authorship. For the purposes of this License, Derivative Works
+shall not include works that remain separable from, or merely link (or bind by
+name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version
+of the Work and any modifications or additions to that Work or Derivative Works
+thereof, that is intentionally submitted to Licensor for inclusion in the Work
+by the copyright owner or by an individual or Legal Entity authorized to submit
+on behalf of the copyright owner. For the purposes of this definition,
+"submitted" means any form of electronic, verbal, or written communication sent
+to the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control systems, and
+issue tracking systems that are managed by, or on behalf of, the Licensor for
+the purpose of discussing and improving the Work, but excluding communication
+that is conspicuously marked or otherwise designated in writing by the copyright
+owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
+of whom a Contribution has been received by Licensor and subsequently
+incorporated within the Work.
+
+2. Grant of Copyright License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the Work and such
+Derivative Works in Source or Object form.
+
+3. Grant of Patent License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable (except as stated in this section) patent license to make, have
+made, use, offer to sell, sell, import, and otherwise transfer the Work, where
+such license applies only to those patent claims licensable by such Contributor
+that are necessarily infringed by their Contribution(s) alone or by combination
+of their Contribution(s) with the Work to which such Contribution(s) was
+submitted. If You institute patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Work or a
+Contribution incorporated within the Work constitutes direct or contributory
+patent infringement, then any patent licenses granted to You under this License
+for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution.
+
+You may reproduce and distribute copies of the Work or Derivative Works thereof
+in any medium, with or without modifications, and in Source or Object form,
+provided that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of
+this License; and
+You must cause any modified files to carry prominent notices stating that You
+changed the files; and
+You must retain, in the Source form of any Derivative Works that You distribute,
+all copyright, patent, trademark, and attribution notices from the Source form
+of the Work, excluding those notices that do not pertain to any part of the
+Derivative Works; and
+If the Work includes a "NOTICE" text file as part of its distribution, then any
+Derivative Works that You distribute must include a readable copy of the
+attribution notices contained within such NOTICE file, excluding those notices
+that do not pertain to any part of the Derivative Works, in at least one of the
+following places: within a NOTICE text file distributed as part of the
+Derivative Works; within the Source form or documentation, if provided along
+with the Derivative Works; or, within a display generated by the Derivative
+Works, if and wherever such third-party notices normally appear. The contents of
+the NOTICE file are for informational purposes only and do not modify the
+License. You may add Your own attribution notices within Derivative Works that
+You distribute, alongside or as an addendum to the NOTICE text from the Work,
+provided that such additional attribution notices cannot be construed as
+modifying the License.
+You may add Your own copyright statement to Your modifications and may provide
+additional or different license terms and conditions for use, reproduction, or
+distribution of Your modifications, or for any such Derivative Works as a whole,
+provided Your use, reproduction, and distribution of the Work otherwise complies
+with the conditions stated in this License.
+
+5. Submission of Contributions.
+
+Unless You explicitly state otherwise, any Contribution intentionally submitted
+for inclusion in the Work by You to the Licensor shall be under the terms and
+conditions of this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify the terms of
+any separate license agreement you may have executed with Licensor regarding
+such Contributions.
+
+6. Trademarks.
+
+This License does not grant permission to use the trade names, trademarks,
+service marks, or product names of the Licensor, except as required for
+reasonable and customary use in describing the origin of the Work and
+reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty.
+
+Unless required by applicable law or agreed to in writing, Licensor provides the
+Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+including, without limitation, any warranties or conditions of TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
+solely responsible for determining the appropriateness of using or
+redistributing the Work and assume any risks associated with Your exercise of
+permissions under this License.
+
+8. Limitation of Liability.
+
+In no event and under no legal theory, whether in tort (including negligence),
+contract, or otherwise, unless required by applicable law (such as deliberate
+and grossly negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License or
+out of the use or inability to use the Work (including but not limited to
+damages for loss of goodwill, work stoppage, computer failure or malfunction, or
+any and all other commercial damages or losses), even if such Contributor has
+been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability.
+
+While redistributing the Work or Derivative Works thereof, You may choose to
+offer, and charge a fee for, acceptance of support, warranty, indemnity, or
+other liability obligations and/or rights consistent with this License. However,
+in accepting such obligations, You may act only on Your own behalf and on Your
+sole responsibility, not on behalf of any other Contributor, and only if You
+agree to indemnify, defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason of your
+accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work
+
+To apply the Apache License to your work, attach the following boilerplate
+notice, with the fields enclosed by brackets "[]" replaced with your own
+identifying information. (Don't include the brackets!) The text should be
+enclosed in the appropriate comment syntax for the file format. We also
+recommend that a file or class name and description of purpose be included on
+the same "printed page" as the copyright notice for easier identification within
+third-party archives.
+
+ Copyright 2010-2020 Redgate Software Ltd
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git b/LICENSE.txt a/LICENSE.txt
new file mode 100644
index 0000000..547b931
--- /dev/null
+++ a/LICENSE.txt
@@ -0,0 +1,13 @@
+Copyright 2010-2020 Redgate Software Ltd
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
\ No newline at end of file
diff --git b/README.md a/README.md
new file mode 100644
index 0000000..d06b5d0
--- /dev/null
+++ a/README.md
@@ -0,0 +1,47 @@
+# [Flyway](https://flywaydb.org) by [Redgate](https://www.red-gate.com/) [](https://travis-ci.org/flyway/flyway) [](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.flywaydb.flyway-core%22) [](http://www.apache.org/licenses/LICENSE-2.0)
+
+### Database Migrations Made Easy.
+
+
+
+#### Evolve your database schema easily and reliably across all your instances.
+Simple, focused and powerful.
+
+#### Works on
+Windows, macOS, Linux, Docker, Java and Android
+
+#### Supported build tools
+Maven and Gradle
+
+#### Supported databases
+Oracle, SQL Server, DB2, MySQL, Aurora MySQL, MariaDB, Percona XtraDB Cluster, PostgreSQL, Aurora PostgreSQL, Redshift, CockroachDB, SAP HANA, Sybase ASE, Informix, H2, HSQLDB, Derby, SQLite, Firebird
+
+#### Third party plugins
+SBT, Ant, Spring Boot, Grails, Play!, DropWizard, Grunt, Griffon, Ninja, ...
+
+## Documentation
+https://flywaydb.org
+
+## About
+Flyway is brought to you by [Redgate](https://www.red-gate.com/) with the help of [many contributors](https://flywaydb.org/documentation/contribute/hallOfFame.html).
+
+## How to contribute
+https://flywaydb.org/documentation/contribute
+
+## License
+Copyright (C) 2010-2020 [Boxfuse GmbH](https://boxfuse.com)
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+## Trademark
+Flyway is a registered trademark of [Boxfuse GmbH](https://boxfuse.com), owned by [Redgate](https://www.red-gate.com/).
diff --git b/README.txt a/README.txt
new file mode 100644
index 0000000..6bcd0ec
--- /dev/null
+++ a/README.txt
@@ -0,0 +1,34 @@
+Welcome to Flyway.
+------------------
+Database Migrations Made Easy.
+
+
+Documentation
+-------------
+You can find getting started guides and reference documentation at https://flywaydb.org
+
+
+Contributing
+------------
+Here is the info on how you can contribute in various ways to the project: https://flywaydb.org/documentation/contribute/
+
+
+License
+-------
+Copyright (C) 2010-2020 Boxfuse GmbH
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+
+Flyway is a registered trademark of Boxfuse GmbH.
\ No newline at end of file
diff --git b/flyway-commandline/pom.xml a/flyway-commandline/pom.xml
new file mode 100644
index 0000000..418e05e
--- /dev/null
+++ a/flyway-commandline/pom.xml
@@ -0,0 +1,376 @@
+
+
+ 4.0.0
+
+ org.flywaydb
+ flyway-parent
+ 0-SNAPSHOT
+
+ flyway-commandline
+ jar
+ ${project.artifactId}
+
+
+
+
+
+
+
+ ${project.groupId}
+ flyway-core
+ ${project.version}
+
+
+ org.apache.derby
+ derby
+
+
+ org.apache.derby
+ derbytools
+
+
+ org.apache.derby
+ derbyshared
+
+
+ org.apache.derby
+ derbyclient
+
+
+ com.h2database
+ h2
+
+
+ org.hsqldb
+ hsqldb
+
+
+ com.microsoft.sqlserver
+ mssql-jdbc
+
+
+ net.sourceforge.jtds
+ jtds
+
+
+ mysql
+ mysql-connector-java
+
+
+
+ net.java.dev.jna
+ jna
+
+
+ net.java.dev.jna
+ jna-platform
+
+
+ org.firebirdsql.jdbc
+ jaybird-jdk18
+
+
+ org.mariadb.jdbc
+ mariadb-java-client
+
+
+ org.postgresql
+ postgresql
+
+
+ net.snowflake
+ snowflake-jdbc
+
+
+ org.xerial
+ sqlite-jdbc
+
+
+ org.fusesource.jansi
+ jansi
+
+
+ com.google.code.gson
+ gson
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ maven-resources-plugin
+
+
+ copy-license
+
+ copy-resources
+
+ generate-resources
+
+
+
+ ..
+
+ LICENSE.txt
+ README.txt
+
+
+
+ ${project.build.outputDirectory}/META-INF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ build-assemblies
+
+ false
+
+
+
+ net.adoptopenjdk
+ jre
+ windows-x64
+ zip
+ provided
+
+
+ net.adoptopenjdk
+ jre
+ linux-x64
+ tar.gz
+ provided
+
+
+ net.adoptopenjdk
+ jre
+ macos-x64
+ tar.gz
+ provided
+
+
+ com.oracle.database.jdbc
+ ojdbc8
+
+
+
+
+
+ maven-dependency-plugin
+
+
+ unpack-jres
+ package
+
+ unpack-dependencies
+
+
+ true
+ jre
+ true
+ true
+
+
+
+
+ copy-editions
+ package
+
+ copy
+
+
+
+
+ org.flywaydb.pro
+ flyway-commandline
+ ${project.version}
+ jar
+ ${project.build.directory}/editions/pro
+
+
+ org.flywaydb.pro
+ flyway-core
+ ${project.version}
+ jar
+ ${project.build.directory}/editions/pro
+
+
+ org.flywaydb.enterprise
+ flyway-commandline
+ ${project.version}
+ jar
+ ${project.build.directory}/editions/enterprise
+
+
+ org.flywaydb.enterprise
+ flyway-core
+ ${project.version}
+ jar
+ ${project.build.directory}/editions/enterprise
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ maven-assembly-plugin
+
+
+ nojre-assembly
+ package
+
+ single
+
+
+
+ src/main/assembly/no-jre.xml
+
+ false
+
+
+
+ jre-assemblies
+ package
+
+ single
+
+
+
+ src/main/assembly/windows.xml
+ src/main/assembly/linux.xml
+ src/main/assembly/macos.xml
+
+
+
+
+
+ UTF-8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git b/flyway-commandline/src/main/assembly/LICENSES-THIRD-PARTY.txt a/flyway-commandline/src/main/assembly/LICENSES-THIRD-PARTY.txt
new file mode 100644
index 0000000..d97ebd7
--- /dev/null
+++ a/flyway-commandline/src/main/assembly/LICENSES-THIRD-PARTY.txt
@@ -0,0 +1,4485 @@
+This distribution contains third-party software subject to various licenses:
+
+Java Runtime Environment ${version.jre} (jre/*)
+-------------------------------------
+Source: https://adoptopenjdk.net/
+
+
+GNU General Public License, version 2,
+with the Classpath Exception
+
+The GNU General Public License (GPL)
+
+Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share
+and change it. By contrast, the GNU General Public License is intended to
+guarantee your freedom to share and change free software--to make sure the
+software is free for all its users. This General Public License applies to
+most of the Free Software Foundation's software and to any other program whose
+authors commit to using it. (Some other Free Software Foundation software is
+covered by the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+When we speak of free software, we are referring to freedom, not price. Our
+General Public Licenses are designed to make sure that you have the freedom to
+distribute copies of free software (and charge for this service if you wish),
+that you receive source code or can get it if you want it, that you can change
+the software or use pieces of it in new free programs; and that you know you
+can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to deny
+you these rights or to ask you to surrender the rights. These restrictions
+translate to certain responsibilities for you if you distribute copies of the
+software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or for
+a fee, you must give the recipients all the rights that you have. You must
+make sure that they, too, receive or can get the source code. And you must
+show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2)
+offer you this license which gives you legal permission to copy, distribute
+and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain that
+everyone understands that there is no warranty for this free software. If the
+software is modified by someone else and passed on, we want its recipients to
+know that what they have is not the original, so that any problems introduced
+by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents. We
+wish to avoid the danger that redistributors of a free program will
+individually obtain patent licenses, in effect making the program proprietary.
+To prevent this, we have made it clear that any patent must be licensed for
+everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification
+follow.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License applies to any program or other work which contains a notice
+placed by the copyright holder saying it may be distributed under the terms of
+this General Public License. The "Program", below, refers to any such program
+or work, and a "work based on the Program" means either the Program or any
+derivative work under copyright law: that is to say, a work containing the
+Program or a portion of it, either verbatim or with modifications and/or
+translated into another language. (Hereinafter, translation is included
+without limitation in the term "modification".) Each licensee is addressed as
+"you".
+
+Activities other than copying, distribution and modification are not covered by
+this License; they are outside its scope. The act of running the Program is
+not restricted, and the output from the Program is covered only if its contents
+constitute a work based on the Program (independent of having been made by
+running the Program). Whether that is true depends on what the Program does.
+
+1. You may copy and distribute verbatim copies of the Program's source code as
+you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this License
+and to the absence of any warranty; and give any other recipients of the
+Program a copy of this License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and you may
+at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of it, thus
+forming a work based on the Program, and copy and distribute such modifications
+or work under the terms of Section 1 above, provided that you also meet all of
+these conditions:
+
+ a) You must cause the modified files to carry prominent notices stating
+ that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in whole or
+ in part contains or is derived from the Program or any part thereof, to be
+ licensed as a whole at no charge to all third parties under the terms of
+ this License.
+
+ c) If the modified program normally reads commands interactively when run,
+ you must cause it, when started running for such interactive use in the
+ most ordinary way, to print or display an announcement including an
+ appropriate copyright notice and a notice that there is no warranty (or
+ else, saying that you provide a warranty) and that users may redistribute
+ the program under these conditions, and telling the user how to view a copy
+ of this License. (Exception: if the Program itself is interactive but does
+ not normally print such an announcement, your work based on the Program is
+ not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If identifiable
+sections of that work are not derived from the Program, and can be reasonably
+considered independent and separate works in themselves, then this License, and
+its terms, do not apply to those sections when you distribute them as separate
+works. But when you distribute the same sections as part of a whole which is a
+work based on the Program, the distribution of the whole must be on the terms
+of this License, whose permissions for other licensees extend to the entire
+whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise the
+right to control the distribution of derivative or collective works based on
+the Program.
+
+In addition, mere aggregation of another work not based on the Program with the
+Program (or with a work based on the Program) on a volume of a storage or
+distribution medium does not bring the other work under the scope of this
+License.
+
+3. You may copy and distribute the Program (or a work based on it, under
+Section 2) in object code or executable form under the terms of Sections 1 and
+2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable source
+ code, which must be distributed under the terms of Sections 1 and 2 above
+ on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three years, to
+ give any third party, for a charge no more than your cost of physically
+ performing source distribution, a complete machine-readable copy of the
+ corresponding source code, to be distributed under the terms of Sections 1
+ and 2 above on a medium customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer to
+ distribute corresponding source code. (This alternative is allowed only
+ for noncommercial distribution and only if you received the program in
+ object code or executable form with such an offer, in accord with
+ Subsection b above.)
+
+The source code for a work means the preferred form of the work for making
+modifications to it. For an executable work, complete source code means all
+the source code for all modules it contains, plus any associated interface
+definition files, plus the scripts used to control compilation and installation
+of the executable. However, as a special exception, the source code
+distributed need not include anything that is normally distributed (in either
+source or binary form) with the major components (compiler, kernel, and so on)
+of the operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the source
+code from the same place counts as distribution of the source code, even though
+third parties are not compelled to copy the source along with the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program except as
+expressly provided under this License. Any attempt otherwise to copy, modify,
+sublicense or distribute the Program is void, and will automatically terminate
+your rights under this License. However, parties who have received copies, or
+rights, from you under this License will not have their licenses terminated so
+long as such parties remain in full compliance.
+
+5. You are not required to accept this License, since you have not signed it.
+However, nothing else grants you permission to modify or distribute the Program
+or its derivative works. These actions are prohibited by law if you do not
+accept this License. Therefore, by modifying or distributing the Program (or
+any work based on the Program), you indicate your acceptance of this License to
+do so, and all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the Program),
+the recipient automatically receives a license from the original licensor to
+copy, distribute or modify the Program subject to these terms and conditions.
+You may not impose any further restrictions on the recipients' exercise of the
+rights granted herein. You are not responsible for enforcing compliance by
+third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues), conditions
+are imposed on you (whether by court order, agreement or otherwise) that
+contradict the conditions of this License, they do not excuse you from the
+conditions of this License. If you cannot distribute so as to satisfy
+simultaneously your obligations under this License and any other pertinent
+obligations, then as a consequence you may not distribute the Program at all.
+For example, if a patent license would not permit royalty-free redistribution
+of the Program by all those who receive copies directly or indirectly through
+you, then the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply and
+the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or
+other property right claims or to contest validity of any such claims; this
+section has the sole purpose of protecting the integrity of the free software
+distribution system, which is implemented by public license practices. Many
+people have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing to
+distribute software through any other system and a licensee cannot impose that
+choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain
+countries either by patents or by copyrighted interfaces, the original
+copyright holder who places the Program under this License may add an explicit
+geographical distribution limitation excluding those countries, so that
+distribution is permitted only in or among countries not thus excluded. In
+such case, this License incorporates the limitation as if written in the body
+of this License.
+
+9. The Free Software Foundation may publish revised and/or new versions of the
+General Public License from time to time. Such new versions will be similar in
+spirit to the present version, but may differ in detail to address new problems
+or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any later
+version", you have the option of following the terms and conditions either of
+that version or of any later version published by the Free Software Foundation.
+If the Program does not specify a version number of this License, you may
+choose any version ever published by the Free Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free programs
+whose distribution conditions are different, write to the author to ask for
+permission. For software which is copyrighted by the Free Software Foundation,
+write to the Free Software Foundation; we sometimes make exceptions for this.
+Our decision will be guided by the two goals of preserving the free status of
+all derivatives of our free software and of promoting the sharing and reuse of
+software generally.
+
+NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
+PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
+PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,
+YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
+ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
+PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
+BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER
+OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest possible
+use to the public, the best way to achieve this is to make it free software
+which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program. It is safest to attach
+them to the start of each source file to most effectively convey the exclusion
+of warranty; and each file should have at least the "copyright" line and a
+pointer to where the full notice is found.
+
+ One line to give the program's name and a brief idea of what it does.
+
+ Copyright (C)
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc., 59
+ Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this when it
+starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
+ with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free
+ software, and you are welcome to redistribute it under certain conditions;
+ type 'show c' for details.
+
+The hypothetical commands 'show w' and 'show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may be
+called something other than 'show w' and 'show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your school,
+if any, to sign a "copyright disclaimer" for the program, if necessary. Here
+is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ 'Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ signature of Ty Coon, 1 April 1989
+
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General Public
+License instead of this License.
+
+
+"CLASSPATH" EXCEPTION TO THE GPL
+
+Certain source files distributed by Oracle America and/or its affiliates are
+subject to the following clarification and special exception to the GPL, but
+only where Oracle has expressly included in the particular source file's header
+the words "Oracle designates this particular file as subject to the "Classpath"
+exception as provided by Oracle in the LICENSE file that accompanied this code."
+
+ Linking this library statically or dynamically with other modules is making
+ a combined work based on this library. Thus, the terms and conditions of
+ the GNU General Public License cover the whole combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent modules,
+ and to copy and distribute the resulting executable under terms of your
+ choice, provided that you also meet, for each linked independent module,
+ the terms and conditions of the license of that module. An independent
+ module is a module which is not derived from or based on this library. If
+ you modify this library, you may extend this exception to your version of
+ the library, but you are not obligated to do so. If you do not wish to do
+ so, delete this exception statement from your version.
+
+
+
+
+ADDITIONAL INFORMATION ABOUT LICENSING
+
+Certain files distributed by Oracle America, Inc. and/or its affiliates are
+subject to the following clarification and special exception to the GPLv2,
+based on the GNU Project exception for its Classpath libraries, known as the
+GNU Classpath Exception.
+
+Note that Oracle includes multiple, independent programs in this software
+package. Some of those programs are provided under licenses deemed
+incompatible with the GPLv2 by the Free Software Foundation and others.
+For example, the package includes programs licensed under the Apache
+License, Version 2.0 and may include FreeType. Such programs are licensed
+to you under their original licenses.
+
+Oracle facilitates your further distribution of this package by adding the
+Classpath Exception to the necessary parts of its GPLv2 code, which permits
+you to use that code in combination with other independent modules not
+licensed under the GPLv2. However, note that this would not permit you to
+commingle code under an incompatible license with Oracle's GPLv2 licensed
+code by, for example, cutting and pasting such code into a file also
+containing Oracle's GPLv2 licensed code and then distributing the result.
+
+Additionally, if you were to remove the Classpath Exception from any of the
+files to which it applies and distribute the result, you would likely be
+required to license some or all of the other code in that distribution under
+the GPLv2 as well, and since the GPLv2 is incompatible with the license terms
+of some items included in the distribution by Oracle, removing the Classpath
+Exception could therefore effectively compromise your ability to further
+distribute the package.
+
+Failing to distribute notices associated with some files may also create
+unexpected legal consequences.
+
+Proceed with caution and we recommend that you obtain the advice of a lawyer
+skilled in open source matters before removing the Classpath Exception or
+making modifications to this package which may subsequently be redistributed
+and/or involve the use of third party software.
+
+
+Oracle OJDBC8 ${version.oracle} (drivers/ojdbc-${version.oracle}.jar)
+----------------------------------------------------------
+Source: https://repo1.maven.org/maven2/com/oracle/ojdbc/ojdbc8/${version.oracle}/ojdbc8-${version.oracle}.pom
+
+Oracle Free Use Terms and Conditions (FUTC)
+
+Oracle Free Use Terms and Conditions Definitions
+
+"Oracle" refers to Oracle America, Inc. "You" and "Your" refers to (a) a company or organization (each an "Entity")
+accessing the Programs, if use of the Programs will be on behalf of such Entity; or (b) an individual accessing the
+Programs, if use of the Programs will not be on behalf of an Entity. "Program(s)" refers to Oracle software provided
+by Oracle pursuant to the following terms and any updates, error corrections, and/or Program Documentation provided by
+Oracle. "Program Documentation" refers to Program user manuals and Program installation manuals, if any. If available,
+Program Documentation may be delivered with the Programs and/or may be accessed from www.oracle.com/documentation.
+"Separate Terms" refers to separate license terms that are specified in the Program Documentation, readmes or notice
+files and that apply to Separately Licensed Technology. "Separately Licensed Technology" refers to Oracle or third
+party technology that is licensed under Separate Terms and not under the terms of this license. Separately Licensed
+Technology Oracle may provide certain notices to You in Program Documentation, readmes or notice files in connection
+with Oracle or third party technology provided as or with the Programs. If specified in the Program Documentation,
+readmes or notice files, such technology will be licensed to You under Separate Terms. Your rights to use Separately
+Licensed Technology under Separate Terms are not restricted in any way by the terms herein. For clarity,
+notwithstanding the existence of a notice, third party technology that is not Separately Licensed Technology shall be
+deemed part of the Programs licensed to You under the terms of this license. Source Code for Open Source Software For
+software that You receive from Oracle in binary form that is licensed under an open source license that gives You the
+right to receive the source code for that binary, You can obtain a copy of the applicable source code from
+https://oss.oracle.com/sources/ or http://www.oracle.com/goto/opensourcecode. If the source code for such software was
+not provided to You with the binary, You can also receive a copy of the source code on physical media by submitting a
+written request pursuant to the instructions in the "Written Offer for Source Code" section of the latter website.
+-------------------------------------------------------------------------------
+The following license terms apply to those Programs that are not provided to You under Separate Terms. License Rights
+and Restrictions Oracle grants to You, as a recipient of this Program, a nonexclusive, nontransferable, limited license
+to, subject to the conditions stated herein, (a) internally use the unmodified Programs for the purposes of developing,
+testing, prototyping and demonstrating your applications, and running the Programs for your own internal business
+operations; and (b) redistribute unmodified Programs and Programs Documentation, under the terms of this License,
+provided that You do not charge Your end users any additional fees for the use of the Programs. You may make copies of
+the Programs to the extent reasonably necessary for exercising the license rights granted herein and for backup
+purposes. You are granted the right to use the Programs to provide third party training in the use of the Programs and
+associated Separately Licensed Technology only if there is express authorization of such use by Oracle on the Program's
+download page or in the Program Documentation. Your license is contingent on Your compliance with the following
+conditions:
+- You include a copy of this license with any distribution by You of the Programs;
+- You do not remove markings or notices of either Oracle's or a licensor's proprietary rights from the Programs or
+Program Documentation;
+- You comply with all U.S. and applicable export control and economic sanctions laws and regulations that govern Your
+use of the Programs (including technical data);
+- You do not cause or permit reverse engineering, disassembly or decompilation of the Programs (except as allowed by
+law) by You nor allow an associated party to do so. For clarity, any source code that may be included in the
+distribution with the Programs is provided solely for reference purposes and may not be modified, unless such source
+code is under Separate Terms permitting modification. Ownership Oracle or its licensors retain all ownership and
+intellectual property rights to the Programs. Information Collection The Programs' installation and/or auto-update
+processes, if any, may transmit a limited amount of data to Oracle or its service provider about those processes to
+help Oracle understand and optimize them. Oracle does not associate the data with personally identifiable information.
+Refer to Oracle's Privacy Policy at www.oracle.com/privacy.
+
+Disclaimer of Warranties; Limitation of Liability
+
+THE PROGRAMS ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. ORACLE FURTHER DISCLAIMS ALL WARRANTIES, EXPRESS AND
+IMPLIED, INCLUDING WITHOUT LIMITATION, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+NONINFRINGEMENT. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL ORACLE BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING
+BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+Last updated: 8 October 2018
+
+
+Derby ${version.derby} (drivers/derby-${version.derby}.jar)
+Derby Client ${version.derby} (drivers/derbyclient-${version.derby}.jar)
+Derby Tools ${version.derby} (drivers/derbytools-${version.derby}.jar)
+Derby Shared ${version.derby} (drivers/derbyshared-${version.derby}.jar)
+----------------------------------------------------------
+Source: http://db.apache.org/derby/
+
+Copyright 2004-2014 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
+
+H2 ${version.h2} (drivers/h2-${version.h2}.jar)
+-----------------------------------
+Source: http://www.h2database.com/
+
+Copyright 2004-2014 H2 Group
+
+This software contains unmodified binary redistributions for H2 database engine (http://www.h2database.com/),
+which is dual licensed and available under the MPL 2.0 (Mozilla Public License) or under the EPL 1.0 (Eclipse Public License).
+An original copy of the license agreement can be found at: http://www.h2database.com/html/license.html
+
+
+
+
+HSQLDB ${version.hsqldb} (drivers/hsqldb-${version.hsqldb}.jar)
+---------------------------------------
+Source: http://hsqldb.org/
+
+For work developed by the HSQL Development Group:
+
+Copyright (c) 2001-2014, The HSQL Development Group
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+Neither the name of the HSQL Development Group nor the names of its
+contributors may be used to endorse or promote products derived from this
+software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+For work originally developed by the Hypersonic SQL Group:
+
+Copyright (c) 1995-2000, The Hypersonic SQL Group.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+Neither the name of the Hypersonic SQL Group nor the names of its
+contributors may be used to endorse or promote products derived from this
+software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This software consists of voluntary contributions made by many individuals
+on behalf of the Hypersonic SQL Group.
+
+
+
+
+jTDS ${version.jtds} (drivers/jtds-${version.jtds}.jar)
+-----------------------------------
+Source: http://jtds.sourceforge.net/
+
+Copyright (C) 2004-2014 The jTDS Project
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ , 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+
+
+
+Java Native Access ${version.jna} (drivers/jna-${version.jna}.jar, drivers/jna-platform-${version.jna}.jar)
+--------------------------------------------------------------------------------
+Source: https://github.com/java-native-access/jna
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+
+
+
+MariaDB Java Client ${version.mariadb} (drivers/mariadb-java-client-${version.mariadb}.jar)
+-----------------------------------------------------------------
+Source: https://mariadb.com/kb/en/mariadb/client-libraries/mariadb-java-client/
+
+Copyright (c) 2012-2014 Monty Program Ab.
+
+This library is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the Free
+Software Foundation; either version 2.1 of the License, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this library; if not, write to Monty Program Ab info@montyprogram.com.
+
+This particular MariaDB Client for Java file is work
+derived from a Drizzle-JDBC. Drizzle-JDBC file which is covered by subject to
+the following copyright and notice provisions:
+
+Copyright (c) 2009-2011, Marcus Eriksson
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+Redistributions of source code must retain the above copyright notice, this list
+of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice, this
+list of conditions and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+
+Neither the name of the driver nor the names of its contributors may not be
+used to endorse or promote products derived from this software without specific
+prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+OF SUCH DAMAGE.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ , 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+
+
+
+MySQL Connector/J ${version.mysql} (drivers/mysql-connector-java-${version.mysql}.jar)
+-----------------------------------------------------------------
+Source: https://dev.mysql.com/downloads/connector/j/
+
+Introduction
+
+ This License Information User Manual contains Oracle's product license
+ and other licensing information, including licensing information for
+ third-party software which may be included in this distribution of
+ MySQL Connector/J 8.0.
+
+ Last updated: June 2018.
+
+Licensing Information
+
+ This is a release of MySQL Connector/J 8.0, brought to you by the MySQL
+ team at Oracle. This software is released under version 2 of the GNU
+ General Public License (GPLv2), as set forth below, with the following
+ additional permissions:
+
+ This distribution of MySQL Connector/J 8.0 is distributed with certain
+ software that is licensed under separate terms, as designated in a
+ particular file or component or in the license documentation. Without
+ limiting your rights under the GPLv2, the authors of MySQL hereby grant
+ you an additional permission to link the program and your derivative
+ works with the separately licensed software that they have included
+ with the program.
+
+ Without limiting the foregoing grant of rights under the GPLv2 and
+ additional permission as to separately licensed software, this
+ Connector is also subject to the Universal FOSS Exception, version 1.0,
+ a copy of which is reproduced below and can also be found along with
+ its FAQ at http://oss.oracle.com/licenses/universal-foss-exception.
+
+ Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights
+ reserved.
+
+Election of GPLv2
+
+ For the avoidance of doubt, except that if any license choice other
+ than GPL or LGPL is available it will apply instead, Oracle elects to
+ use only the General Public License version 2 (GPLv2) at this time for
+ any software where a choice of GPL license versions is made available
+ with the language indicating that GPLv2 or any later version may be
+ used, or where a choice of which version of the GPL is applied is
+ otherwise unspecified.
+
+GNU General Public License Version 2.0, June 1991
+
+The following applies to all products licensed under the GNU General
+Public License, Version 2.0: You may not use the identified files
+except in compliance with the GNU General Public License, Version
+2.0 (the "License.") You may obtain a copy of the License at
+http://www.gnu.org/licenses/gpl-2.0.txt. A copy of the license is
+also reproduced below. Unless required by applicable law or agreed
+to in writing, software distributed under the License is distributed
+on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+either express or implied. See the License for the specific language
+governing permissions and limitations under the License.
+
+GNU GENERAL PUBLIC LICENSE
+Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+Everyone is permitted to copy and distribute verbatim
+copies of this license document, but changing it is not
+allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software,
+and (2) offer you this license which gives you legal permission to
+copy, distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on,
+we want its recipients to know that what they have is not the original,
+so that any problems introduced by others will not reflect on the
+original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software
+ interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as
+a special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+
+ 9. The Free Software Foundation may publish revised and/or new
+versions of the General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Program does not specify a
+version number of this License, you may choose any version ever
+published by the Free Software Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the
+author to ask for permission. For software which is copyrighted by the
+Free Software Foundation, write to the Free Software Foundation; we
+sometimes make exceptions for this. Our decision will be guided by the
+two goals of preserving the free status of all derivatives of our free
+software and of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND,
+EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS
+WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
+ type 'show w'. This is free software, and you are welcome
+ to redistribute it under certain conditions; type 'show c'
+ for details.
+
+The hypothetical commands 'show w' and 'show c' should show the
+appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than 'show w' and
+'show c'; they could even be mouse-clicks or menu items--whatever
+suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ program 'Gnomovision' (which makes passes at compilers) written
+ by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library,
+you may consider it more useful to permit linking proprietary
+applications with the library. If this is what you want to do, use
+the GNU Lesser General Public License instead of this License.
+
+The Universal FOSS Exception, Version 1.0
+
+ In addition to the rights set forth in the other license(s) included in
+ the distribution for this software, data, and/or documentation
+ (collectively the "Software", and such licenses collectively with this
+ additional permission the "Software License"), the copyright holders
+ wish to facilitate interoperability with other software, data, and/or
+ documentation distributed with complete corresponding source under a
+ license that is OSI-approved and/or categorized by the FSF as free
+ (collectively "Other FOSS"). We therefore hereby grant the following
+ additional permission with respect to the use and distribution of the
+ Software with Other FOSS, and the constants, function signatures, data
+ structures and other invocation methods used to run or interact with
+ each of them (as to each, such software's "Interfaces"):
+ i. The Software's Interfaces may, to the extent permitted by the
+ license of the Other FOSS, be copied into, used and distributed in
+ the Other FOSS in order to enable interoperability, without
+ requiring a change to the license of the Other FOSS other than as
+ to any Interfaces of the Software embedded therein. The Software's
+ Interfaces remain at all times under the Software License,
+ including without limitation as used in the Other FOSS (which upon
+ any such use also then contains a portion of the Software under the
+ Software License).
+ ii. The Other FOSS's Interfaces may, to the extent permitted by the
+ license of the Other FOSS, be copied into, used and distributed in
+ the Software in order to enable interoperability, without requiring
+ that such Interfaces be licensed under the terms of the Software
+ License or otherwise altering their original terms, if this does
+ not require any portion of the Software other than such Interfaces
+ to be licensed under the terms other than the Software License.
+ iii. If only Interfaces and no other code is copied between the
+ Software and the Other FOSS in either direction, the use and/or
+ distribution of the Software with the Other FOSS shall not be
+ deemed to require that the Other FOSS be licensed under the license
+ of the Software, other than as to any Interfaces of the Software
+ copied into the Other FOSS. This includes, by way of example and
+ without limitation, statically or dynamically linking the Software
+ together with Other FOSS after enabling interoperability using the
+ Interfaces of one or both, and distributing the resulting
+ combination under different licenses for the respective portions
+ thereof. For avoidance of doubt, a license which is OSI-approved or
+ categorized by the FSF as free, includes, for the purpose of this
+ permission, such licenses with additional permissions, and any
+ license that has previously been so approved or categorized as
+ free, even if now deprecated or otherwise no longer recognized as
+ approved or free. Nothing in this additional permission grants any
+ right to distribute any portion of the Software on terms other than
+ those of the Software License or grants any additional permission
+ of any kind for use or distribution of the Software in conjunction
+ with software other than Other FOSS.
+
+Licenses for Third-Party Components
+
+ The following sections contain licensing information for libraries that
+ we have included with the MySQL Connector/J 8.0 source and components
+ used to test MySQL Connector/J 8.0. Commonly used licenses referenced
+ herein can be found in Commonly Used Licenses. We are thankful to all
+ individuals that have created these.
+
+Ant-Contrib
+
+ The following software may be included in this product:
+Ant-Contrib
+Copyright (c) 2001-2003 Ant-Contrib project. All rights reserved.
+Licensed under the Apache 1.1 License Agreement, a copy of which is reproduced b
+elow.
+
+The Apache Software License, Version 1.1
+
+Copyright (c) 2001-2003 Ant-Contrib project. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+
+ 3. The end-user documentation included with the redistribution, if
+ any, must include the following acknowlegement:
+ "This product includes software developed by the
+ Ant-Contrib project (http://sourceforge.net/projects/ant-contrib)."
+ Alternately, this acknowlegement may appear in the software itself,
+ if and wherever such third-party acknowlegements normally appear.
+
+
+ 4. The name Ant-Contrib must not be used to endorse or promote
+ products derived from this software without prior written
+ permission. For written permission, please contact
+ ant-contrib-developers@lists.sourceforge.net.
+
+
+ 5. Products derived from this software may not be called "Ant-Contrib"
+ nor may "Ant-Contrib" appear in their names without prior written
+ permission of the Ant-Contrib project.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE ANT-CONTRIB PROJECT OR ITS
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+c3p0 JDBC Library
+
+ You are receiving a copy of c3p0-0.9.1-pre6.jar in both source and
+ object code in the following /src/lib/c3p0-0.9.1-pre6.jar. The terms of
+ the Oracle license do NOT apply to c3p0-0.9.1-pre6.jar; it is licensed
+ under the following license, separately from the Oracle programs you
+ receive. If you do not wish to install this library, you may remove the
+ file /src/lib/c3p0-0.9.1-pre6.jar, but the Oracle program might not
+ operate properly or at all without the library.
+
+ This component is licensed under GNU Lesser General Public License
+ Version 2.1, February 1999.
+
+Google Protocol Buffers
+
+ The following software may be included in this product:
+Protocol Buffers (aka Google protobuf)
+
+Google Protocol Buffers - protobuf
+Copyright 2008, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms,
+with or without modification, are permitted provided
+that the following conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+* Redistributions in binary form must reproduce the
+ above copyright notice, this list of conditions and
+ the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+* Neither the name of Google Inc. nor the names of its
+ contributors may be used to endorse or promote products
+ derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Code generated by the Protocol Buffer compiler is owned by
+the owner of the input file used when generating it. This
+code is not standalone and requires a support library to be
+linked with it. This support library is itself covered by
+the above license.
+
+jboss-common-jdbc-wrapper.jar
+
+ You are receiving a copy of jboss-common-jdbc-wrapper.jar in both
+ source and object code in the following
+ /src/lib/jboss-common-jdbc-wrapper.jar. The terms of the Oracle license
+ do NOT apply to jboss-common-jdbc-wrapper.jar; it is licensed under the
+ following license, separately from the Oracle programs you receive. If
+ you do not wish to install this library, you may remove the file
+ /src/lib/jboss-common-jdbc-wrapper.jar, but the Oracle program might
+ not operate properly or at all without the library.
+
+ This component is licensed under GNU Lesser General Public License
+ Version 2.1, February 1999.
+
+NanoXML
+
+ The following software may be included in this product:
+
+ NanoXML
+
+ * Copyright (C) 2000-2002 Marc De Scheemaecker, All Rights Reserved.
+ *
+
+ * This software is provided 'as-is', without any express or implied warranty.
+
+ * In no event will the authors be held liable for any damages arising from the
+
+ * use of this software.
+ *
+
+ * Permission is granted to anyone to use this software for any purpose,
+
+ * including commercial applications, and to alter it and redistribute it
+
+ * freely, subject to the following restrictions:
+ *
+
+ * 1. The origin of this software must not be misrepresented; you must not
+
+ * claim that you wrote the original software. If you use this software in
+
+ * a product, an acknowledgment in the product documentation would be
+
+ * appreciated but is not required.
+ *
+
+ * 2. Altered source versions must be plainly marked as such, and must not be
+
+ * misrepresented as being the original software.
+ *
+
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+
+rox.jar
+
+ The following software may be included in this product:
+
+ rox.jar
+Copyright (c) 2006, James Greenfield
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+
+ * Redistributions of source code must retain the above copyright notice, thi
+s
+ list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of the nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIE
+D
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVI
+CES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Simple Logging Facade for Java (SLF4J)
+
+ The following software may be included in this product:
+Simple Logging Facade for Java (SLF4J)
+
+Copyright (c) 2004-2008 QOS.ch
+All rights reserved.
+
+Permission is hereby granted, free of charge,
+to any person obtaining a copy of this software
+and associated documentation files (the "Software"),
+to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify,
+merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the
+following conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY
+OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
+EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+OR OTHER DEALINGS IN THE SOFTWARE.
+
+Unicode Data Files
+
+ The following software may be included in this product:
+
+ Unicode Data Files
+COPYRIGHT AND PERMISSION NOTICE
+
+Copyright (c) 1991-2014 Unicode, Inc. All rights reserved. Distributed under
+the Terms of Use in http://www.unicode.org/copyright.html.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of the Unicode data files and any associated documentation (the "Data Files")
+or Unicode software and any associated documentation (the "Software") to deal
+in the Data Files or Software without restriction, including without
+limitation the rights to use, copy, modify, merge, publish, distribute,
+and/or sell copies of the Data Files or Software, and to permit persons to
+whom the Data Files or Software are furnished to do so, provided that (a) the
+above copyright notice(s) and this permission notice appear with all copies
+of the Data Files or Software, (b) both the above copyright notice(s) and
+this permission notice appear in associated documentation, and (c) there is
+clear notice in each modified Data File or in the Software as well as in the
+documentation associated with the Data File(s) or Software that the data or
+software has been modified.
+
+THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
+INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR
+CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE
+DATA FILES OR SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder shall not
+be used in advertising or otherwise to promote the sale, use or other
+dealings in these Data Files or Software without prior written authorization
+of the copyright holder.
+
+Commonly Used Licenses
+
+Artistic License (Perl) 1.0
+
+The "Artistic License"
+
+Preamble
+
+The intent of this document is to state the conditions under which a
+Package may be copied, such that the Copyright Holder maintains some
+semblance of artistic control over the development of the package,
+while giving the users of the package the right to use and distribute
+the Package in a more-or-less customary fashion, plus the right to make
+reasonable modifications.
+
+Definitions:
+
+ "Package" refers to the collection of files distributed by the
+ Copyright Holder, and derivatives of that collection of files
+ created through textual modification.
+
+ "Standard Version" refers to such a Package if it has not been
+ modified, or has been modified in accordance with the wishes
+ of the Copyright Holder as specified below.
+
+ "Copyright Holder" is whoever is named in the copyright or
+ copyrights for the package.
+
+ "You" is you, if you're thinking about copying or distributing
+ this Package.
+
+ "Reasonable copying fee" is whatever you can justify on the
+ basis of media cost, duplication charges, time of people involved,
+ and so on. (You will not be required to justify it to the
+ Copyright Holder, but only to the computing community at large
+ as a market that must bear the fee.)
+
+ "Freely Available" means that no fee is charged for the item
+ itself, though there may be fees involved in handling the item.
+ It also means that recipients of the item may redistribute it
+ under the same conditions they received it.
+
+1. You may make and give away verbatim copies of the source form of the
+Standard Version of this Package without restriction, provided that you
+duplicate all of the original copyright notices and associated disclaimers.
+
+2. You may apply bug fixes, portability fixes and other modifications
+derived from the Public Domain or from the Copyright Holder. A Package
+modified in such a way shall still be considered the Standard Version.
+
+3. You may otherwise modify your copy of this Package in any way, provided
+that you insert a prominent notice in each changed file stating how and
+when you changed that file, and provided that you do at least ONE of the
+following:
+
+ a) place your modifications in the Public Domain or otherwise make them
+ Freely Available, such as by posting said modifications to Usenet or
+ an equivalent medium, or placing the modifications on a major archive
+ site such as uunet.uu.net, or by allowing the Copyright Holder to include
+ your modifications in the Standard Version of the Package.
+
+ b) use the modified Package only within your corporation or organization.
+
+ c) rename any non-standard executables so the names do not conflict
+ with standard executables, which must also be provided, and provide
+ a separate manual page for each non-standard executable that clearly
+ documents how it differs from the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+4. You may distribute the programs of this Package in object code or
+executable form, provided that you do at least ONE of the following:
+
+ a) distribute a Standard Version of the executables and library files,
+ together with instructions (in the manual page or equivalent) on where
+ to get the Standard Version.
+
+ b) accompany the distribution with the machine-readable source of
+ the Package with your modifications.
+
+ c) give non-standard executables non-standard names, and clearly
+ document the differences in manual pages (or equivalent), together
+ with instructions on where to get the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+5. You may charge a reasonable copying fee for any distribution of this
+Package. You may charge any fee you choose for support of this
+Package. You may not charge a fee for this Package itself. However,
+you may distribute this Package in aggregate with other (possibly
+commercial) programs as part of a larger (possibly commercial) software
+distribution provided that you do not advertise this Package as a
+product of your own. You may embed this Package's interpreter within
+an executable of yours (by linking); this shall be construed as a mere
+form of aggregation, provided that the complete Standard Version of the
+interpreter is so embedded.
+
+6. The scripts and library files supplied as input to or produced as
+output from the programs of this Package do not automatically fall
+under the copyright of this Package, but belong to whoever generated
+them, and may be sold commercially, and may be aggregated with this
+Package. If such scripts or library files are aggregated with this
+Package via the so-called "undump" or "unexec" methods of producing a
+binary executable image, then distribution of such an image shall
+neither be construed as a distribution of this Package nor shall it
+fall under the restrictions of Paragraphs 3 and 4, provided that you do
+not represent such an executable image as a Standard Version of this
+Package.
+
+7. C subroutines (or comparably compiled subroutines in other
+languages) supplied by you and linked into this Package in order to
+emulate subroutines and variables of the language defined by this
+Package shall not be considered part of this Package, but are the
+equivalent of input as in Paragraph 6, provided these subroutines do
+not change the language in any way that would cause it to fail the
+regression tests for the language.
+
+8. Aggregation of this Package with a commercial distribution is always
+permitted provided that the use of this Package is embedded; that is,
+when no overt attempt is made to make this Package's interfaces visible
+to the end user of the commercial distribution. Such use shall not be
+construed as a distribution of this Package.
+
+9. The name of the Copyright Holder may not be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+
+10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+ The End
+
+GNU Lesser General Public License Version 2.1, February 1999
+
+The following applies to all products licensed under the
+GNU Lesser General Public License, Version 2.1: You may
+not use the identified files except in compliance with
+the GNU Lesser General Public License, Version 2.1 (the
+"License"). You may obtain a copy of the License at
+http://www.gnu.org/licenses/lgpl-2.1.html. A copy of the
+license is also reproduced below. Unless required by
+applicable law or agreed to in writing, software distributed
+under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+or implied. See the License for the specific language governing
+permissions and limitations under the License.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes a de-facto standard. To achieve this, non-free programs
+must be allowed to use the library. A more frequent case is that
+a free library does the same job as widely used non-free libraries.
+In this case, there is little to gain by limiting the free library
+to free software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control
+compilation and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended
+to apply, and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms
+of the ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library.
+It is safest to attach them to the start of each source file to most
+effectively convey the exclusion of warranty; and each file should
+have at least the "copyright" line and a pointer to where the full
+notice is found.
+
+
+ Copyright (C)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James
+ Random Hacker.
+
+ , 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+GNU Lesser General Public License Version 2, June 1991
+
+GNU LIBRARY GENERAL PUBLIC LICENSE
+
+Version 2, June 1991
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is numbered 2
+because it goes with version 2 of the ordinary GPL.]
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to
+share and change it. By contrast, the GNU General Public Licenses are
+intended to guarantee your freedom to share and change free software--to make
+sure the software is free for all its users.
+
+This license, the Library General Public License, applies to some specially
+designated Free Software Foundation software, and to any other libraries
+whose authors decide to use it. You can use it for your libraries, too.
+
+When we speak of free software, we are referring to freedom, not price. Our
+General Public Licenses are designed to make sure that you have the freedom
+to distribute copies of free software (and charge for this service if you
+wish), that you receive source code or can get it if you want it, that you
+can change the software or use pieces of it in new free programs; and that
+you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to
+deny you these rights or to ask you to surrender the rights. These
+restrictions translate to certain responsibilities for you if you distribute
+copies of the library, or if you modify it.
+
+For example, if you distribute copies of the library, whether gratis or for a
+fee, you must give the recipients all the rights that we gave you. You must
+make sure that they, too, receive or can get the source code. If you link a
+program with the library, you must provide complete object files to the
+recipients so that they can relink them with the library, after making
+changes to the library and recompiling it. And you must show them these terms
+so they know their rights.
+
+Our method of protecting your rights has two steps: (1) copyright the
+library, and (2) offer you this license which gives you legal permission to
+copy, distribute and/or modify the library.
+
+Also, for each distributor's protection, we want to make certain that
+everyone understands that there is no warranty for this free library. If the
+library is modified by someone else and passed on, we want its recipients to
+know that what they have is not the original version, so that any problems
+introduced by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents. We
+wish to avoid the danger that companies distributing free software will
+individually obtain patent licenses, thus in effect transforming the program
+into proprietary software. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+Most GNU software, including some libraries, is covered by the ordinary GNU
+General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary one;
+be sure to read it in full, and don't assume that anything in it is the same
+as in the ordinary license.
+
+The reason we have a separate public license for some libraries is that they
+blur the distinction we usually make between modifying or adding to a program
+and simply using it. Linking a program with a library, without changing the
+library, is in some sense simply using the library, and is analogous to
+running a utility program or application program. However, in a textual and
+legal sense, the linked executable is a combined work, a derivative of the
+original library, and the ordinary General Public License treats it as such.
+
+Because of this blurred distinction, using the ordinary General Public
+License for libraries did not effectively promote software sharing, because
+most developers did not use the libraries. We concluded that weaker
+conditions might promote sharing better.
+
+However, unrestricted linking of non-free programs would deprive the users of
+those programs of all benefit from the free status of the libraries
+themselves. This Library General Public License is intended to permit
+developers of non-free programs to use free libraries, while preserving your
+freedom as a user of such programs to change the free libraries that are
+incorporated in them. (We have not seen how to achieve this as regards
+changes in header files, but we have achieved it as regards changes in the
+actual functions of the Library.) The hope is that this will lead to faster
+development of free libraries.
+
+The precise terms and conditions for copying, distribution and modification
+follow. Pay close attention to the difference between a "work based on the
+library" and a "work that uses the library". The former contains code derived
+from the library, while the latter only works together with the library.
+
+Note that it is possible for a library to be covered by the ordinary General
+Public License rather than by this special one.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License Agreement applies to any software library which contains a
+notice placed by the copyright holder or other authorized party saying it may
+be distributed under the terms of this Library General Public License (also
+called "this License"). Each licensee is addressed as "you".
+
+A "library" means a collection of software functions and/or data prepared so
+as to be conveniently linked with application programs (which use some of
+those functions and data) to form executables.
+
+The "Library", below, refers to any such software library or work which has
+been distributed under these terms. A "work based on the Library" means
+either the Library or any derivative work under copyright law: that is to
+say, a work containing the Library or a portion of it, either verbatim or
+with modifications and/or translated straightforwardly into another language.
+(Hereinafter, translation is included without limitation in the term
+"modification".)
+
+"Source code" for a work means the preferred form of the work for making
+modifications to it. For a library, complete source code means all the source
+code for all modules it contains, plus any associated interface definition
+files, plus the scripts used to control compilation and installation of the
+library.
+
+Activities other than copying, distribution and modification are not covered
+by this License; they are outside its scope. The act of running a program
+using the Library is not restricted, and output from such a program is
+covered only if its contents constitute a work based on the Library
+(independent of the use of the Library in a tool for writing it). Whether
+that is true depends on what the Library does and what the program that uses
+the Library does.
+
+1. You may copy and distribute verbatim copies of the Library's complete
+source code as you receive it, in any medium, provided that you conspicuously
+and appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this
+License and to the absence of any warranty; and distribute a copy of this
+License along with the Library.
+
+You may charge a fee for the physical act of transferring a copy, and you may
+at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Library or any portion of it,
+thus forming a work based on the Library, and copy and distribute such
+modifications or work under the terms of Section 1 above, provided that you
+also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+ b) You must cause the files modified to carry prominent notices stating
+that you changed the files and the date of any change.
+ c) You must cause the whole of the work to be licensed at no charge to
+all third parties under the terms of this License.
+ d) If a facility in the modified Library refers to a function or a table
+of data to be supplied by an application program that uses the facility,
+other than as an argument passed when the facility is invoked, then you must
+make a good faith effort to ensure that, in the event an application does not
+supply such function or table, the facility still operates, and performs
+whatever part of its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has a
+purpose that is entirely well-defined independent of the application.
+Therefore, Subsection 2d requires that any application-supplied function or
+table used by this function must be optional: if the application does not
+supply it, the square root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If identifiable
+sections of that work are not derived from the Library, and can be reasonably
+considered independent and separate works in themselves, then this License,
+and its terms, do not apply to those sections when you distribute them as
+separate works. But when you distribute the same sections as part of a whole
+which is a work based on the Library, the distribution of the whole must be
+on the terms of this License, whose permissions for other licensees extend to
+the entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise the
+right to control the distribution of derivative or collective works based on
+the Library.
+
+In addition, mere aggregation of another work not based on the Library with
+the Library (or with a work based on the Library) on a volume of a storage or
+distribution medium does not bring the other work under the scope of this
+License.
+
+3. You may opt to apply the terms of the ordinary GNU General Public License
+instead of this License to a given copy of the Library. To do this, you must
+alter all the notices that refer to this License, so that they refer to the
+ordinary GNU General Public License, version 2, instead of to this License.
+(If a newer version than version 2 of the ordinary GNU General Public License
+has appeared, then you can specify that version instead if you wish.) Do not
+make any other change in these notices.
+
+Once this change is made in a given copy, it is irreversible for that copy,
+so the ordinary GNU General Public License applies to all subsequent copies
+and derivative works made from that copy.
+
+This option is useful when you wish to copy part of the code of the Library
+into a program that is not a library.
+
+4. You may copy and distribute the Library (or a portion or derivative of it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you accompany it with the complete
+corresponding machine-readable source code, which must be distributed under
+the terms of Sections 1 and 2 above on a medium customarily used for software
+interchange.
+
+If distribution of object code is made by offering access to copy from a
+designated place, then offering equivalent access to copy the source code
+from the same place satisfies the requirement to distribute the source code,
+even though third parties are not compelled to copy the source along with the
+object code.
+
+5. A program that contains no derivative of any portion of the Library, but
+is designed to work with the Library by being compiled or linked with it, is
+called a "work that uses the Library". Such a work, in isolation, is not a
+derivative work of the Library, and therefore falls outside the scope of this
+License.
+
+However, linking a "work that uses the Library" with the Library creates an
+executable that is a derivative of the Library (because it contains portions
+of the Library), rather than a "work that uses the library". The executable
+is therefore covered by this License. Section 6 states terms for distribution
+of such executables.
+
+When a "work that uses the Library" uses material from a header file that is
+part of the Library, the object code for the work may be a derivative work of
+the Library even though the source code is not. Whether this is true is
+especially significant if the work can be linked without the Library, or if
+the work is itself a library. The threshold for this to be true is not
+precisely defined by law.
+
+If such an object file uses only numerical parameters, data structure layouts
+and accessors, and small macros and small inline functions (ten lines or less
+in length), then the use of the object file is unrestricted, regardless of
+whether it is legally a derivative work. (Executables containing this object
+code plus portions of the Library will still fall under Section 6.)
+
+Otherwise, if the work is a derivative of the Library, you may distribute the
+object code for the work under the terms of Section 6. Any executables
+containing that work also fall under Section 6, whether or not they are
+linked directly with the Library itself.
+
+6. As an exception to the Sections above, you may also compile or link a
+"work that uses the Library" with the Library to produce a work containing
+portions of the Library, and distribute that work under terms of your choice,
+provided that the terms permit modification of the work for the customer's
+own use and reverse engineering for debugging such modifications.
+
+You must give prominent notice with each copy of the work that the Library is
+used in it and that the Library and its use are covered by this License. You
+must supply a copy of this License. If the work during execution displays
+copyright notices, you must include the copyright notice for the Library
+among them, as well as a reference directing the user to the copy of this
+License. Also, you must do one of these things:
+
+ a) Accompany the work with the complete corresponding machine-readable
+source code for the Library including whatever changes were used in the work
+(which must be distributed under Sections 1 and 2 above); and, if the work is
+an executable linked with the Library, with the complete machine-readable
+"work that uses the Library", as object code and/or source code, so that the
+user can modify the Library and then relink to produce a modified executable
+containing the modified Library. (It is understood that the user who changes
+the contents of definitions files in the Library will not necessarily be able
+to recompile the application to use the modified definitions.)
+ b) Accompany the work with a written offer, valid for at least three
+years, to give the same user the materials specified in Subsection 6a, above,
+for a charge no more than the cost of performing this distribution.
+ c) If distribution of the work is made by offering access to copy from a
+designated place, offer equivalent access to copy the above specified
+materials from the same place.
+ d) Verify that the user has already received a copy of these materials or
+that you have already sent this user a copy.
+
+For an executable, the required form of the "work that uses the Library" must
+include any data and utility programs needed for reproducing the executable
+from it. However, as a special exception, the source code distributed need
+not include anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component itself
+accompanies the executable.
+
+It may happen that this requirement contradicts the license restrictions of
+other proprietary libraries that do not normally accompany the operating
+system. Such a contradiction means you cannot use both them and the Library
+together in an executable that you distribute.
+
+7. You may place library facilities that are a work based on the Library
+side-by-side in a single library together with other library facilities not
+covered by this License, and distribute such a combined library, provided
+that the separate distribution of the work based on the Library and of the
+other library facilities is otherwise permitted, and provided that you do
+these two things:
+
+ a) Accompany the combined library with a copy of the same work based on
+the Library, uncombined with any other library facilities. This must be
+distributed under the terms of the Sections above.
+ b) Give prominent notice with the combined library of the fact that part
+of it is a work based on the Library, and explaining where to find the
+accompanying uncombined form of the same work.
+
+8. You may not copy, modify, sublicense, link with, or distribute the Library
+except as expressly provided under this License. Any attempt otherwise to
+copy, modify, sublicense, link with, or distribute the Library is void, and
+will automatically terminate your rights under this License. However, parties
+who have received copies, or rights, from you under this License will not
+have their licenses terminated so long as such parties remain in full
+compliance.
+
+9. You are not required to accept this License, since you have not signed it.
+However, nothing else grants you permission to modify or distribute the
+Library or its derivative works. These actions are prohibited by law if you
+do not accept this License. Therefore, by modifying or distributing the
+Library (or any work based on the Library), you indicate your acceptance of
+this License to do so, and all its terms and conditions for copying,
+distributing or modifying the Library or works based on it.
+
+10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the original
+licensor to copy, distribute, link with or modify the Library subject to
+these terms and conditions. You may not impose any further restrictions on
+the recipients' exercise of the rights granted herein. You are not
+responsible for enforcing compliance by third parties to this License.
+
+11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not excuse
+you from the conditions of this License. If you cannot distribute so as to
+satisfy simultaneously your obligations under this License and any other
+pertinent obligations, then as a consequence you may not distribute the
+Library at all. For example, if a patent license would not permit
+royalty-free redistribution of the Library by all those who receive copies
+directly or indirectly through you, then the only way you could satisfy both
+it and this License would be to refrain entirely from distribution of the
+Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply, and
+the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents
+or other property right claims or to contest validity of any such claims;
+this section has the sole purpose of protecting the integrity of the free
+software distribution system which is implemented by public license
+practices. Many people have made generous contributions to the wide range of
+software distributed through that system in reliance on consistent
+application of that system; it is up to the author/donor to decide if he or
+she is willing to distribute software through any other system and a licensee
+cannot impose that choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+12. If the distribution and/or use of the Library is restricted in certain
+countries either by patents or by copyrighted interfaces, the original
+copyright holder who places the Library under this License may add an
+explicit geographical distribution limitation excluding those countries, so
+that distribution is permitted only in or among countries not thus excluded.
+In such case, this License incorporates the limitation as if written in the
+body of this License.
+
+13. The Free Software Foundation may publish revised and/or new versions of
+the Library General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and "any later
+version", you have the option of following the terms and conditions either of
+that version or of any later version published by the Free Software
+Foundation. If the Library does not specify a license version number, you may
+choose any version ever published by the Free Software Foundation.
+
+14. If you wish to incorporate parts of the Library into other free programs
+whose distribution conditions are incompatible with these, write to the
+author to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes make
+exceptions for this. Our decision will be guided by the two goals of
+preserving the free status of all derivatives of our free software and of
+promoting the sharing and reuse of software generally.
+
+NO WARRANTY
+
+15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
+LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
+PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE,
+YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO
+LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR
+THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER
+SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+END OF TERMS AND CONDITIONS
+How to Apply These Terms to Your New Libraries
+
+If you develop a new library, and you want it to be of the greatest possible
+use to the public, we recommend making it free software that everyone can
+redistribute and change. You can do so by permitting redistribution under
+these terms (or, alternatively, under the terms of the ordinary General
+Public License).
+
+To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+one line to give the library's name and an idea of what it does.
+Copyright (C) year name of author
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the
+Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+Boston, MA 02110-1301, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+Yoyodyne, Inc., hereby disclaims all copyright interest in
+the library `Frob' (a library for tweaking knobs) written
+by James Random Hacker.
+
+signature of Ty Coon, 1 April 1990
+Ty Coon, President of Vice
+
+That's all there is to it!
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Written Offer for Source Code
+
+ For any software that you receive from Oracle in binary form which is
+ licensed under an open source license that gives you the right to
+ receive the source code for that binary, you can obtain a copy of the
+ applicable source code by visiting
+ http://www.oracle.com/goto/opensourcecode. If the source code for the
+ binary was not provided to you with the binary, you can also receive a
+ copy of the source code on physical media by submitting a written
+ request to the address listed below or by sending an email to Oracle
+ using the following link:
+ http://www.oracle.com/goto/opensourcecode/request.
+ Oracle America, Inc.
+ Attn: Senior Vice President
+ Development and Engineering Legal
+ 500 Oracle Parkway, 10th Floor
+ Redwood Shores, CA 94065
+
+ Your request should include:
+
+ * The name of the binary for which you are requesting the source code
+
+ * The name and version number of the Oracle product containing the
+ binary
+
+ * The date you received the Oracle product
+
+ * Your name
+
+ * Your company name (if applicable)
+
+ * Your return mailing address and email, and
+
+ * A telephone number in the event we need to reach you.
+
+ We may charge you a fee to cover the cost of physical media and
+ processing.
+
+ Your request must be sent
+ a. within three (3) years of the date you received the Oracle product
+ that included the binary that is the subject of your request, or
+ b. in the case of code licensed under the GPL v3 for as long as Oracle
+ offers spare parts or customer support for that product model.
+
+
+
+
+
+
+
+PostgreSQL JDBC Driver ${version.postgresql} (drivers/postgresql-${version.postgresql}.jar)
+-----------------------------------------------------------------------------
+Source: https://github.com/pgjdbc/pgjdbc
+
+Copyright (c) 1997-2014, PostgreSQL Global Development Group
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+3. Neither the name of the PostgreSQL Global Development Group nor the names
+ of its contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+
+Snowflake JDBC ${version.snowflake} (drivers/snowflake-jdbc-${version.snowflake}.jar)
+------------------------------------------------------------------
+Source: hhttps://github.com/snowflakedb/snowflake-jdbc/blob/master/LICENSE.txt
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright (c) 2013-2018 Snowflake Computing, Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
+
+SQLite JDBC Driver ${version.sqlite} (drivers/sqlite-jdbc-${version.sqlite}.jar)
+----------------------------------------------------------------
+Source: https://bitbucket.org/xerial/sqlite-jdbc
+
+Copyright 2014 Taro L. Saito
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Copyright (c) 2006, David Crawshaw. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+
+
+Microsoft SQL Server JDBC Driver ${version.mssql-jdbc} (drivers/mssql-jdbc-${version.mssql-jdbc}.jar)
+-----------------------------------------------------------------------------
+Source: https://github.com/Microsoft/mssql-jdbc
+
+Copyright(c) 2017 Microsoft Corporation
+All rights reserved.
+
+MIT License
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"),
+to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+
+
+Jansi ${version.jansi} (lib/jansi-${version.jansi}.jar)
+----------------------------------------------------------------
+Source: https://github.com/fusesource/jansi
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+Gson ${version.gson} (lib/gson-${version.gson}.jar)
+----------------------------------------------------------------
+Source: https://raw.githubusercontent.com/google/gson/master/LICENSE
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
\ No newline at end of file
diff --git b/flyway-commandline/src/main/assembly/README.txt a/flyway-commandline/src/main/assembly/README.txt
new file mode 100644
index 0000000..b4258a6
--- /dev/null
+++ a/flyway-commandline/src/main/assembly/README.txt
@@ -0,0 +1,25 @@
+Welcome to Flyway
+-----------------
+Database Migrations Made Easy
+
+
+Documentation
+-------------
+You can find getting started guides and reference documentation at https://flywaydb.org
+
+
+Contributing
+------------
+Here is the info on how you can contribute in various ways to the project: https://flywaydb.org/documentation/contribute/
+
+
+License
+-------
+Copyright (C) 2010-2020 Boxfuse GmbH
+
+Flyway Community Edition : https://flywaydb.org/licenses/flyway-community
+Flyway 30 day limited trial : https://flywaydb.org/licenses/flyway-trial
+Flyway Pro Edition : https://flywaydb.org/licenses/flyway-pro
+Flyway Enterprise Edition : https://flywaydb.org/licenses/flyway-enterprise
+
+Flyway is a registered trademark of Boxfuse GmbH.
\ No newline at end of file
diff --git b/flyway-commandline/src/main/assembly/component.xml a/flyway-commandline/src/main/assembly/component.xml
new file mode 100644
index 0000000..ac3baec
--- /dev/null
+++ a/flyway-commandline/src/main/assembly/component.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ src/main/assembly
+
+
+ flyway.cmd
+
+ 644
+ true
+
+
+ src/main/assembly
+
+
+ flyway
+
+ 744
+ unix
+ true
+
+
+ src/main/assembly
+ drivers
+
+ put-your-jdbc-drivers-here.txt
+
+ 644
+
+
+ src/main/assembly
+ conf
+
+ flyway.conf
+
+ 644
+
+
+ src/main/assembly
+ sql
+
+ put-your-sql-migrations-here.txt
+
+ 644
+
+
+ src/main/assembly
+ jars
+
+ put-your-java-migration-jars-here.txt
+
+ 644
+
+
+ src/main/assembly
+ licenses
+
+ flyway-community.txt
+ LICENSES-THIRD-PARTY.txt
+
+ flyway-pro.txt
+ flyway-enterprise.txt
+
+
+ 644
+ true
+
+
+ src/main/assembly
+
+
+ README.txt
+
+ 644
+
+
+
+ target/editions/pro
+ lib/pro
+
+ *
+
+ 644
+
+
+ target/editions/enterprise
+ lib/enterprise
+
+ *
+
+ 644
+
+
+
+
+
+ lib
+
+ false
+
+ org.fusesource.jansi:jansi
+ com.google.code.gson:gson
+
+
+
+ lib/community
+
+ false
+
+ org.flywaydb:flyway-core
+ org.flywaydb:flyway-commandline
+
+
+
+ drivers
+
+ false
+
+ *
+
+
+ org.flywaydb:flyway-*
+ org.fusesource.jansi:jansi
+ com.google.code.gson:gson
+
+
+
+
\ No newline at end of file
diff --git b/flyway-commandline/src/main/assembly/flyway a/flyway-commandline/src/main/assembly/flyway
new file mode 100644
index 0000000..51c1d10
--- /dev/null
+++ a/flyway-commandline/src/main/assembly/flyway
@@ -0,0 +1,75 @@
+#!/usr/bin/env bash
+#
+# Copyright 2010-2020 Boxfuse GmbH
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Detect Linux
+linux=false
+ case "`uname`" in
+ Linux*) linux=true;;
+ esac
+
+# Dereference softlinks
+THIS="$0"
+ while [ -h "$THIS" ] ; do
+ ls=`ls -ld "$THIS"`
+ softlink=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$softlink" : '/.*' > /dev/null; then THIS="$softlink"; else THIS=`dirname "$THIS"`/"$softlink"; fi
+ done
+# Detect the installation directory
+INSTALLDIR=`dirname "$THIS"`
+
+if [ -x "$INSTALLDIR/jre/bin/java" ]; then
+ JAVA_CMD=$INSTALLDIR/jre/bin/java
+else
+ # Use JAVA_HOME if it is set
+ if [ -z "$JAVA_HOME" ]; then JAVA_CMD=java; else JAVA_CMD=$JAVA_HOME/bin/java; fi
+fi
+
+# Determine Flyway edition to use
+POSITIONAL=()
+while [[ $# -gt 0 ]]; do
+ POSITIONAL+=("$1")
+ flag="$1"
+ case $flag in
+ -community)
+ FLYWAY_EDITION=community
+ ;;
+ -pro)
+ FLYWAY_EDITION=pro
+ ;;
+ -enterprise)
+ FLYWAY_EDITION=enterprise
+ ;;
+ esac
+ shift
+done
+set -- "${POSITIONAL[@]}"
+if [ -z "$FLYWAY_EDITION" ]; then
+ FLYWAY_EDITION=community
+fi
+
+CP="$INSTALLDIR/lib/*:$INSTALLDIR/lib/$FLYWAY_EDITION/*:$INSTALLDIR/drivers/*"
+
+EXTRA_ARGS=
+if $linux; then
+ EXTRA_ARGS=-Djava.security.egd=file:/dev/../dev/urandom
+fi
+
+if `command -v cygpath > /dev/null`; then CP=`cygpath -pw "$CP"`; fi
+"$JAVA_CMD" $JAVA_ARGS $EXTRA_ARGS -cp "$CP" org.flywaydb.commandline.Main "$@"
+
+# Exit using the same code returned from Java
+exit $?
\ No newline at end of file
diff --git b/flyway-commandline/src/main/assembly/flyway-community.txt a/flyway-commandline/src/main/assembly/flyway-community.txt
new file mode 100644
index 0000000..cec23e4
--- /dev/null
+++ a/flyway-commandline/src/main/assembly/flyway-community.txt
@@ -0,0 +1,191 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright
+owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities
+that control, are controlled by, or are under common control with that entity.
+For the purposes of this definition, "control" means (i) the power, direct or
+indirect, to cause the direction or management of such entity, whether by
+contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
+outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising
+permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including
+but not limited to software source code, documentation source, and configuration
+files.
+
+"Object" form shall mean any form resulting from mechanical transformation or
+translation of a Source form, including but not limited to compiled object code,
+generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made
+available under the License, as indicated by a copyright notice that is included
+in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that
+is based on (or derived from) the Work and for which the editorial revisions,
+annotations, elaborations, or other modifications represent, as a whole, an
+original work of authorship. For the purposes of this License, Derivative Works
+shall not include works that remain separable from, or merely link (or bind by
+name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version
+of the Work and any modifications or additions to that Work or Derivative Works
+thereof, that is intentionally submitted to Licensor for inclusion in the Work
+by the copyright owner or by an individual or Legal Entity authorized to submit
+on behalf of the copyright owner. For the purposes of this definition,
+"submitted" means any form of electronic, verbal, or written communication sent
+to the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control systems, and
+issue tracking systems that are managed by, or on behalf of, the Licensor for
+the purpose of discussing and improving the Work, but excluding communication
+that is conspicuously marked or otherwise designated in writing by the copyright
+owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
+of whom a Contribution has been received by Licensor and subsequently
+incorporated within the Work.
+
+2. Grant of Copyright License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the Work and such
+Derivative Works in Source or Object form.
+
+3. Grant of Patent License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable (except as stated in this section) patent license to make, have
+made, use, offer to sell, sell, import, and otherwise transfer the Work, where
+such license applies only to those patent claims licensable by such Contributor
+that are necessarily infringed by their Contribution(s) alone or by combination
+of their Contribution(s) with the Work to which such Contribution(s) was
+submitted. If You institute patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Work or a
+Contribution incorporated within the Work constitutes direct or contributory
+patent infringement, then any patent licenses granted to You under this License
+for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution.
+
+You may reproduce and distribute copies of the Work or Derivative Works thereof
+in any medium, with or without modifications, and in Source or Object form,
+provided that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of
+this License; and
+You must cause any modified files to carry prominent notices stating that You
+changed the files; and
+You must retain, in the Source form of any Derivative Works that You distribute,
+all copyright, patent, trademark, and attribution notices from the Source form
+of the Work, excluding those notices that do not pertain to any part of the
+Derivative Works; and
+If the Work includes a "NOTICE" text file as part of its distribution, then any
+Derivative Works that You distribute must include a readable copy of the
+attribution notices contained within such NOTICE file, excluding those notices
+that do not pertain to any part of the Derivative Works, in at least one of the
+following places: within a NOTICE text file distributed as part of the
+Derivative Works; within the Source form or documentation, if provided along
+with the Derivative Works; or, within a display generated by the Derivative
+Works, if and wherever such third-party notices normally appear. The contents of
+the NOTICE file are for informational purposes only and do not modify the
+License. You may add Your own attribution notices within Derivative Works that
+You distribute, alongside or as an addendum to the NOTICE text from the Work,
+provided that such additional attribution notices cannot be construed as
+modifying the License.
+You may add Your own copyright statement to Your modifications and may provide
+additional or different license terms and conditions for use, reproduction, or
+distribution of Your modifications, or for any such Derivative Works as a whole,
+provided Your use, reproduction, and distribution of the Work otherwise complies
+with the conditions stated in this License.
+
+5. Submission of Contributions.
+
+Unless You explicitly state otherwise, any Contribution intentionally submitted
+for inclusion in the Work by You to the Licensor shall be under the terms and
+conditions of this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify the terms of
+any separate license agreement you may have executed with Licensor regarding
+such Contributions.
+
+6. Trademarks.
+
+This License does not grant permission to use the trade names, trademarks,
+service marks, or product names of the Licensor, except as required for
+reasonable and customary use in describing the origin of the Work and
+reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty.
+
+Unless required by applicable law or agreed to in writing, Licensor provides the
+Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+including, without limitation, any warranties or conditions of TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
+solely responsible for determining the appropriateness of using or
+redistributing the Work and assume any risks associated with Your exercise of
+permissions under this License.
+
+8. Limitation of Liability.
+
+In no event and under no legal theory, whether in tort (including negligence),
+contract, or otherwise, unless required by applicable law (such as deliberate
+and grossly negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License or
+out of the use or inability to use the Work (including but not limited to
+damages for loss of goodwill, work stoppage, computer failure or malfunction, or
+any and all other commercial damages or losses), even if such Contributor has
+been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability.
+
+While redistributing the Work or Derivative Works thereof, You may choose to
+offer, and charge a fee for, acceptance of support, warranty, indemnity, or
+other liability obligations and/or rights consistent with this License. However,
+in accepting such obligations, You may act only on Your own behalf and on Your
+sole responsibility, not on behalf of any other Contributor, and only if You
+agree to indemnify, defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason of your
+accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work
+
+To apply the Apache License to your work, attach the following boilerplate
+notice, with the fields enclosed by brackets "[]" replaced with your own
+identifying information. (Don't include the brackets!) The text should be
+enclosed in the appropriate comment syntax for the file format. We also
+recommend that a file or class name and description of purpose be included on
+the same "printed page" as the copyright notice for easier identification within
+third-party archives.
+
+ Copyright 2010-2017 Boxfuse GmbH
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git b/flyway-commandline/src/main/assembly/flyway-enterprise.txt a/flyway-commandline/src/main/assembly/flyway-enterprise.txt
new file mode 100644
index 0000000..fdf2602
--- /dev/null
+++ a/flyway-commandline/src/main/assembly/flyway-enterprise.txt
@@ -0,0 +1,135 @@
+Flyway Enterprise Edition License and Support Agreement
+=======================================================
+
+Any use of the Flyway Enterprise Edition software is subject to the terms of this license agreement (“Agreement”). Please read the full Agreement carefully. This License and Support Agreement relates to purchases of the Flyway Enterprise Edition Software made on or after 2nd August 2019.
+
+This Agreement sets out the conditions under which and the extent to which the end user (referred to as “Licensee” below) is granted the right to use the “Flyway Enterprise Edition” software (referred to as “Software” below) provided by : Boxfuse GmbH, Scwedenstr. 9/Gebäude 1, 13359 Berlin, Germany (referred to as “Licensor” below).
+
+The Licensee confirms that it accepts and agrees to be legally bound by all terms and conditions of this Agreement by downloading and/or installing and/or using the Software. If you do not accept these terms, do not download, install or use the Software.
+
+IMPORTANT NOTICES:
+(i) A copy of Agreement will be sent with your Boxfuse GmbH invoice;
+(ii) Where you sign a paper version or a bespoke version of this Agreement, that paper/bespoke version will take precedence over any subsequent Agreements that were sent with your invoice; and
+(iii) This Agreement shall prevail over your standard terms and conditions (if any) attached to, enclosed with, or referred to in, any purchase order or confirmation of order.
+
+1. Grant of rights
+------------------
+
+1.1 Evaluation. Licensee is entitled to a 30 day free trial of the Software for the purposes of deciding whether or not the Software meets Licensee’s requirement. (“Evaluation Period”) During the Evaluation Period the following terms apply:
+ 1.1.1 During the Evaluation Period, Licensee hereby agrees that the Software is provided AS IS with no representation, guarantee or warranty of any kind as to its functionality, quality, performance, suitability or fitness for purpose. All other terms, conditions, representations and warranties expressed or implied whether by statute or otherwise are hereby expressly excluded.
+ 1.1.2 Licensor shall not be liable for any claim, damages or other liability arising from or in connection with Licensee’s use of the Software during the Evaluation Period.
+ 1.1.3 For the avoidance of doubt, during the Evaluation Period: (i) clauses 11.1, 10.3 and 14.2 of this Agreement shall not apply; and (ii) clause 14.1 shall apply except that reference to clause 14.2 is deleted.
+ 1.1.4 Before or upon expiry of the Evaluation Period:
+(i) if, in Licensee’s sole opinion, the Software has met its requirements, and Licensee wishes to continue to use the Software beyond the end of the Evaluation Period, it can decide whether to obtain the equivalent Subscription Fee version. Once the appropriate Subscription has been obtained, this Agreement shall continue in force (except that this clause 1.1 shall no longer apply).
+(ii) If Licensee decides that the Software does not meet Licensee’s requirements, or otherwise does not wish to enter into a paid up Subscription, then Licensee shall destroy the Software and all copies, in any form including partial copies or modifications of the Software received from the Licensor or made in connect with this Evaluation Period and all documentation relating thereto. Any rights of Licensee to use the Software shall cease.
+1.2 Subscription. In consideration of Licensee paying to Licensor the Subscription Fee, Licensor grants Licensee a non-exclusive, non-transferable right to access and use the Software during the Subscription Period in accordance with this Agreement (“Subscription”).
+1.3 The Subscription is personal to the Licensee. Licensee may not rent, lease, sub-license, sell, pledge, assign the benefit or delegate the burden of this Agreement or Software or hold this Agreement on trust for any other person.
+1.4 Licensee is granted the following rights to the Software, but not to the source code of the Software:
+ 1.4.1 the right to temporarily reproduce, in whole or in parts, the Software, by any means and in any form, to the extent that uploading, displaying, running or other contractual use of the Software requires reproduction; and
+ 1.4.2 the right to permanently reproduce, in whole or in parts, the Software, to the extent that the creation of backups as are customary in the business requires reproduction.
+1.5 Except as stated in this Agreement, Licensee has no right to use, incorporate into other products, copy, publish, display, modify or translate the Software or any modification, adaption or copy of the Software or any part thereof. Licensee may only decompile, reverse engineer, or disassemble the source code Software either in whole or in part, as expressly permitted under the Subscription or under Sections 50(A), (B) and (BA) of the Copyright, Designs and Patents Act 1988 (as amended or updated from time to time) or other applicable law.
+1.6 The rights set out in this clause 1 may be exercised in any hardware and software environment of Licensee, for all currently known types of use (subject to any restrictions above); such rights are limited to the agreed multiple(s) of 10 production database schemas set out in the Licensor’s invoice.
+1.7 Licensee shall not use the Software to manufacture or distribute a product that is substantially similar to or competitive with the Software.
+
+2. Ownership of intellectual property rights
+--------------------------------------------
+
+2.1 Licensee acknowledges that i) all Intellectual Property Rights in or relating to the Software are owned by or licensed to Licensor and ii) except as expressly granted under the Agreement, Licensee has no rights in the Software.
+2.2 Licensee hereby agrees to refrain from any action which would diminish the Licensor’s Intellectual Property Rights in or relating to the Software or which would call those rights into question.
+2.3 Licensee agrees not to delete, remove or alter any trade marks, logos, copyright notices or similar proprietary devices of the Licensor’s, including without limitation any electronic watermarks or other identifiers that may be incorporated in the Software. All representations of Licensors name or logo must remain as originally distributed.
+
+3. Remuneration
+---------------
+
+3.1 The Subscription Fee (together with any levies, duties and/or taxes imposed on Licensee in Licensee’s jurisdiction (including but not limited to, value added tax, sales tax, use tax and withholding tax)) shall be due and payable by Licensee when Licensor issues a license key to Licensee for the Software. The Subscription Fee means the fee payable by Licensee under this Agreement to Licensor (excluding VAT and all other relevant taxes, where applicable), as detailed by Licensor from time including through Licensor’s website or as part of a written quotation.
+3.2 Licensee may not deduct any amounts from the Subscription Fee, unless otherwise specified in this Agreement.
+3.3 Where Licensee have obtained the Software through a Reseller, the terms agreed with such Reseller in relation to invoicing and payment will apply instead of this clause 3.
+
+4. Confidentiality
+------------------
+
+4.1 Licensee agrees not to provide or disclose any confidential information of Licensor’s (including relating to or derived from the Software) to any third party, including where such confidential information is derived under any applicable law as set out in clause 1.5.
+4.2 Other than the disclosures referred to in Licensor’s Privacy Policy, Licensor agrees not to provide or disclose to any third party any information of a confidential nature in any form whatsoever which is disclosed to Licensor by Licensee or on behalf of Licensee.
+4.3 The provisions of clauses 4.1 and 4.2 will not apply to the extent that:
+ 4.3.1 such information is in the receiving party’s possession free from any restriction as to its use or disclosure; or
+ 4.3.2 the receiving party can demonstrate that such information is in the public domain (other than as a result of an unauthorised disclosure); or
+ 4.3.3 such information is required to be disclosed by law.
+4.4 No information to which clause 4.3.3 applies shall be disclosed to a third party unless and until the receiving party has (unless prevented from doing so by law) (i) given the disclosing party reasonable written notice of such proposed disclosure, (ii) consulted with the disclosing party, and (iii) agreed with the disclosing party the content of the disclosure, provided that it shall not limit the disclosure in a manner which would prevent the receiving party from complying with a statutory or regulatory obligation or court order.
+
+5. Updates and upgrades
+-----------------------
+
+5.1 The Subscription includes all updates and upgrades of the Software released during the Subscription Period without any further fees, unless otherwise agreed on in a separate agreement.
+
+6. Rights to the source code
+----------------------------
+
+6.1 The Licensee is granted the following rights to the source code of the Software:
+ 6.1.1 the right to edit the source code solely for the purpose of correcting defects, and under the condition that the Licensee shall transmit to the Licensor all modifications made and grant the Licensor all rights required for the commercial exploitation of these changes in new versions or follow-on products of the software, in accordance with the Contributor License Agreement (CLA) of the Licensor (https://cla-assistant.io/flyway/flyway), that is applicable at the time of submitting the modifications to the Licensor.
+ 6.1.2 If, while a valid Subscription for the Software is in effect, insolvency proceedings have been opened on the assets of the Licensor or the opening of such proceedings has been rejected due to lack of assets, the Licensee shall be entitled to edit the software more extensively for the purpose of adapting the software to changing software environments, thus ensuring its continued operability.
+ 6.1.3 The Licensee is not permitted to disclose the source code.
+
+7. Support
+----------
+
+7.1 The Subscription entitles the Licensee to technical support by e-mail for a period of one year, starting with the acquisition of the license. The Licensor agrees to provide the Licensee technical support at no charge.
+7.2 Support requests must be sent by e-mail to support@flywaydb.org and shall be answered by email within 2 business days.
+
+8. Audit right
+--------------
+
+8.1 The Licensor has the right to verify the compliance of the Licensee with the license conditions. For this purpose, either the Licensor or a third party appointed by the Licensor shall be entitled, upon prior notice and with an appropriate lead time, to verify the compliant use of the software at the premises of the Licensee during normal business hours of the Licensee. The Licensee is obligated to assist the Licensor with the audit free of charge, and provide Licensor with adequate support, especially but not limited to granting access to information and to the systems on which the software is being used.
+
+9. Mention right
+----------------
+
+9.1 The Licensee grants the Licensor the right to mention the Licensee as a customer and user of the software, including the right to list the Licensee as a customer on Licensor’s website using both the Licensee’s company name and logo.
+
+10. Liability
+-------------
+
+10.1 Nothing in this Agreement shall limit or exclude either party’s liability for: (a) personal injury or death resulting from negligence, (b) fraud; or (c) any other matter for which liability cannot be excluded by law.
+10.2 Subject to clause 10.1, neither party shall be liable to the other party for any indirect, special or consequential loss or damage whatsoever arising under or in relation to this Agreement (whether in contract, tort (including negligence), breach of statutory duty, restitution or otherwise). The Licensor shall not be liable to the Licensee for any of the following types of loss or damage arising under or in relation to this Agreement: (a) any loss of profits, business, contracts, anticipated savings, goodwill, or revenue; or (b) any loss, or corruption, of software or data; or (c) any loss of use of hardware, software or data.
+10.3 Subject to clauses 10.1, 10.2 and 14.2 the Licensor’s aggregate liability under and in connection with this Agreement howsoever caused shall be limited in all cases to the Subscription Fee.
+10.4 The provisions of this clause 10 allocate risks under this Agreement between the Licensor and Licensee, and the Subscription Fee reflects this allocation of risks and these limitations of liability.
+
+11. Limited Warranty
+--------------------
+
+11.1 Licensor warrants that:
+ 11.1.1 Licensor owns the Intellectual Property Rights in the Software and/or have the right to grant a licence to Licensee;
+ 11.1.2 in creating the Software, Licensor has not knowingly infringed the intellectual property rights of third parties; and
+ 11.1.3 for a period of 90 days from the first installation of the Software (or, if applicable, 90 days from the end of the Evaluation Period if Licensee continues to use the Subscription Software) the Software shall operate substantially in accordance with its description. However, Licensee acknowledges that the Software is of such a complexity that there will be inherent defects and that therefore the Licensor can give no warranty that the Software is free from error or defect or that operation of the Software shall be uninterrupted.
+11.2 Other than as provided for in clause 11.1 above, Licensor does not offer any warranty related to the Software provided, either express or implied, including but not limited to implied warranties of fitness for purpose or satisfactory quality. The Software has been developed as a standard product for use by a wide variety of users and so Licensor is unable to warrant that the Software will meet any particular user needs. Licensee shall take full responsibility for ensuring that the Software is suitable for Licensee’s intended purposes and to facilitate investigation into such suitability, Licensor offers a free Evaluation Period.
+
+12. Agreement Term
+------------------
+
+12.1 The Subscription is valid for a period of 12 months from the purchase by the Licensee of the Subscription (“Subscription Period”). The Subscription and this Agreement will terminate automatically at the end of the Subscription Period.
+12.2 If Licensor does not receive the Subscription Fee, Licensor reserves the right to terminate the Subscription 30 days after the payment due date.
+12.3 The Subscription will terminate automatically if Licensee uninstalls and ceases use of the Software, or uninstalls and destroys or voluntarily returns the Software to Licensor, and notifies Licensor that Licensee has done so.
+12.4 Where the Subscription is terminated in accordance with clause 12.3 or clause 12.2, then the Agreement shall terminate in its entirety.
+12.5 Upon termination of this Agreement: (a) Licensee must cease use of the Software, and uninstall, destroy or put beyond use all copies of the Software in Licensee’s possession or control, and (b) the provisions of clauses 1.7, 4, 10, 11.2, 12, 14 and 15.1 to 15.6 will remain in effect.
+
+13. Data collection and Privacy Policy
+--------------------------------------
+
+13.1 Information on the data Licensor collects about Licensee and how Licensor treats that data is set out in Licensor’s Privacy Policy, which can be viewed at: https://flywaydb.org/legal-information.
+
+14. Third party claims
+----------------------
+
+14.1 Licensee agrees to indemnify Licensor from any loss or damage whether in contract, tort (including negligence), breach of statutory duty, restitution or otherwise, if a third party claims that Licensee’s use of the Software causes any such loss or damage, except in the circumstances in clause 14.2 below.
+14.2 If any claim is brought against Licensee alleging that their use of the intellectual property associated with the Software in accordance with this Agreement infringes the rights of any third party, Licensee shall promptly notify Licensor and supply full details of the claim. The parties shall consult together on an appropriate course of action and seek to minimise the effect of any claim on the respective businesses. Licensor shall have the right, but not the obligation, to take control of all negotiations and litigation arising out of the claim. Licensor will pay damages and costs awarded against Licensee in connection with any claim subject to a maximum of the Subscription Fee paid to Licensor by Licensee. Licensor shall have the right at its sole choice, to either; (i) use reasonable endeavours to negotiation terms for continued use by Licensee of the claimed infringing software; or (ii) use reasonable endeavours to amend the Software to make it non-infringing; or (iii) terminate this Agreement with immediate effect and in such event, Licensor shall refund to Licensee the Subscription Fee paid.
+
+15. General
+-----------
+
+15.1 Governing law and settlement of disputes. This Agreement (and any dispute or claim relating to it, or its formation, existence, construction, performance, validity or termination) will be governed by and construed in accordance with the laws of England. The courts of England and Wales shall have non-exclusive jurisdiction to settle any dispute or claim arising out of or in connection with this agreement or its subject matter or formation (including non-contractual disputes or claims). Without prejudice to any other rights or remedies that Licensor may have, Licensee acknowledges and agrees that damages alone would not be an adequate remedy for any breach of clauses 1, 2 and 4 by Licensee. Accordingly, Licensor shall be entitled to seek an injunction or other equitable relief for any threatened or actual breach of those clauses.
+15.2 Compliance with applicable law. Licensee agrees that, notwithstanding clause 15.1 above, Licensee may be subject to additional laws in other jurisdictions with respect to its use of the Software in such jurisdictions. Licensee agrees to comply with the laws of any such jurisdiction including, without limitation, any applicable export laws or regulations.
+15.3 Severability. If any provision or part of any provision in this Agreement is found to be illegal, invalid or unenforceable for any reason then the remaining provisions or part provisions remain unaffected and the parties shall meet promptly to discuss in good faith and agree an alternative provision or part provision that provides as closely as possible, the same commercial effect as the original.
+15.4 No waiver. No failure or delay by any party to exercise any right, power or remedy will operate as a waiver of it, nor will any partial exercise preclude any further exercise of the same, or of some other right, power or remedy.
+15.5 No third party rights. Licensor and Licensee do not intend that any of this Agreement will be enforceable by virtue of the Contracts (Rights of Third Parties) Act 1999 by any person not a party to it and all rights by virtue of the Contracts (Rights of Third Parties) Act 1999 are hereby excluded.
+15.6 Entire agreement. This Agreement contains all the terms which the parties have agreed in relation to the subject matter of this Agreement and supersedes any prior oral agreements, representations or understandings between the parties in relation to such subject matter.
+15.7 Consumer regulations. This clause applies to Consumers only. Licensee shall have the right to cancel this Agreement 14 days from the date Licensee agrees to be obliged to pay for the Software under this Agreement. Should Licensee wish to cancel this Agreement under this clause 15.7, Licensee must notify Licensor of Licensee’s decision to cancel by sending Licensor an email clearly confirming its decision to: invoices@flywaydb.org. If Licensee has any complaints about this Agreement, including complaints about the Software, please raise these with Boxfuse GmbH using sales@flywaydb.org.
+
diff --git b/flyway-commandline/src/main/assembly/flyway-pro.txt a/flyway-commandline/src/main/assembly/flyway-pro.txt
new file mode 100644
index 0000000..ba9642d
--- /dev/null
+++ a/flyway-commandline/src/main/assembly/flyway-pro.txt
@@ -0,0 +1,133 @@
+Flyway Pro Edition License and Support Agreement
+================================================
+
+Any use of the Flyway Pro Edition software is subject to the terms of this license agreement (“Agreement”). Please read the full Agreement carefully. This License and Support Agreement relates to purchases of the Flyway Pro Edition Software made on or after 2nd August 2019.
+
+This Agreement sets out the conditions under which and the extent to which the end user (referred to as “Licensee” below) is granted the right to use the “Flyway Pro Edition” software (referred to as “Software” below) provided by : Boxfuse GmbH, Scwedenstr. 9/Gebäude 1, 13359 Berlin, Germany (referred to as “Licensor” below).
+
+The Licensee confirms that it accepts and agrees to be legally bound by all terms and conditions of this Agreement by downloading and/or installing and/or using the Software. If you do not accept these terms, do not download, install or use the Software.
+
+IMPORTANT NOTICES:
+(i) A copy of Agreement will be sent with your Boxfuse GmbH invoice;
+(ii) Where you sign a paper version or a bespoke version of this Agreement, that paper/bespoke version will take precedence over any subsequent Agreements that were sent with your invoice; and
+(iii) This Agreement shall prevail over your standard terms and conditions (if any) attached to, enclosed with, or referred to in, any purchase order or confirmation of order.
+
+1. Grant of rights
+------------------
+
+1.1 Evaluation. Licensee is entitled to a 30 day free trial of the Software for the purposes of deciding whether or not the Software meets Licensee’s requirement. (“Evaluation Period”) During the Evaluation Period the following terms apply:
+ 1.1.1 During the Evaluation Period, Licensee hereby agrees that the Software is provided AS IS with no representation, guarantee or warranty of any kind as to its functionality, quality, performance, suitability or fitness for purpose. All other terms, conditions, representations and warranties expressed or implied whether by statute or otherwise are hereby expressly excluded.
+ 1.1.2 Licensor shall not be liable for any claim, damages or other liability arising from or in connection with Licensee’s use of the Software during the Evaluation Period.
+ 1.1.3 For the avoidance of doubt, during the Evaluation Period: (i) clauses 11.1, 10.3 and 14.2 of this Agreement shall not apply; and (ii) clause 14.1 shall apply except that reference to clause 14.2 is deleted.
+ 1.1.4 Before or upon expiry of the Evaluation Period:
+(i) if, in Licensee’s sole opinion, the Software has met its requirements, and Licensee wishes to continue to use the Software beyond the end of the Evaluation Period, it can decide whether to obtain the equivalent Subscription Fee version. Once the appropriate Subscription has been obtained, this Agreement shall continue in force (except that this clause 1.1 shall no longer apply).
+(ii) If Licensee decides that the Software does not meet Licensee’s requirements, or otherwise does not wish to enter into a paid up Subscription, then Licensee shall destroy the Software and all copies, in any form including partial copies or modifications of the Software received from the Licensor or made in connect with this Evaluation Period and all documentation relating thereto. Any rights of Licensee to use the Software shall cease.
+1.2 Subscription. In consideration of Licensee paying to Licensor the Subscription Fee, Licensor grants Licensee a non-exclusive, non-transferable right to access and use the Software during the Subscription Period in accordance with this Agreement (“Subscription”).
+1.3 The Subscription is personal to the Licensee. Licensee may not rent, lease, sub-license, sell, pledge, assign the benefit or delegate the burden of this Agreement or Software or hold this Agreement on trust for any other person.
+1.4 Licensee is granted the following rights to the Software, but not to the source code of the Software:
+ 1.4.1 the right to temporarily reproduce, in whole or in parts, the Software, by any means and in any form, to the extent that uploading, displaying, running or other contractual use of the Software requires reproduction; and
+ 1.4.2 the right to permanently reproduce, in whole or in parts, the Software, to the extent that the creation of backups as are customary in the business requires reproduction.
+1.5 Except as stated in this Agreement, Licensee has no right to use, incorporate into other products, copy, publish, display, modify or translate the Software or any modification, adaption or copy of the Software or any part thereof. Licensee may only decompile, reverse engineer, or disassemble the source code Software either in whole or in part, as expressly permitted under the Subscription or under Sections 50(A), (B) and (BA) of the Copyright, Designs and Patents Act 1988 (as amended or updated from time to time) or other applicable law.
+1.6 The rights set out in this clause 1 may be exercised in any hardware and software environment of Licensee, for all currently known types of use (subject to any restrictions above); such rights are limited to the agreed multiple(s) of 10 production database schemas set out in the Licensor’s invoice.
+1.7 Licensee shall not use the Software to manufacture or distribute a product that is substantially similar to or competitive with the Software.
+
+2. Ownership of intellectual property rights
+--------------------------------------------
+
+2.1 Licensee acknowledges that i) all Intellectual Property Rights in or relating to the Software are owned by or licensed to Licensor and ii) except as expressly granted under the Agreement, Licensee has no rights in the Software.
+2.2 Licensee hereby agrees to refrain from any action which would diminish the Licensor’s Intellectual Property Rights in or relating to the Software or which would call those rights into question.
+2.3 Licensee agrees not to delete, remove or alter any trade marks, logos, copyright notices or similar proprietary devices of the Licensor’s, including without limitation any electronic watermarks or other identifiers that may be incorporated in the Software. All representations of Licensors name or logo must remain as originally distributed.
+
+3. Remuneration
+---------------
+
+3.1 The Subscription Fee (together with any levies, duties and/or taxes imposed on Licensee in Licensee’s jurisdiction (including but not limited to, value added tax, sales tax, use tax and withholding tax)) shall be due and payable by Licensee when Licensor issues a license key to Licensee for the Software. The Subscription Fee means the fee payable by Licensee under this Agreement to Licensor (excluding VAT and all other relevant taxes, where applicable), as detailed by Licensor from time including through Licensor’s website or as part of a written quotation.
+3.2 Licensee may not deduct any amounts from the Subscription Fee, unless otherwise specified in this Agreement.
+3.3 Where Licensee have obtained the Software through a Reseller, the terms agreed with such Reseller in relation to invoicing and payment will apply instead of this clause 3.
+
+4. Confidentiality
+------------------
+
+4.1 Licensee agrees not to provide or disclose any confidential information of Licensor’s (including relating to or derived from the Software) to any third party, including where such confidential information is derived under any applicable law as set out in clause 1.5.
+4.2 Other than the disclosures referred to in Licensor’s Privacy Policy, Licensor agrees not to provide or disclose to any third party any information of a confidential nature in any form whatsoever which is disclosed to Licensor by Licensee or on behalf of Licensee.
+4.3 The provisions of clauses 4.1 and 4.2 will not apply to the extent that:
+ 4.3.1 such information is in the receiving party’s possession free from any restriction as to its use or disclosure; or
+ 4.3.2 the receiving party can demonstrate that such information is in the public domain (other than as a result of an unauthorised disclosure); or
+ 4.3.3 such information is required to be disclosed by law.
+4.4 No information to which clause 4.3.3 applies shall be disclosed to a third party unless and until the receiving party has (unless prevented from doing so by law) (i) given the disclosing party reasonable written notice of such proposed disclosure, (ii) consulted with the disclosing party, and (iii) agreed with the disclosing party the content of the disclosure, provided that it shall not limit the disclosure in a manner which would prevent the receiving party from complying with a statutory or regulatory obligation or court order.
+
+5. Updates and upgrades
+-----------------------
+
+5.1 The Subscription includes all updates and upgrades of the Software released during the Subscription Period without any further fees, unless otherwise agreed on in a separate agreement.
+
+6. Rights to the source code
+----------------------------
+
+6.1 The Licensee is granted the following rights to the source code of the Software:
+ 6.1.1 the right to edit the source code solely for the purpose of correcting defects, and under the condition that the Licensee shall transmit to the Licensor all modifications made and grant the Licensor all rights required for the commercial exploitation of these changes in new versions or follow-on products of the software, in accordance with the Contributor License Agreement (CLA) of the Licensor (https://cla-assistant.io/flyway/flyway), that is applicable at the time of submitting the modifications to the Licensor.
+ 6.1.2 If, while a valid Subscription for the Software is in effect, insolvency proceedings have been opened on the assets of the Licensor or the opening of such proceedings has been rejected due to lack of assets, the Licensee shall be entitled to edit the software more extensively for the purpose of adapting the software to changing software environments, thus ensuring its continued operability.
+ 6.1.3 The Licensee is not permitted to disclose the source code.
+
+7. Support
+----------
+
+7.1 The Subscription does not entitle the Licensee to technical support.
+
+8. Audit right
+--------------
+
+8.1 The Licensor has the right to verify the compliance of the Licensee with the license conditions. For this purpose, either the Licensor or a third party appointed by the Licensor shall be entitled, upon prior notice and with an appropriate lead time, to verify the compliant use of the software at the premises of the Licensee during normal business hours of the Licensee. The Licensee is obligated to assist the Licensor with the audit free of charge, and provide Licensor with adequate support, especially but not limited to granting access to information and to the systems on which the software is being used.
+
+9. Mention right
+----------------
+
+9.1 The Licensee grants the Licensor the right to mention the Licensee as a customer and user of the software, including the right to list the Licensee as a customer on Licensor’s website using both the Licensee’s company name and logo.
+
+10. Liability
+-------------
+
+10.1 Nothing in this Agreement shall limit or exclude either party’s liability for: (a) personal injury or death resulting from negligence, (b) fraud; or (c) any other matter for which liability cannot be excluded by law.
+10.2 Subject to clause 10.1, neither party shall be liable to the other party for any indirect, special or consequential loss or damage whatsoever arising under or in relation to this Agreement (whether in contract, tort (including negligence), breach of statutory duty, restitution or otherwise). The Licensor shall not be liable to the Licensee for any of the following types of loss or damage arising under or in relation to this Agreement: (a) any loss of profits, business, contracts, anticipated savings, goodwill, or revenue; or (b) any loss, or corruption, of software or data; or (c) any loss of use of hardware, software or data.
+10.3 Subject to clauses 10.1, 10.2 and 14.2 the Licensor’s aggregate liability under and in connection with this Agreement howsoever caused shall be limited in all cases to the Subscription Fee.
+10.4 The provisions of this clause 10 allocate risks under this Agreement between the Licensor and Licensee, and the Subscription Fee reflects this allocation of risks and these limitations of liability.
+
+11. Limited Warranty
+--------------------
+
+11.1 Licensor warrants that:
+ 11.1.1 Licensor owns the Intellectual Property Rights in the Software and/or have the right to grant a licence to Licensee;
+ 11.1.2 in creating the Software, Licensor has not knowingly infringed the intellectual property rights of third parties; and
+ 11.1.3 for a period of 90 days from the first installation of the Software (or, if applicable, 90 days from the end of the Evaluation Period if Licensee continues to use the Subscription Software) the Software shall operate substantially in accordance with its description. However, Licensee acknowledges that the Software is of such a complexity that there will be inherent defects and that therefore the Licensor can give no warranty that the Software is free from error or defect or that operation of the Software shall be uninterrupted.
+11.2 Other than as provided for in clause 11.1 above, Licensor does not offer any warranty related to the Software provided, either express or implied, including but not limited to implied warranties of fitness for purpose or satisfactory quality. The Software has been developed as a standard product for use by a wide variety of users and so Licensor is unable to warrant that the Software will meet any particular user needs. Licensee shall take full responsibility for ensuring that the Software is suitable for Licensee’s intended purposes and to facilitate investigation into such suitability, Licensor offers a free Evaluation Period.
+
+12. Agreement Term
+------------------
+
+12.1 The Subscription is valid for a period of 12 months from the purchase by the Licensee of the Subscription (“Subscription Period”). The Subscription and this Agreement will terminate automatically at the end of the Subscription Period.
+12.2 If Licensor does not receive the Subscription Fee, Licensor reserves the right to terminate the Subscription 30 days after the payment due date.
+12.3 The Subscription will terminate automatically if Licensee uninstalls and ceases use of the Software, or uninstalls and destroys or voluntarily returns the Software to Licensor, and notifies Licensor that Licensee has done so.
+12.4 Where the Subscription is terminated in accordance with clause 12.3 or clause 12.2, then the Agreement shall terminate in its entirety.
+12.5 Upon termination of this Agreement: (a) Licensee must cease use of the Software, and uninstall, destroy or put beyond use all copies of the Software in Licensee’s possession or control, and (b) the provisions of clauses 1.7, 4, 10, 11.2, 12,14 and 15.1 to 15.6 will remain in effect.
+
+13. Data collection and Privacy Policy
+--------------------------------------
+
+13.1 Information on the data Licensor collects about Licensee and how Licensor treats that data is set out in Licensor’s Privacy Policy, which can be viewed at: https://flywaydb.org/legal-information.
+
+14. Third party claims
+----------------------
+
+14.1 Licensee agrees to indemnify Licensor from any loss or damage whether in contract, tort (including negligence), breach of statutory duty, restitution or otherwise, if a third party claims that Licensee’s use of the Software causes any such loss or damage, except in the circumstances in clause 14.2 below.
+14.2 If any claim is brought against Licensee alleging that their use of the intellectual property associated with the Software in accordance with this Agreement infringes the rights of any third party, Licensee shall promptly notify Licensor and supply full details of the claim. The parties shall consult together on an appropriate course of action and seek to minimise the effect of any claim on the respective businesses. Licensor shall have the right, but not the obligation, to take control of all negotiations and litigation arising out of the claim. Licensor will pay damages and costs awarded against Licensee in connection with any claim subject to a maximum of the Subscription Fee paid to Licensor by Licensee. Licensor shall have the right at its sole choice, to either; (i) use reasonable endeavours to negotiation terms for continued use by Licensee of the claimed infringing software; or (ii) use reasonable endeavours to amend the Software to make it non-infringing; or (iii) terminate this Agreement with immediate effect and in such event, Licensor shall refund to Licensee the Subscription Fee paid.
+
+15. General
+-----------
+
+15.1 Governing law and settlement of disputes. This Agreement (and any dispute or claim relating to it, or its formation, existence, construction, performance, validity or termination) will be governed by and construed in accordance with the laws of England. The courts of England and Wales shall have non-exclusive jurisdiction to settle any dispute or claim arising out of or in connection with this agreement or its subject matter or formation (including non-contractual disputes or claims). Without prejudice to any other rights or remedies that Licensor may have, Licensee acknowledges and agrees that damages alone would not be an adequate remedy for any breach of clauses 1, 2 and 4 by Licensee. Accordingly, Licensor shall be entitled to seek an injunction or other equitable relief for any threatened or actual breach of those clauses.
+15.2 Compliance with applicable law. Licensee agrees that, notwithstanding clause 15.1 above, Licensee may be subject to additional laws in other jurisdictions with respect to its use of the Software in such jurisdictions. Licensee agrees to comply with the laws of any such jurisdiction including, without limitation, any applicable export laws or regulations.
+15.3 Severability. If any provision or part of any provision in this Agreement is found to be illegal, invalid or unenforceable for any reason then the remaining provisions or part provisions remain unaffected and the parties shall meet promptly to discuss in good faith and agree an alternative provision or part provision that provides as closely as possible, the same commercial effect as the original.
+15.4 No waiver. No failure or delay by any party to exercise any right, power or remedy will operate as a waiver of it, nor will any partial exercise preclude any further exercise of the same, or of some other right, power or remedy.
+15.5 No third party rights. Licensor and Licensee do not intend that any of this Agreement will be enforceable by virtue of the Contracts (Rights of Third Parties) Act 1999 by any person not a party to it and all rights by virtue of the Contracts (Rights of Third Parties) Act 1999 are hereby excluded.
+15.6 Entire agreement. This Agreement contains all the terms which the parties have agreed in relation to the subject matter of this Agreement and supersedes any prior oral agreements, representations or understandings between the parties in relation to such subject matter.
+15.7 Consumer regulations. This clause applies to Consumers only. Licensee shall have the right to cancel this Agreement 14 days from the date Licensee agrees to be obliged to pay for the Software under this Agreement. Should Licensee wish to cancel this Agreement under this clause 15.7, Licensee must notify Licensor of Licensee’s decision to cancel by sending Licensor an email clearly confirming its decision to: invoices@flywaydb.org. If Licensee has any complaints about this Agreement, including complaints about the Software, please raise these with Boxfuse GmbH using sales@flywaydb.org.
diff --git b/flyway-commandline/src/main/assembly/flyway.cmd a/flyway-commandline/src/main/assembly/flyway.cmd
new file mode 100644
index 0000000..b9ae897
--- /dev/null
+++ a/flyway-commandline/src/main/assembly/flyway.cmd
@@ -0,0 +1,71 @@
+@REM
+@REM Copyright 2010-2020 Redgate Software Ltd
+@REM
+@REM Licensed under the Apache License, Version 2.0 (the "License");
+@REM you may not use this file except in compliance with the License.
+@REM You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing, software
+@REM distributed under the License is distributed on an "AS IS" BASIS,
+@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@REM See the License for the specific language governing permissions and
+@REM limitations under the License.
+@REM
+
+@Echo off
+
+setlocal
+
+@REM Set the current directory to the installation directory
+call :getCurrentBatch INSTALLDIR1
+set INSTALLDIR=%INSTALLDIR1%
+set INSTALLDIR=%INSTALLDIR:~0,-10%
+
+if exist "%INSTALLDIR%\jre\bin\java.exe" (
+ set JAVA_CMD="%INSTALLDIR%\jre\bin\java.exe"
+) else (
+ @REM Use JAVA_HOME if it is set
+ if "%JAVA_HOME%"=="" (
+ set JAVA_CMD=java
+ ) else (
+ set JAVA_CMD="%JAVA_HOME%\bin\java.exe"
+ )
+)
+
+if "%JAVA_ARGS%"=="" (
+ set JAVA_ARGS=
+)
+
+@REM Determine Flyway edition to use
+:loop
+IF NOT [%1]==[] (
+ IF [%1]==[-community] (
+ SET FLYWAY_EDITION=community
+ GOTO :loop-end
+ )
+ IF [%1]==[-pro] (
+ SET FLYWAY_EDITION=pro
+ GOTO :loop-end
+ )
+ IF [%1]==[-enterprise] (
+ SET FLYWAY_EDITION=enterprise
+ GOTO :loop-end
+ )
+ SHIFT /1
+ GOTO :loop
+)
+:loop-end
+if "%FLYWAY_EDITION%"=="" (
+ set FLYWAY_EDITION=community
+)
+
+%JAVA_CMD% %JAVA_ARGS% -cp "%CLASSPATH%;%INSTALLDIR%\lib\*;%INSTALLDIR%\lib\%FLYWAY_EDITION%\*;%INSTALLDIR%\drivers\*" org.flywaydb.commandline.Main %*
+
+@REM Exit using the same code returned from Java
+EXIT /B %ERRORLEVEL%
+
+:getCurrentBatch
+ set "%~1=%~f0"
+ goto :eof
\ No newline at end of file
diff --git b/flyway-commandline/src/main/assembly/flyway.conf a/flyway-commandline/src/main/assembly/flyway.conf
new file mode 100644
index 0000000..7006a40
--- /dev/null
+++ a/flyway-commandline/src/main/assembly/flyway.conf
@@ -0,0 +1,343 @@
+#
+# Copyright 2010-2020 Boxfuse GmbH
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# JDBC url to use to connect to the database
+# Examples
+# --------
+# Most drivers are included out of the box.
+# * = JDBC driver must be downloaded and installed in /drivers manually
+# ** = TNS_ADMIN environment variable must point to the directory of where tnsnames.ora resides
+# Aurora MySQL : jdbc:mysql://..rds.amazonaws.com:/?=&=...
+# Aurora PostgreSQL : jdbc:postgresql://..rds.amazonaws.com:/?=&=...
+# CockroachDB : jdbc:postgresql://:/?=&=...
+# DB2* : jdbc:db2://:/
+# Derby : jdbc:derby::<;attribute=value>
+# Firebird : jdbc:firebirdsql://[:]/?=&=...
+# H2 : jdbc:h2:
+# HSQLDB : jdbc:hsqldb:file:
+# Informix* : jdbc:informix-sqli://:/:informixserver=dev
+# MariaDB : jdbc:mariadb://:/?=&=...
+# MySQL : jdbc:mysql://:/?=&=...
+# Oracle : jdbc:oracle:thin:@//:/
+# Oracle (TNS)** : jdbc:oracle:thin:@
+# PostgreSQL : jdbc:postgresql://:/?=&=...
+# SAP HANA* : jdbc:sap://:/?databaseName=
+# Snowflake* : jdbc:snowflake://.snowflakecomputing.com/?db=&warehouse=&role=...
+# SQL Server : jdbc:sqlserver://:;databaseName=
+# SQLite : jdbc:sqlite:
+# Sybase ASE : jdbc:jtds:sybase://:/
+# Redshift* : jdbc:redshift://:/
+# flyway.url=
+
+# Fully qualified classname of the JDBC driver (autodetected by default based on flyway.url)
+# flyway.driver=
+
+# User to use to connect to the database. Flyway will prompt you to enter it if not specified, and if the JDBC
+# connection is not using a password-less method of authentication.
+# flyway.user=
+
+# Password to use to connect to the database. Flyway will prompt you to enter it if not specified, and if the JDBC
+# connection is not using a password-less method of authentication.
+# flyway.password=
+
+# The maximum number of retries when attempting to connect to the database. After each failed attempt,
+# Flyway will wait 1 second before attempting to connect again, up to the maximum number of times specified
+# by connectRetries. (default: 0)
+# flyway.connectRetries=
+
+# The SQL statements to run to initialize a new database connection immediately after opening it. (default: none)
+# flyway.initSql=
+
+# The default schema managed by Flyway. This schema name is case-sensitive. If not specified, but flyway.schemas is, Flyway uses the first schema
+# in that list. If that is also not specified, Flyway uses the default schema for the database connection.
+# Consequences:
+# - This schema will be the one containing the schema history table.
+# - This schema will be the default for the database connection (provided the database supports this concept).
+# flyway.defaultSchema=
+
+# Comma-separated list of schemas managed by Flyway. These schema names are case-sensitive. If not specified, Flyway uses
+# the default schema for the database connection. If flyway.defaultSchema is not specified, then the first of
+# this list also acts as default schema.
+# Consequences:
+# - Flyway will automatically attempt to create all these schemas, unless they already exist.
+# - The schemas will be cleaned in the order of this list.
+# - If Flyway created them, the schemas themselves will be dropped when cleaning.
+# flyway.schemas=
+
+# Whether Flyway should attempt to create the schemas specified in the schemas property
+# flyway.createSchemas=
+
+# Name of Flyway's schema history table (default: flyway_schema_history)
+# By default (single-schema mode) the schema history table is placed in the default schema for the connection
+# provided by the datasource.
+# When the flyway.schemas property is set (multi-schema mode), the schema history table is placed in the first
+# schema of the list.
+# flyway.table=
+
+# The tablespace where to create the schema history table that will be used by Flyway. If not specified, Flyway uses
+# the default tablespace for the database connection.
+# This setting is only relevant for databases that do support the notion of tablespaces. Its value is simply
+# ignored for all others.
+# flyway.tablespace=
+
+# Comma-separated list of locations to scan recursively for migrations. (default: filesystem:<>/sql)
+# The location type is determined by its prefix.
+# Unprefixed locations or locations starting with classpath: point to a package on the classpath and may contain
+# both SQL and Java-based migrations.
+# Locations starting with filesystem: point to a directory on the filesystem, may only
+# contain SQL migrations and are only scanned recursively down non-hidden directories.
+# Wildcards can be used to reduce duplication of location paths. (e.g. filesystem:migrations/*/oracle) Supported wildcards:
+# ** : Matches any 0 or more directories
+# * : Matches any 0 or more non-separator characters
+# ? : Matches any 1 non-separator character
+# flyway.locations=
+
+# Comma-separated list of fully qualified class names of custom MigrationResolver to use for resolving migrations.
+# flyway.resolvers=
+
+# If set to true, default built-in resolvers (jdbc, spring-jdbc and sql) are skipped and only custom resolvers as
+# defined by 'flyway.resolvers' are used. (default: false)
+# flyway.skipDefaultResolvers=
+
+# Comma-separated list of directories containing JDBC drivers and Java-based migrations.
+# (default: /jars)
+# flyway.jarDirs=
+
+# File name prefix for versioned SQL migrations (default: V)
+# Versioned SQL migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+# which using the defaults translates to V1_1__My_description.sql
+# flyway.sqlMigrationPrefix=
+
+# The file name prefix for undo SQL migrations. (default: U)
+# Undo SQL migrations are responsible for undoing the effects of the versioned migration with the same version.
+# They have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+# which using the defaults translates to U1.1__My_description.sql
+# Flyway Pro and Flyway Enterprise only
+# flyway.undoSqlMigrationPrefix=
+
+# File name prefix for repeatable SQL migrations (default: R)
+# Repeatable SQL migrations have the following file name structure: prefixSeparatorDESCRIPTIONsuffix ,
+# which using the defaults translates to R__My_description.sql
+# flyway.repeatableSqlMigrationPrefix=
+
+# File name separator for Sql migrations (default: __)
+# Sql migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+# which using the defaults translates to V1_1__My_description.sql
+# flyway.sqlMigrationSeparator=
+
+# Comma-separated list of file name suffixes for SQL migrations. (default: .sql)
+# SQL migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+# which using the defaults translates to V1_1__My_description.sql
+# Multiple suffixes (like .sql,.pkg,.pkb) can be specified for easier compatibility with other tools such as
+# editors with specific file associations.
+# flyway.sqlMigrationSuffixes=
+
+# Whether to stream SQL migrations when executing them. (default: false)
+# Streaming doesn't load the entire migration in memory at once. Instead each statement is loaded individually.
+# This is particularly useful for very large SQL migrations composed of multiple MB or even GB of reference data,
+# as this dramatically reduces Flyway's memory consumption.
+# Flyway Pro and Flyway Enterprise only
+# flyway.stream=
+
+# Whether to batch SQL statements when executing them. (default: false)
+# Batching can save up to 99 percent of network roundtrips by sending up to 100 statements at once over the
+# network to the database, instead of sending each statement individually. This is particularly useful for very
+# large SQL migrations composed of multiple MB or even GB of reference data, as this can dramatically reduce
+# the network overhead. This is supported for INSERT, UPDATE, DELETE, MERGE and UPSERT statements.
+# All other statements are automatically executed without batching.
+# Flyway Pro and Flyway Enterprise only
+# flyway.batch=
+
+# Encoding of SQL migrations (default: UTF-8). Caution: changing the encoding after migrations have been run
+# will invalidate the calculated checksums and require a `flyway repair`.
+# flyway.encoding=
+
+# Whether placeholders should be replaced. (default: true)
+# flyway.placeholderReplacement=
+
+# Placeholders to replace in Sql migrations
+# flyway.placeholders.user=
+# flyway.placeholders.my_other_placeholder=
+
+# Prefix of every placeholder (default: ${ )
+# flyway.placeholderPrefix=
+
+# Suffix of every placeholder (default: } )
+# flyway.placeholderSuffix=
+
+# Target version up to which Flyway should consider migrations.
+# Defaults to 'latest'
+# Special values:
+# - 'current': designates the current version of the schema
+# - 'latest': the latest version of the schema, as defined by the migration with the highest version
+# flyway.target=
+
+# Whether to automatically call validate or not when running migrate. (default: true)
+# flyway.validateOnMigrate=
+
+# Whether to automatically call clean or not when a validation error occurs. (default: false)
+# This is exclusively intended as a convenience for development. even though we
+# strongly recommend not to change migration scripts once they have been checked into SCM and run, this provides a
+# way of dealing with this case in a smooth manner. The database will be wiped clean automatically, ensuring that
+# the next migration will bring you back to the state checked into SCM.
+# Warning ! Do not enable in production !
+# flyway.cleanOnValidationError=
+
+# Whether to disable clean. (default: false)
+# This is especially useful for production environments where running clean can be quite a career limiting move.
+# flyway.cleanDisabled=
+
+# The version to tag an existing schema with when executing baseline. (default: 1)
+# flyway.baselineVersion=
+
+# The description to tag an existing schema with when executing baseline. (default: << Flyway Baseline >>)
+# flyway.baselineDescription=
+
+# Whether to automatically call baseline when migrate is executed against a non-empty schema with no schema history
+# table. This schema will then be initialized with the baselineVersion before executing the migrations.
+# Only migrations above baselineVersion will then be applied.
+# This is useful for initial Flyway production deployments on projects with an existing DB.
+# Be careful when enabling this as it removes the safety net that ensures
+# Flyway does not migrate the wrong database in case of a configuration mistake! (default: false)
+# flyway.baselineOnMigrate=
+
+# Allows migrations to be run "out of order" (default: false).
+# If you already have versions 1 and 3 applied, and now a version 2 is found,
+# it will be applied too instead of being ignored.
+# flyway.outOfOrder=
+
+# Whether Flyway should output a table with the results of queries when executing migrations (default: true).
+# Flyway Pro and Flyway Enterprise only
+# flyway.outputQueryResults=
+
+# This allows you to tie in custom code and logic to the Flyway lifecycle notifications (default: empty).
+# Set this to a comma-separated list of fully qualified class names of org.flywaydb.core.api.callback.Callback
+# implementations.
+# flyway.callbacks=
+
+# If set to true, default built-in callbacks (sql) are skipped and only custom callback as
+# defined by 'flyway.callbacks' are used. (default: false)
+# flyway.skipDefaultCallbacks=
+
+# Ignore missing migrations when reading the schema history table. These are migrations that were performed by an
+# older deployment of the application that are no longer available in this version. For example: we have migrations
+# available on the classpath with versions 1.0 and 3.0. The schema history table indicates that a migration with
+# version 2.0 (unknown to us) has also been applied. Instead of bombing out (fail fast) with an exception, a
+# warning is logged and Flyway continues normally. This is useful for situations where one must be able to deploy
+# a newer version of the application even though it doesn't contain migrations included with an older one anymore.
+# Note that if the most recently applied migration is removed, Flyway has no way to know it is missing and will
+# mark it as future instead.
+# true to continue normally and log a warning, false to fail fast with an exception. (default: false)
+# flyway.ignoreMissingMigrations=
+
+# Ignore ignored migrations when reading the schema history table. These are migrations that were added in between
+# already migrated migrations in this version. For example: we have migrations available on the classpath with
+# versions from 1.0 to 3.0. The schema history table indicates that version 1 was finished on 1.0.15, and the next
+# 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
+# by migrate command, but by default is rejected by validate. When ignoreIgnoredMigrations is enabled, such case
+# will not be reported by validate command. This is useful for situations where one must be able to deliver
+# complete set of migrations in a delivery package for multiple versions of the product, and allows for further
+# development of older versions.
+# true to continue normally, false to fail fast with an exception. (default: false)
+# flyway.ignoreIgnoredMigrations=
+
+# Ignore pending migrations when reading the schema history table. These are migrations that are available
+# but have not yet been applied. This can be useful for verifying that in-development migration changes
+# don't contain any validation-breaking changes of migrations that have already been applied to a production
+# environment, e.g. as part of a CI/CD process, without failing because of the existence of new migration versions.
+# (default: false)
+# flyway.ignorePendingMigrations=
+
+# Ignore future migrations when reading the schema history table. These are migrations that were performed by a
+# newer deployment of the application that are not yet available in this version. For example: we have migrations
+# available on the classpath up to version 3.0. The schema history table indicates that a migration to version 4.0
+# (unknown to us) has already been applied. Instead of bombing out (fail fast) with an exception, a
+# warning is logged and Flyway continues normally. This is useful for situations where one must be able to redeploy
+# an older version of the application after the database has been migrated by a newer one.
+# true to continue normally and log a warning, false to fail fast with an exception. (default: true)
+# flyway.ignoreFutureMigrations=
+
+# Whether to validate migrations and callbacks whose scripts do not obey the correct naming convention. A failure can be
+# useful to check that errors such as case sensitivity in migration prefixes have been corrected.
+# false to continue normally, true to fail fast with an exception (default: false)
+# flyway.validateMigrationNaming=
+
+# Whether to allow mixing transactional and non-transactional statements within the same migration.
+# Flyway attempts to run each migration within its own transaction
+# If Flyway detects that a specific statement cannot be run within a transaction, it won’t run that migration within a transaction
+# This option toggles whether transactional and non-transactional statements can be mixed within a migration run.
+# Enabling this means for 'mixed' migrations, the entire script will be run without a transaction
+# Note that this is only applicable for PostgreSQL, Aurora PostgreSQL, SQL Server and SQLite which all have
+# statements that do not run at all within a transaction.
+# This is not to be confused with implicit transaction, as they occur in MySQL or Oracle, where even though a
+# DDL statement was run within within a transaction, the database will issue an implicit commit before and after
+# its execution.
+# true if mixed migrations should be allowed. false if an error should be thrown instead. (default: false)
+# flyway.mixed=
+
+# Whether to group all pending migrations together in the same transaction when applying them
+# (only recommended for databases with support for DDL transactions).
+# true if migrations should be grouped. false if they should be applied individually instead. (default: false)
+# flyway.group=
+
+# The username that will be recorded in the schema history table as having applied the migration.
+# <> for the current database user of the connection. (default: <>).
+# flyway.installedBy=
+
+# Rules for the built-in error handler that let you override specific SQL states and errors codes in order to
+# force specific errors or warnings to be treated as debug messages, info messages, warnings or errors.
+# Each error override has the following format: STATE:12345:W.
+# It is a 5 character SQL state (or * to match all SQL states), a colon,
+# the SQL error code (or * to match all SQL error codes), a colon and finally
+# the desired behavior that should override the initial one.
+# The following behaviors are accepted:
+# - D to force a debug message
+# - D- to force a debug message, but do not show the original sql state and error code
+# - I to force an info message
+# - I- to force an info message, but do not show the original sql state and error code
+# - W to force a warning
+# - W- to force a warning, but do not show the original sql state and error code
+# - E to force an error
+# - E- to force an error, but do not show the original sql state and error code
+# Example 1: to force Oracle stored procedure compilation issues to produce
+# errors instead of warnings, the following errorOverride can be used: 99999:17110:E
+# Example 2: to force SQL Server PRINT messages to be displayed as info messages (without SQL state and error
+# code details) instead of warnings, the following errorOverride can be used: S0001:0:I-
+# Example 3: to force all errors with SQL error code 123 to be treated as warnings instead,
+# the following errorOverride can be used: *:123:W
+# Flyway Pro and Flyway Enterprise only
+# flyway.errorOverrides=
+
+# The file where to output the SQL statements of a migration dry run. If the file specified is in a non-existent
+# directory, Flyway will create all directories and parent directories as needed.
+# <> to execute the SQL statements directly against the database. (default: <>)
+# Flyway Pro and Flyway Enterprise only
+# flyway.dryRunOutput=
+
+# Whether to Flyway's support for Oracle SQL*Plus commands should be activated. (default: false)
+# Flyway Pro and Flyway Enterprise only
+# flyway.oracle.sqlplus=
+
+# Whether Flyway should issue a warning instead of an error whenever it encounters an Oracle SQL*Plus
+# statement it doesn't yet support. (default: false)
+# Flyway Pro and Flyway Enterprise only
+# flyway.oracle.sqlplusWarn=
+
+# Your Flyway license key (FL01...). Not yet a Flyway Pro or Enterprise Edition customer?
+# Request your Flyway trial license key st https://flywaydb.org/download/
+# to try out Flyway Pro and Enterprise Edition features free for 30 days.
+# Flyway Pro and Flyway Enterprise only
+# flyway.licenseKey=
\ No newline at end of file
diff --git b/flyway-commandline/src/main/assembly/linux.xml a/flyway-commandline/src/main/assembly/linux.xml
new file mode 100644
index 0000000..d264a84
--- /dev/null
+++ a/flyway-commandline/src/main/assembly/linux.xml
@@ -0,0 +1,36 @@
+
+
+ linux-x64
+
+ tar.gz
+
+ flyway-${project.version}
+
+ src/main/assembly/component.xml
+
+
+
+ target/dependency/jre-linux-x64-tar.gz/jdk-${version.jre}+9-jre
+ jre
+ 755
+
+
+
\ No newline at end of file
diff --git b/flyway-commandline/src/main/assembly/macos.xml a/flyway-commandline/src/main/assembly/macos.xml
new file mode 100644
index 0000000..3327e22
--- /dev/null
+++ a/flyway-commandline/src/main/assembly/macos.xml
@@ -0,0 +1,36 @@
+
+
+ macosx-x64
+
+ tar.gz
+
+ flyway-${project.version}
+
+ src/main/assembly/component.xml
+
+
+
+ target/dependency/jre-macos-x64-tar.gz/jdk-${version.jre}+9-jre/Contents/Home
+ jre
+ 755
+
+
+
\ No newline at end of file
diff --git b/flyway-commandline/src/main/assembly/no-jre.xml a/flyway-commandline/src/main/assembly/no-jre.xml
new file mode 100644
index 0000000..7a4b500
--- /dev/null
+++ a/flyway-commandline/src/main/assembly/no-jre.xml
@@ -0,0 +1,30 @@
+
+
+ no-jre
+
+ tar.gz
+ zip
+
+ flyway-${project.version}
+
+ src/main/assembly/component.xml
+
+
\ No newline at end of file
diff --git b/flyway-commandline/src/main/assembly/put-your-java-migration-jars-here.txt a/flyway-commandline/src/main/assembly/put-your-java-migration-jars-here.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ a/flyway-commandline/src/main/assembly/put-your-java-migration-jars-here.txt
diff --git b/flyway-commandline/src/main/assembly/put-your-jdbc-drivers-here.txt a/flyway-commandline/src/main/assembly/put-your-jdbc-drivers-here.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ a/flyway-commandline/src/main/assembly/put-your-jdbc-drivers-here.txt
diff --git b/flyway-commandline/src/main/assembly/put-your-sql-migrations-here.txt a/flyway-commandline/src/main/assembly/put-your-sql-migrations-here.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ a/flyway-commandline/src/main/assembly/put-your-sql-migrations-here.txt
diff --git b/flyway-commandline/src/main/assembly/windows.xml a/flyway-commandline/src/main/assembly/windows.xml
new file mode 100644
index 0000000..18c6f38
--- /dev/null
+++ a/flyway-commandline/src/main/assembly/windows.xml
@@ -0,0 +1,36 @@
+
+
+ windows-x64
+
+ zip
+
+ flyway-${project.version}
+
+ src/main/assembly/component.xml
+
+
+
+ target/dependency/jre-windows-x64-zip/jdk-${version.jre}+9-jre
+ jre
+ 644
+
+
+
\ No newline at end of file
diff --git b/flyway-commandline/src/main/java/org/flywaydb/commandline/ColorizedConsoleLog.java a/flyway-commandline/src/main/java/org/flywaydb/commandline/ColorizedConsoleLog.java
new file mode 100644
index 0000000..f0f345c
--- /dev/null
+++ a/flyway-commandline/src/main/java/org/flywaydb/commandline/ColorizedConsoleLog.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.commandline;
+
+import org.flywaydb.core.api.logging.Log;
+import org.fusesource.jansi.Ansi;
+import org.fusesource.jansi.Ansi.Color;
+import org.fusesource.jansi.AnsiConsole;
+
+import java.io.PrintStream;
+
+/**
+ * Wrapper which adds color to a Console output.
+ */
+class ColorizedConsoleLog implements Log {
+ private final ConsoleLog log;
+
+ public static void install(boolean force) {
+ if (force) {
+ System.setProperty("jansi.force", "true");
+ }
+
+ AnsiConsole.systemInstall();
+ }
+
+ public ColorizedConsoleLog(ConsoleLog log) {
+ this.log = log;
+ }
+
+ @Override
+ public boolean isDebugEnabled() {
+ return this.log.isDebugEnabled();
+ }
+
+ @Override
+ public void debug(String message) {
+ colorizeBright(System.out, Color.BLACK);
+ this.log.debug(message);
+ reset(System.out);
+ }
+
+ @Override
+ public void info(String message) {
+ if (message.startsWith("Successfully")) {
+ colorize(System.out, Color.GREEN);
+ this.log.info(message);
+ reset(System.out);
+ } else {
+ this.log.info(message);
+ }
+ }
+
+ @Override
+ public void warn(String message) {
+ colorize(System.out, Color.YELLOW);
+ this.log.warn(message);
+ reset(System.out);
+ }
+
+ @Override
+ public void error(String message) {
+ colorize(System.err, Color.RED);
+ this.log.error(message);
+ reset(System.err);
+ }
+
+ @Override
+ public void error(String message, Exception e) {
+ colorize(System.err, Color.RED);
+ this.log.error(message, e);
+ reset(System.err);
+ }
+
+ private void colorize(PrintStream stream, Color color) {
+ stream.print(Ansi.ansi().fg(color));
+ }
+
+ private void colorizeBright(PrintStream stream, Color color) {
+ stream.print(Ansi.ansi().fgBright(color));
+ }
+
+ private void reset(PrintStream stream) {
+ stream.print(Ansi.ansi().reset());
+ }
+}
\ No newline at end of file
diff --git b/flyway-commandline/src/main/java/org/flywaydb/commandline/CommandLineArguments.java a/flyway-commandline/src/main/java/org/flywaydb/commandline/CommandLineArguments.java
new file mode 100644
index 0000000..f66090f
--- /dev/null
+++ a/flyway-commandline/src/main/java/org/flywaydb/commandline/CommandLineArguments.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.commandline;
+
+import org.flywaydb.commandline.ConsoleLog.Level;
+import org.flywaydb.core.api.FlywayException;
+import org.flywaydb.core.api.logging.Log;
+import org.flywaydb.core.internal.util.StringUtils;
+
+import java.util.*;
+
+class CommandLineArguments {
+
+ enum Color {
+ ALWAYS("always"),
+ NEVER("never"),
+ AUTO("auto");
+
+ private final String value;
+
+ Color(String value) {
+ this.value = value;
+ }
+
+ public static Color fromString(String value) {
+ if (value.isEmpty()) {
+ return AUTO;
+ }
+
+ for (Color color : values()) {
+ if (color.value.equals(value)) {
+ return color;
+ }
+ }
+
+ return null;
+ }
+
+ public static boolean isValid(String value) {
+ return fromString(value) != null;
+ }
+ }
+
+ // Flags
+ private static String DEBUG_FLAG = "-X";
+ private static String QUIET_FLAG = "-q";
+ private static String SUPPRESS_PROMPT_FLAG = "-n";
+ private static String PRINT_VERSION_AND_EXIT_FLAG = "-v";
+ private static String JSON_FLAG = "-json";
+ private static String PRINT_USAGE_FLAG = "-?";
+ private static String COMMUNITY_FLAG = "-community";
+ private static String PRO_FLAG = "-pro";
+ private static String ENTERPRISE_FLAG = "-enterprise";
+
+ // Command line specific configuration options
+ private static String OUTPUT_FILE = "outputFile";
+ private static String LOG_FILE = "logFile";
+ private static String CONFIG_FILE_ENCODING = "configFileEncoding";
+ private static String CONFIG_FILES = "configFiles";
+ private static String COLOR = "color";
+ private static String WORKING_DIRECTORY = "workingDirectory";
+
+ private static List VALID_OPERATIONS_AND_FLAGS = Arrays.asList(
+ DEBUG_FLAG,
+ QUIET_FLAG,
+ SUPPRESS_PROMPT_FLAG,
+ PRINT_VERSION_AND_EXIT_FLAG,
+ JSON_FLAG,
+ PRINT_USAGE_FLAG,
+ COMMUNITY_FLAG,
+ PRO_FLAG,
+ ENTERPRISE_FLAG,
+ "help",
+ "migrate",
+ "clean",
+ "info",
+ "validate",
+ "undo",
+ "baseline",
+ "repair"
+ );
+
+ private final String[] args;
+
+ CommandLineArguments(String[] args) {
+ this.args = args;
+ }
+
+ private static boolean isFlagSet(String[] args, String flag) {
+ for (String arg : args) {
+ if (flag.equals(arg)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static String getArgumentValue(String argName, String[] allArgs) {
+ for (String arg : allArgs) {
+ if (arg.startsWith("-" + argName + "=")) {
+ return parseConfigurationOptionValueFromArg(arg);
+ }
+ }
+ return "";
+ }
+
+ private static String parseConfigurationOptionValueFromArg(String arg) {
+ int index = arg.indexOf("=");
+
+ if (index < 0 || index == arg.length()) {
+ return "";
+ }
+
+ return arg.substring(index + 1);
+ }
+
+ private static List getOperationsFromArgs(String[] args) {
+ List operations = new ArrayList<>();
+
+ for (String arg : args) {
+ if (!arg.startsWith("-")) {
+ operations.add(arg);
+ }
+ }
+ return operations;
+ }
+
+ private static List getConfigFilesFromArgs(String[] args) {
+ String configFilesCommaSeparatedList = getArgumentValue(CONFIG_FILES, args);
+
+ return Arrays.asList(StringUtils.tokenizeToStringArray(configFilesCommaSeparatedList, ","));
+ }
+
+ private static Map getConfigurationFromArgs(String[] args) {
+ Map configuration = new HashMap<>();
+
+ for (String arg : args) {
+ if (isConfigurationArg(arg)) {
+ String configurationOptionName = getConfigurationOptionNameFromArg(arg);
+
+ if (!isConfigurationOptionIgnored(configurationOptionName)) {
+ configuration.put("flyway." + configurationOptionName, parseConfigurationOptionValueFromArg(arg));
+ }
+ }
+ }
+
+ return configuration;
+ }
+
+ private static boolean isConfigurationOptionIgnored(String configurationOptionName) {
+ return OUTPUT_FILE.equals(configurationOptionName) ||
+ LOG_FILE.equals(configurationOptionName) ||
+ COLOR.equals(configurationOptionName) ||
+ WORKING_DIRECTORY.equals(configurationOptionName);
+ }
+
+ private static String getConfigurationOptionNameFromArg(String arg) {
+ int index = arg.indexOf("=");
+
+ return arg.substring(1, index);
+ }
+
+ private static boolean isConfigurationArg(String arg) {
+ return arg.startsWith("-") && arg.contains("=");
+ }
+
+ void validate(Log log) {
+ for (String arg : args) {
+ if (!isConfigurationArg(arg) && !CommandLineArguments.VALID_OPERATIONS_AND_FLAGS.contains(arg)) {
+ throw new FlywayException("Invalid argument: " + arg);
+ }
+ }
+
+ if (isLogFilepathSet()) {
+ if (isOutputFileSet()) {
+ throw new FlywayException("-logFile and -outputFile are incompatible. -logFile is deprecated. Instead use -outputFile.");
+ }
+
+ if (shouldOutputJson()) {
+ throw new FlywayException("-logFile and -json are incompatible. -logFile is deprecated. Instead use -outputFile to print JSON to a file.");
+ }
+
+ log.warn("-logFile is deprecated. Instead use -outputFile.");
+ }
+
+ if (shouldOutputJson() && !hasOperation("info") ) {
+ throw new FlywayException("The -json flag is only supported by the info command.");
+ }
+
+ String colorArgumentValue = getArgumentValue(COLOR, args);
+ if (!Color.isValid(colorArgumentValue)) {
+ throw new FlywayException("'" + colorArgumentValue + "' is an invalid value for the -color option. Use 'always', 'never', or 'auto'.");
+ }
+ }
+
+ boolean shouldSuppressPrompt() {
+ return isFlagSet(args, SUPPRESS_PROMPT_FLAG);
+ }
+
+ boolean shouldPrintVersionAndExit() {
+ return isFlagSet(args, PRINT_VERSION_AND_EXIT_FLAG);
+ }
+
+ boolean shouldOutputJson() {
+ return isFlagSet(args, JSON_FLAG);
+ }
+
+ boolean shouldPrintUsage() {
+ return isFlagSet(args, PRINT_USAGE_FLAG) || getOperations().isEmpty();
+ }
+
+ Level getLogLevel() {
+ if (isFlagSet(args, QUIET_FLAG)) {
+ return Level.WARN;
+ }
+
+ if (isFlagSet(args, DEBUG_FLAG)) {
+ return Level.DEBUG;
+ }
+
+ return Level.INFO;
+ }
+
+ boolean hasOperation(String operation) {
+ return getOperations().contains(operation);
+ }
+
+ List getOperations() {
+ return getOperationsFromArgs(args);
+ }
+
+ List getConfigFiles() {
+ return getConfigFilesFromArgs(args);
+ }
+
+ String getOutputFile() {
+ return getArgumentValue(OUTPUT_FILE, args);
+ }
+
+ String getLogFilepath() {
+ return getArgumentValue(LOG_FILE, args);
+ }
+
+ String getWorkingDirectory() {
+ return getArgumentValue(WORKING_DIRECTORY, args);
+ }
+
+ boolean isOutputFileSet() {
+ return !getOutputFile().isEmpty();
+ }
+
+ boolean isLogFilepathSet() {
+ return !getLogFilepath().isEmpty();
+ }
+
+ boolean isWorkingDirectorySet() {
+ return !getWorkingDirectory().isEmpty();
+ }
+
+ String getConfigFileEncoding() {
+ return getArgumentValue(CONFIG_FILE_ENCODING, args);
+ }
+
+ boolean isConfigFileEncodingSet() {
+ return !getConfigFileEncoding().isEmpty();
+ }
+
+ Color getColor() {
+ return Color.fromString(getArgumentValue(COLOR, args));
+ }
+
+ Map getConfiguration() {
+ return getConfigurationFromArgs(args);
+ }
+}
\ No newline at end of file
diff --git b/flyway-commandline/src/main/java/org/flywaydb/commandline/ConsoleLog.java a/flyway-commandline/src/main/java/org/flywaydb/commandline/ConsoleLog.java
new file mode 100644
index 0000000..dcec32f
--- /dev/null
+++ a/flyway-commandline/src/main/java/org/flywaydb/commandline/ConsoleLog.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.commandline;
+
+import org.flywaydb.core.api.logging.Log;
+
+/**
+ * Console output for standard output and standard error.
+ */
+class ConsoleLog implements Log {
+ public enum Level {
+ DEBUG, INFO, WARN
+ }
+
+ private final Level level;
+
+ /**
+ * Creates a new PrintStream Log.
+ *
+ * @param level the log level.
+ */
+ public ConsoleLog(Level level) {
+ this.level = level;
+ }
+
+ @Override
+ public boolean isDebugEnabled() {
+ return level == Level.DEBUG;
+ }
+
+ public void debug(String message) {
+ if (isDebugEnabled()) {
+ System.out.println("DEBUG: " + message);
+ }
+ }
+
+ public void info(String message) {
+ if (level.compareTo(Level.INFO) <= 0) {
+ System.out.println(message);
+ }
+ }
+
+ public void warn(String message) {
+ System.out.println("WARNING: " + message);
+ }
+
+ public void error(String message) {
+ System.err.println("ERROR: " + message);
+ }
+
+ public void error(String message, Exception e) {
+ System.err.println("ERROR: " + message);
+ e.printStackTrace(System.err);
+ }
+}
\ No newline at end of file
diff --git b/flyway-commandline/src/main/java/org/flywaydb/commandline/ConsoleLogCreator.java a/flyway-commandline/src/main/java/org/flywaydb/commandline/ConsoleLogCreator.java
new file mode 100644
index 0000000..ced631d
--- /dev/null
+++ a/flyway-commandline/src/main/java/org/flywaydb/commandline/ConsoleLogCreator.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.commandline;
+
+import org.flywaydb.commandline.CommandLineArguments.Color;
+import org.flywaydb.core.api.logging.Log;
+import org.flywaydb.core.api.logging.LogCreator;
+
+/**
+ * Log Creator for the Command-Line console.
+ */
+class ConsoleLogCreator implements LogCreator {
+ private final CommandLineArguments commandLineArguments;
+
+ /**
+ * Creates a new Console Log Creator.
+ *
+ * @param commandLineArguments The command line arguments.
+ */
+ ConsoleLogCreator(CommandLineArguments commandLineArguments) {
+ this.commandLineArguments = commandLineArguments;
+ }
+
+ public Log createLogger(Class> clazz) {
+ ConsoleLog log = new ConsoleLog(commandLineArguments.getLogLevel());
+ Color color = commandLineArguments.getColor();
+
+ if (Color.NEVER.equals(color) || (Color.AUTO.equals(color) && System.console() == null)) {
+ return log;
+ }
+
+ ColorizedConsoleLog.install(Color.ALWAYS.equals(color));
+ return new ColorizedConsoleLog(log);
+ }
+}
\ No newline at end of file
diff --git b/flyway-commandline/src/main/java/org/flywaydb/commandline/FileLog.java a/flyway-commandline/src/main/java/org/flywaydb/commandline/FileLog.java
new file mode 100644
index 0000000..8decc30
--- /dev/null
+++ a/flyway-commandline/src/main/java/org/flywaydb/commandline/FileLog.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.commandline;
+
+import org.flywaydb.commandline.ConsoleLog.Level;
+import org.flywaydb.core.api.FlywayException;
+import org.flywaydb.core.api.logging.Log;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+
+class FileLog implements Log {
+
+ private final Path path;
+ private final Level level;
+
+ public FileLog(Path path, Level level) {
+ this.path = path;
+ this.level = level;
+ }
+
+ @Override
+ public boolean isDebugEnabled() {
+ return level == Level.DEBUG;
+ }
+
+ @Override
+ public void debug(String message) {
+ if (isDebugEnabled()) {
+ writeLogMessage("DEBUG", message);
+ }
+ }
+
+ @Override
+ public void info(String message) {
+ if (level.compareTo(Level.INFO) <= 0) {
+ writeLogMessage(message);
+ }
+ }
+
+ @Override
+ public void warn(String message) {
+ writeLogMessage("WARNING", message);
+ }
+
+ @Override
+ public void error(String message) {
+ writeLogMessage("ERROR", message);
+ }
+
+ @Override
+ public void error(String message, Exception e) {
+ StringWriter stringWriter = new StringWriter();
+ e.printStackTrace(new PrintWriter(stringWriter));
+ String stackTrace = stringWriter.toString();
+
+ writeLogMessage("ERROR", message);
+ writeLogMessage(stackTrace);
+ }
+
+ private void writeLogMessage(String prefix, String message) {
+ String logMessage = prefix + ": " + message;
+ writeLogMessage(logMessage);
+ }
+
+ private void writeLogMessage(String logMessage) {
+ try {
+ Files.write(path, (logMessage + "\n").getBytes(), StandardOpenOption.APPEND, StandardOpenOption.WRITE);
+ } catch(IOException exception) {
+ throw new FlywayException("Could not write to file at " + path + ".", exception);
+ }
+ }
+}
\ No newline at end of file
diff --git b/flyway-commandline/src/main/java/org/flywaydb/commandline/FileLogCreator.java a/flyway-commandline/src/main/java/org/flywaydb/commandline/FileLogCreator.java
new file mode 100644
index 0000000..2434c49
--- /dev/null
+++ a/flyway-commandline/src/main/java/org/flywaydb/commandline/FileLogCreator.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.commandline;
+
+import org.flywaydb.core.api.FlywayException;
+import org.flywaydb.core.api.logging.Log;
+import org.flywaydb.core.api.logging.LogCreator;
+import org.flywaydb.commandline.ConsoleLog.Level;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+
+/**
+ * Log Creator for logging to a file
+ */
+class FileLogCreator implements LogCreator {
+ private final Level level;
+ private final Path path;
+
+ /**
+ * Creates a new file Log Creator.
+ *
+ * @param commandLineArguments The command line arguments
+ */
+ FileLogCreator(CommandLineArguments commandLineArguments) {
+ String outputFilepath = "";
+
+ if (commandLineArguments.isOutputFileSet()) {
+ outputFilepath = commandLineArguments.getOutputFile();
+ } else if (commandLineArguments.isLogFilepathSet()) {
+ outputFilepath = commandLineArguments.getLogFilepath();
+ }
+
+ this.level = commandLineArguments.getLogLevel();
+ this.path = Paths.get(outputFilepath);
+
+ prepareOutputFile(path);
+ }
+
+ public Log createLogger(Class> clazz) {
+ return new FileLog(path, level);
+ }
+
+ private static void prepareOutputFile(Path path) {
+ try {
+ Files.write(path, "".getBytes(), StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);
+ } catch(IOException exception) {
+ throw new FlywayException("Could not initialize log file at " + path + ".", exception);
+ }
+ }
+}
\ No newline at end of file
diff --git b/flyway-commandline/src/main/java/org/flywaydb/commandline/Main.java a/flyway-commandline/src/main/java/org/flywaydb/commandline/Main.java
new file mode 100644
index 0000000..f11cc16
--- /dev/null
+++ a/flyway-commandline/src/main/java/org/flywaydb/commandline/Main.java
@@ -0,0 +1,592 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.commandline;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.flywaydb.commandline.ConsoleLog.Level;
+import org.flywaydb.core.Flyway;
+import org.flywaydb.core.api.*;
+import org.flywaydb.core.api.logging.Log;
+import org.flywaydb.core.api.logging.LogCreator;
+import org.flywaydb.core.api.logging.LogFactory;
+import org.flywaydb.core.internal.configuration.ConfigUtils;
+import org.flywaydb.core.internal.info.MigrationInfoDumper;
+import org.flywaydb.core.internal.jdbc.DriverDataSource;
+import org.flywaydb.core.internal.license.VersionPrinter;
+import org.flywaydb.core.internal.output.ErrorOutput;
+import org.flywaydb.core.internal.util.ClassUtils;
+import org.flywaydb.core.internal.util.FileCopyUtils;
+import org.flywaydb.core.internal.util.StringUtils;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.*;
+
+/**
+ * Main class and central entry point of the Flyway command-line tool.
+ */
+public class Main {
+ private static Log LOG;
+
+ static LogCreator getLogCreator(CommandLineArguments commandLineArguments) {
+ // JSON output uses a different mechanism, so we do not create any loggers
+ if (commandLineArguments.shouldOutputJson()) {
+ return MultiLogCreator.empty();
+ }
+
+ List logCreators = new ArrayList<>();
+
+ logCreators.add(new ConsoleLogCreator(commandLineArguments));
+
+ if (commandLineArguments.isOutputFileSet() || commandLineArguments.isLogFilepathSet()) {
+ logCreators.add(new FileLogCreator(commandLineArguments));
+ }
+
+ return new MultiLogCreator(logCreators);
+ }
+
+ /**
+ * Initializes the logging.
+ */
+ static void initLogging(CommandLineArguments commandLineArguments) {
+ LogCreator logCreator = getLogCreator(commandLineArguments);
+ LogFactory.setFallbackLogCreator(logCreator);
+ LOG = LogFactory.getLog(Main.class);
+ }
+
+ /**
+ * Main method.
+ *
+ * @param args The command-line arguments.
+ */
+ public static void main(String[] args) {
+ CommandLineArguments commandLineArguments = new CommandLineArguments(args);
+ initLogging(commandLineArguments);
+
+ try {
+ commandLineArguments.validate(LOG);
+
+ if (commandLineArguments.shouldPrintVersionAndExit()) {
+ printVersion();
+ System.exit(0);
+ }
+
+ if (commandLineArguments.hasOperation("help") || commandLineArguments.shouldPrintUsage()) {
+ printUsage();
+ return;
+ }
+
+ Map envVars = ConfigUtils.environmentVariablesToPropertyMap();
+
+ Map config = new HashMap<>();
+ initializeDefaults(config, commandLineArguments);
+ loadConfigurationFromConfigFiles(config, commandLineArguments, envVars);
+ config.putAll(readConfigFromInputStream(System.in));
+
+ if (commandLineArguments.isWorkingDirectorySet()) {
+ makeRelativeLocationsBasedOnWorkingDirectory(commandLineArguments, config);
+ }
+
+ config.putAll(envVars);
+ config = overrideConfiguration(config, commandLineArguments.getConfiguration());
+
+ if (!commandLineArguments.shouldSuppressPrompt()) {
+ promptForCredentialsIfMissing(config);
+ }
+
+ ConfigUtils.dumpConfiguration(config);
+
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ List jarFiles = new ArrayList<>();
+ jarFiles.addAll(getJdbcDriverJarFiles());
+ jarFiles.addAll(getJavaMigrationJarFiles(config));
+ if (!jarFiles.isEmpty()) {
+ classLoader = ClassUtils.addJarsOrDirectoriesToClasspath(classLoader, jarFiles);
+ }
+ filterProperties(config);
+ Flyway flyway = Flyway.configure(classLoader).configuration(config).load();
+
+ for (String operation : commandLineArguments.getOperations()) {
+ executeOperation(flyway, operation, commandLineArguments);
+ }
+ } catch (Exception e) {
+ if (commandLineArguments.shouldOutputJson()) {
+ ErrorOutput errorOutput = ErrorOutput.fromException(e);
+ printJson(commandLineArguments, errorOutput);
+ } else {
+ if (commandLineArguments.getLogLevel() == Level.DEBUG) {
+ LOG.error("Unexpected error", e);
+ } else {
+ LOG.error(getMessagesFromException(e));
+ }
+ }
+ System.exit(1);
+ }
+ }
+
+ private static void makeRelativeLocationsBasedOnWorkingDirectory(CommandLineArguments commandLineArguments, Map config) {
+ String[] locations = config.get(ConfigUtils.LOCATIONS).split(",");
+ for (int i = 0; i < locations.length; i++) {
+ if (locations[i].startsWith(Location.FILESYSTEM_PREFIX)) {
+ String newLocation = locations[i].substring(Location.FILESYSTEM_PREFIX.length());
+ File file = new File(newLocation);
+ if (!file.isAbsolute()) {
+ file = new File(commandLineArguments.getWorkingDirectory(), newLocation);
+ }
+ locations[i] = Location.FILESYSTEM_PREFIX + file.getAbsolutePath();
+ }
+ }
+
+ config.put(ConfigUtils.LOCATIONS, StringUtils.arrayToCommaDelimitedString(locations));
+ }
+
+ private static Map overrideConfiguration(Map existingConfiguration, Map newConfiguration) {
+ Map combinedConfiguration = new HashMap<>();
+
+ combinedConfiguration.putAll(existingConfiguration);
+ combinedConfiguration.putAll(newConfiguration);
+
+ return combinedConfiguration;
+ }
+
+
+ static String getMessagesFromException(Throwable e) {
+ String condensedMessages = "";
+ String preamble = "";
+ while (e != null) {
+ if (e instanceof FlywayException) {
+ condensedMessages += preamble + e.getMessage();
+ } else {
+ condensedMessages += preamble + e.toString();
+ }
+ preamble = "\r\nCaused by: ";
+ e = e.getCause();
+ }
+ return condensedMessages;
+ }
+
+
+ /**
+ * Executes this operation on this Flyway instance.
+ *
+ * @param flyway The Flyway instance.
+ * @param operation The operation to execute.
+ */
+ private static void executeOperation(Flyway flyway, String operation, CommandLineArguments commandLineArguments) {
+ if ("clean".equals(operation)) {
+ flyway.clean();
+ } else if ("baseline".equals(operation)) {
+ flyway.baseline();
+ } else if ("migrate".equals(operation)) {
+ flyway.migrate();
+ } else if ("undo".equals(operation)) {
+ flyway.undo();
+ } else if ("validate".equals(operation)) {
+ flyway.validate();
+ } else if ("info".equals(operation)) {
+ MigrationInfoService info = flyway.info();
+ MigrationInfo current = info.current();
+ MigrationVersion currentSchemaVersion = current == null ? MigrationVersion.EMPTY : current.getVersion();
+
+ MigrationVersion schemaVersionToOutput = currentSchemaVersion == null ? MigrationVersion.EMPTY : currentSchemaVersion;
+ LOG.info("Schema version: " + schemaVersionToOutput);
+ LOG.info("");
+ LOG.info(MigrationInfoDumper.dumpToAsciiTable(info.all()));
+
+ if (commandLineArguments.shouldOutputJson()) {
+ printJson(commandLineArguments, info.getInfoOutput());
+ }
+ } else if ("repair".equals(operation)) {
+ flyway.repair();
+ } else {
+ LOG.error("Invalid operation: " + operation);
+ printUsage();
+ System.exit(1);
+ }
+ }
+
+ private static void printJson(CommandLineArguments commandLineArguments, Object object) {
+ String json = convertObjectToJsonString(object);
+
+ if (commandLineArguments.isOutputFileSet()) {
+ Path path = Paths.get(commandLineArguments.getOutputFile());
+ byte[] bytes = json.getBytes();
+
+ try {
+ Files.write(path, bytes, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);
+ } catch (IOException e) {
+ throw new FlywayException("Could not write to output file " + commandLineArguments.getOutputFile(), e);
+ }
+ }
+
+ System.out.println(json);
+ }
+
+ private static String convertObjectToJsonString(Object object) {
+ Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
+ return gson.toJson(object);
+ }
+
+ /**
+ * Initializes the config with the default configuration for the command-line tool.
+ *
+ * @param config The config object to initialize.
+ */
+ private static void initializeDefaults(Map config, CommandLineArguments commandLineArguments) {
+ // To maintain override order, return extension value first if present
+ String workingDirectory = commandLineArguments.isWorkingDirectorySet() ? commandLineArguments.getWorkingDirectory() : getInstallationDir();
+
+ config.put(ConfigUtils.LOCATIONS, "filesystem:" + new File(workingDirectory, "sql").getAbsolutePath());
+ config.put(ConfigUtils.JAR_DIRS, new File(workingDirectory, "jars").getAbsolutePath());
+ }
+
+
+ /**
+ * Filters there properties to remove the Flyway Commandline-specific ones.
+ *
+ * @param config The properties to filter.
+ */
+ private static void filterProperties(Map config) {
+ config.remove(ConfigUtils.JAR_DIRS);
+ config.remove(ConfigUtils.CONFIG_FILES);
+ config.remove(ConfigUtils.CONFIG_FILE_ENCODING);
+ }
+
+ /**
+ * Prints the version number on the console.
+ */
+ private static void printVersion() {
+ VersionPrinter.printVersionOnly();
+ LOG.info("");
+
+ LOG.debug("Java " + System.getProperty("java.version") + " (" + System.getProperty("java.vendor") + ")");
+ LOG.debug(System.getProperty("os.name") + " " + System.getProperty("os.version") + " " + System.getProperty("os.arch") + "\n");
+ }
+
+ /**
+ * Prints the usage instructions on the console.
+ */
+ private static void printUsage() {
+ LOG.info("Usage");
+ LOG.info("=====");
+ LOG.info("");
+ LOG.info("flyway [options] command");
+ LOG.info("");
+ LOG.info("By default, the configuration will be read from conf/flyway.conf.");
+ LOG.info("Options passed from the command-line override the configuration.");
+ LOG.info("");
+ LOG.info("Commands");
+ LOG.info("--------");
+ LOG.info("migrate : Migrates the database");
+ LOG.info("clean : Drops all objects in the configured schemas");
+ LOG.info("info : Prints the information about applied, current and pending migrations");
+ LOG.info("validate : Validates the applied migrations against the ones on the classpath");
+ LOG.info("undo : [" + "pro] Undoes the most recently applied versioned migration");
+ LOG.info("baseline : Baselines an existing database at the baselineVersion");
+ LOG.info("repair : Repairs the schema history table");
+ LOG.info("");
+ LOG.info("Options (Format: -key=value)");
+ LOG.info("-------");
+ LOG.info("driver : Fully qualified classname of the JDBC driver");
+ LOG.info("url : Jdbc url to use to connect to the database");
+ LOG.info("user : User to use to connect to the database");
+ LOG.info("password : Password to use to connect to the database");
+ LOG.info("connectRetries : Maximum number of retries when attempting to connect to the database");
+ LOG.info("initSql : SQL statements to run to initialize a new database connection");
+ LOG.info("schemas : Comma-separated list of the schemas managed by Flyway");
+ LOG.info("table : Name of Flyway's schema history table");
+ LOG.info("locations : Classpath locations to scan recursively for migrations");
+ LOG.info("resolvers : Comma-separated list of custom MigrationResolvers");
+ LOG.info("skipDefaultResolvers : Skips default resolvers (jdbc, sql and Spring-jdbc)");
+ LOG.info("sqlMigrationPrefix : File name prefix for versioned SQL migrations");
+ LOG.info("undoSqlMigrationPrefix : [" + "pro] File name prefix for undo SQL migrations");
+ LOG.info("repeatableSqlMigrationPrefix : File name prefix for repeatable SQL migrations");
+ LOG.info("sqlMigrationSeparator : File name separator for SQL migrations");
+ LOG.info("sqlMigrationSuffixes : Comma-separated list of file name suffixes for SQL migrations");
+ LOG.info("stream : [" + "pro] Stream SQL migrations when executing them");
+ LOG.info("batch : [" + "pro] Batch SQL statements when executing them");
+ LOG.info("mixed : Allow mixing transactional and non-transactional statements");
+ LOG.info("encoding : Encoding of SQL migrations");
+ LOG.info("placeholderReplacement : Whether placeholders should be replaced");
+ LOG.info("placeholders : Placeholders to replace in sql migrations");
+ LOG.info("placeholderPrefix : Prefix of every placeholder");
+ LOG.info("placeholderSuffix : Suffix of every placeholder");
+ LOG.info("installedBy : Username that will be recorded in the schema history table");
+ LOG.info("target : Target version up to which Flyway should use migrations");
+ LOG.info("outOfOrder : Allows migrations to be run \"out of order\"");
+ LOG.info("callbacks : Comma-separated list of FlywayCallback classes");
+ LOG.info("skipDefaultCallbacks : Skips default callbacks (sql)");
+ LOG.info("validateOnMigrate : Validate when running migrate");
+ LOG.info("validateMigrationNaming : Validate file names of SQL migrations (including callbacks)");
+ LOG.info("ignoreMissingMigrations : Allow missing migrations when validating");
+ LOG.info("ignoreIgnoredMigrations : Allow ignored migrations when validating");
+ LOG.info("ignorePendingMigrations : Allow pending migrations when validating");
+ LOG.info("ignoreFutureMigrations : Allow future migrations when validating");
+ LOG.info("cleanOnValidationError : Automatically clean on a validation error");
+ LOG.info("cleanDisabled : Whether to disable clean");
+ LOG.info("baselineVersion : Version to tag schema with when executing baseline");
+ LOG.info("baselineDescription : Description to tag schema with when executing baseline");
+ LOG.info("baselineOnMigrate : Baseline on migrate against uninitialized non-empty schema");
+ LOG.info("configFiles : Comma-separated list of config files to use");
+ LOG.info("configFileEncoding : Encoding to use when loading the config files");
+ LOG.info("jarDirs : Comma-separated list of dirs for Jdbc drivers & Java migrations");
+ LOG.info("createSchemas : Whether Flyway should attempt to create the schemas specified in the schemas property");
+ LOG.info("dryRunOutput : [" + "pro] File where to output the SQL statements of a migration dry run");
+ LOG.info("errorOverrides : [" + "pro] Rules to override specific SQL states and errors codes");
+ LOG.info("oracle.sqlplus : [" + "pro] Enable Oracle SQL*Plus command support");
+ LOG.info("licenseKey : [" + "pro] Your Flyway license key");
+ LOG.info("color : Whether to colorize output. Values: always, never, or auto (default)");
+ LOG.info("outputFile : Send output to the specified file alongside the console");
+ LOG.info("");
+ LOG.info("Flags");
+ LOG.info("-----");
+ LOG.info("-X : Print debug output");
+ LOG.info("-q : Suppress all output, except for errors and warnings");
+ LOG.info("-n : Suppress prompting for a user and password");
+ LOG.info("-v : Print the Flyway version and exit");
+ LOG.info("-? : Print this usage info and exit");
+ LOG.info("-json : Print the output in JSON format");
+ LOG.info("-community : Run the Flyway Community Edition (default)");
+ LOG.info("-pro : Run the Flyway Pro Edition");
+ LOG.info("-enterprise : Run the Flyway Enterprise Edition");
+ LOG.info("");
+ LOG.info("Example");
+ LOG.info("-------");
+ LOG.info("flyway -user=myuser -password=s3cr3t -url=jdbc:h2:mem -placeholders.abc=def migrate");
+ LOG.info("");
+ LOG.info("More info at https://flywaydb.org/documentation/commandline");
+ }
+
+ /**
+ * Gets the jar files of all the JDBC drivers contained in the drivers folder.
+ *
+ * @return The jar files.
+ */
+ private static List getJdbcDriverJarFiles() {
+ File driversDir = new File(getInstallationDir(), "drivers");
+ File[] files = driversDir.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.endsWith(".jar");
+ }
+ });
+
+ // see javadoc of listFiles(): null if given path is not a real directory
+ if (files == null) {
+ LOG.debug("Directory for Jdbc Drivers not found: " + driversDir.getAbsolutePath());
+ return Collections.emptyList();
+ }
+
+ return Arrays.asList(files);
+ }
+
+ /**
+ * Gets all the jar files contained in the jars folder. (For Java Migrations)
+ *
+ * @param config The configured properties.
+ * @return The jar files.
+ */
+ private static List getJavaMigrationJarFiles(Map config) {
+ String jarDirs = config.get(ConfigUtils.JAR_DIRS);
+ if (!StringUtils.hasLength(jarDirs)) {
+ return Collections.emptyList();
+ }
+
+ jarDirs = jarDirs.replace(File.pathSeparator, ",");
+ String[] dirs = StringUtils.tokenizeToStringArray(jarDirs, ",");
+
+ List jarFiles = new ArrayList<>();
+ for (String dirName : dirs) {
+ File dir = new File(dirName);
+ File[] files = dir.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.endsWith(".jar");
+ }
+ });
+
+ // see javadoc of listFiles(): null if given path is not a real directory
+ if (files == null) {
+ LOG.error("Directory for Java Migrations not found: " + dirName);
+ System.exit(1);
+ }
+
+ jarFiles.addAll(Arrays.asList(files));
+ }
+
+ return jarFiles;
+ }
+
+ /**
+ * Loads the configuration from the various possible locations.
+ *
+ * @param config The properties object to load to configuration into.
+ * @param commandLineArguments The command-line arguments passed in.
+ * @param envVars The environment variables, converted into properties.
+ */
+ /* private -> for testing */
+ static void loadConfigurationFromConfigFiles(Map config, CommandLineArguments commandLineArguments, Map envVars) {
+ String encoding = determineConfigurationFileEncoding(commandLineArguments, envVars);
+ File installationDir = new File(getInstallationDir());
+
+ config.putAll(ConfigUtils.loadDefaultConfigurationFiles(installationDir, encoding));
+
+ for (File configFile : determineConfigFilesFromArgs(commandLineArguments, envVars)) {
+ config.putAll(ConfigUtils.loadConfigurationFile(configFile, encoding, true));
+ }
+ }
+
+ /* private -> for testing */
+ static Map readConfigFromInputStream(InputStream inputStream) {
+ Map config = new HashMap<>();
+
+ try {
+ // System.in.available() : returns an estimate of the number of bytes that can be read (or skipped over) from this input stream
+ // Used to check if there is any data in the stream
+ if (inputStream != null && inputStream.available() > 0) {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
+
+ LOG.debug("Attempting to load configuration from standard input");
+ int firstCharacter = bufferedReader.read();
+
+ if (bufferedReader.ready() && firstCharacter != -1) {
+ // Prepend the first character to the rest of the string
+ // This is a char, represented as an int, so we cast to a char
+ // which is implicitly converted to an string
+ String configurationString = (char)firstCharacter + FileCopyUtils.copyToString(bufferedReader);
+ Map configurationFromStandardInput = ConfigUtils.loadConfigurationFromString(configurationString);
+
+ if (configurationFromStandardInput.isEmpty()) {
+ LOG.debug("Empty configuration provided from standard input");
+ } else {
+ LOG.info("Loaded configuration from standard input");
+ config.putAll(configurationFromStandardInput);
+ }
+ } else {
+ LOG.debug("Could not load configuration from standard input");
+ }
+ }
+ } catch (Exception e) {
+ LOG.debug("Could not load configuration from standard input " + e.getMessage());
+ }
+
+ return config;
+ }
+
+ /**
+ * If no user or password has been provided, prompt for it. If you want to avoid the prompt,
+ * pass in an empty user or password.
+ *
+ * @param config The properties object to load to configuration into.
+ */
+ private static void promptForCredentialsIfMissing(Map config) {
+ Console console = System.console();
+ if (console == null) {
+ // We are running in an automated build. Prompting is not possible.
+ return;
+ }
+
+ if (!config.containsKey(ConfigUtils.URL)) {
+ // URL is not set. We are doomed for failure anyway.
+ return;
+ }
+
+ String url = config.get(ConfigUtils.URL);
+ if (!config.containsKey(ConfigUtils.USER) && needsUser(url)) {
+ config.put(ConfigUtils.USER, console.readLine("Database user: "));
+ }
+
+ if (!config.containsKey(ConfigUtils.PASSWORD) && needsPassword(url)) {
+ char[] password = console.readPassword("Database password: ");
+ config.put(ConfigUtils.PASSWORD, password == null ? "" : String.valueOf(password));
+ }
+ }
+
+ /**
+ * Detect whether the JDBC URL specifies a known authentication mechanism that does not need a username.
+ */
+ private static boolean needsUser(String url) {
+ return DriverDataSource.detectUserRequiredByUrl(url);
+ }
+
+ /**
+ * Detect whether the JDBC URL specifies a known authentication mechanism that does not need a password.
+ */
+ private static boolean needsPassword(String url) {
+ return DriverDataSource.detectPasswordRequiredByUrl(url);
+ }
+
+ /**
+ * Determines the files to use for loading the configuration.
+ *
+ * @param commandLineArguments The command-line arguments passed in.
+ * @param envVars The environment variables converted to Flyway properties.
+ * @return The configuration files.
+ */
+ private static List determineConfigFilesFromArgs(CommandLineArguments commandLineArguments, Map envVars) {
+ List configFiles = new ArrayList<>();
+
+ String workingDirectory = commandLineArguments.isWorkingDirectorySet() ? commandLineArguments.getWorkingDirectory() : null;
+
+ if (envVars.containsKey(ConfigUtils.CONFIG_FILES)) {
+ for (String file : StringUtils.tokenizeToStringArray(envVars.get(ConfigUtils.CONFIG_FILES), ",")) {
+ configFiles.add(new File(workingDirectory, file));
+ }
+ return configFiles;
+ }
+
+
+ for (String file : commandLineArguments.getConfigFiles()) {
+ configFiles.add(new File(workingDirectory, file));
+ }
+
+ return configFiles;
+ }
+
+ /**
+ * @return The installation directory of the Flyway Command-line tool.
+ */
+ @SuppressWarnings("ConstantConditions")
+ private static String getInstallationDir() {
+ String path = ClassUtils.getLocationOnDisk(Main.class);
+ return new File(path) // jar file
+ .getParentFile() // edition dir
+ .getParentFile() // lib dir
+ .getParentFile() // installation dir
+ .getAbsolutePath();
+ }
+
+ /**
+ * Determines the encoding to use for loading the configuration.
+ *
+ * @param commandLineArguments The command-line arguments passed in.
+ * @param envVars The environment variables converted to Flyway properties.
+ * @return The encoding. (default: UTF-8)
+ */
+ private static String determineConfigurationFileEncoding(CommandLineArguments commandLineArguments, Map envVars) {
+ if (envVars.containsKey(ConfigUtils.CONFIG_FILE_ENCODING)) {
+ return envVars.get(ConfigUtils.CONFIG_FILE_ENCODING);
+ }
+
+ if (commandLineArguments.isConfigFileEncodingSet()) {
+ return commandLineArguments.getConfigFileEncoding();
+ }
+
+ return "UTF-8";
+ }
+}
\ No newline at end of file
diff --git b/flyway-commandline/src/main/java/org/flywaydb/commandline/MultiLogCreator.java a/flyway-commandline/src/main/java/org/flywaydb/commandline/MultiLogCreator.java
new file mode 100644
index 0000000..fa97279
--- /dev/null
+++ a/flyway-commandline/src/main/java/org/flywaydb/commandline/MultiLogCreator.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.commandline;
+
+import org.flywaydb.core.api.logging.Log;
+import org.flywaydb.core.api.logging.LogCreator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Log creator for a MultiLog
+ */
+class MultiLogCreator implements LogCreator {
+ private final List logCreators;
+
+ MultiLogCreator(List logCreators) {
+ this.logCreators = logCreators;
+ }
+
+ @Override
+ public Log createLogger(Class> clazz) {
+ List logs = new ArrayList<>();
+
+ for (LogCreator logCreator : logCreators) {
+ logs.add(logCreator.createLogger(clazz));
+ }
+
+ return new MultiLogger(logs);
+ }
+
+ static MultiLogCreator empty() {
+ return new MultiLogCreator(new ArrayList<>());
+ }
+}
\ No newline at end of file
diff --git b/flyway-commandline/src/main/java/org/flywaydb/commandline/MultiLogger.java a/flyway-commandline/src/main/java/org/flywaydb/commandline/MultiLogger.java
new file mode 100644
index 0000000..4aedaaa
--- /dev/null
+++ a/flyway-commandline/src/main/java/org/flywaydb/commandline/MultiLogger.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.commandline;
+
+import org.flywaydb.core.api.logging.Log;
+
+import java.util.List;
+
+/**
+ * Log implementation that forwards method calls to multiple implementations
+ */
+class MultiLogger implements Log {
+
+ private final List logs;
+
+ public MultiLogger(List logs) {
+ this.logs = logs;
+ }
+
+ @Override
+ public boolean isDebugEnabled() {
+ for (Log log : logs) {
+ if (!log.isDebugEnabled()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public void debug(String message) {
+ for (Log log : logs) {
+ log.debug(message);
+ }
+ }
+
+ @Override
+ public void info(String message) {
+ for (Log log : logs) {
+ log.info(message);
+ }
+ }
+
+ @Override
+ public void warn(String message) {
+ for (Log log : logs) {
+ log.warn(message);
+ }
+ }
+
+ @Override
+ public void error(String message) {
+ for (Log log : logs) {
+ log.error(message);
+ }
+ }
+
+ @Override
+ public void error(String message, Exception e) {
+ for (Log log : logs) {
+ log.error(message, e);
+ }
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/pom.xml a/flyway-core/pom.xml
new file mode 100644
index 0000000..8f820b3
--- /dev/null
+++ a/flyway-core/pom.xml
@@ -0,0 +1,355 @@
+
+
+ 4.0.0
+
+ org.flywaydb
+ flyway-parent
+ 0-SNAPSHOT
+
+ flyway-core
+ jar
+ ${project.artifactId}
+
+
+ org.slf4j
+ slf4j-api
+ true
+
+
+ commons-logging
+ commons-logging
+ true
+
+
+ org.jboss
+ jboss-vfs
+ true
+
+
+ org.osgi
+ org.osgi.core
+ true
+ provided
+
+
+ com.google.android
+ android
+ true
+
+
+ org.postgresql
+ postgresql
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ src/main/resources
+ true
+
+
+
+
+ maven-resources-plugin
+
+
+ copy-license
+
+ copy-resources
+
+ generate-resources
+
+
+
+ ..
+
+ LICENSE.txt
+ README.txt
+
+
+
+ ${project.build.outputDirectory}/META-INF
+
+
+
+
+
+ maven-jar-plugin
+
+
+ ${project.build.outputDirectory}/META-INF/MANIFEST.MF
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+
+
+ org.flywaydb.core
+ org.flywaydb.core
+
+ org.flywaydb.core;version=${project.version},
+ org.flywaydb.core.api.*;version=${project.version}
+
+
+ android.content;version="[4.0.1.2,9)";resolution:=optional,
+ android.content.pm;version="[4.0.1.2,9)";resolution:=optional,
+ android.content.res;version="[4.0.1.2,9)";resolution:=optional,
+ android.util;version="[4.0.1.2,9)";resolution:=optional,
+ dalvik.system;version="[4.0.1.2,9)";resolution:=optional,
+ javax.sql,
+ org.apache.commons.logging;version="[1.1,2)";resolution:=optional,
+ org.jboss.vfs;version="[3.1.0,4)";resolution:=optional,
+ org.postgresql.copy;version="[9.3.1102,100.0)";resolution:=optional,
+ org.postgresql.core;version="[9.3.1102,100.0)";resolution:=optional,
+ org.osgi.framework;version="1.3.0";resolution:=mandatory,
+ org.slf4j;version="[1.6,2)";resolution:=optional,
+ org.springframework.*;version="[2.5,6.0)";resolution:=optional
+
+
+
+
+
+ bundle-manifest
+ process-classes
+
+ manifest
+
+
+
+
+
+ maven-javadoc-plugin
+
+
+ **/core/Flyway.java
+ **/core/api/**/*.java
+
+
+
+
+
+
+
+
+
+ maven-javadoc-plugin
+ 3.0.1
+
+
+ **/core/Flyway.java
+ **/core/api/**/*.java
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/Flyway.java a/flyway-core/src/main/java/org/flywaydb/core/Flyway.java
new file mode 100644
index 0000000..a27c780
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/Flyway.java
@@ -0,0 +1,730 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core;
+
+import org.flywaydb.core.api.FlywayException;
+import org.flywaydb.core.api.MigrationInfoService;
+import org.flywaydb.core.api.callback.Callback;
+import org.flywaydb.core.api.configuration.ClassicConfiguration;
+import org.flywaydb.core.api.configuration.Configuration;
+import org.flywaydb.core.api.configuration.FluentConfiguration;
+import org.flywaydb.core.api.logging.Log;
+import org.flywaydb.core.api.logging.LogFactory;
+import org.flywaydb.core.api.migration.JavaMigration;
+import org.flywaydb.core.api.resolver.MigrationResolver;
+import org.flywaydb.core.internal.callback.*;
+import org.flywaydb.core.api.ClassProvider;
+import org.flywaydb.core.internal.clazz.NoopClassProvider;
+import org.flywaydb.core.internal.command.*;
+import org.flywaydb.core.internal.configuration.ConfigurationValidator;
+import org.flywaydb.core.internal.database.DatabaseFactory;
+import org.flywaydb.core.internal.database.base.Database;
+import org.flywaydb.core.internal.database.base.Schema;
+import org.flywaydb.core.internal.jdbc.JdbcConnectionFactory;
+import org.flywaydb.core.internal.license.VersionPrinter;
+import org.flywaydb.core.internal.parser.ParsingContext;
+import org.flywaydb.core.internal.resolver.CompositeMigrationResolver;
+import org.flywaydb.core.internal.resource.NoopResourceProvider;
+import org.flywaydb.core.api.ResourceProvider;
+import org.flywaydb.core.internal.resource.StringResource;
+import org.flywaydb.core.internal.resource.ResourceNameValidator;
+import org.flywaydb.core.internal.scanner.LocationScannerCache;
+import org.flywaydb.core.internal.scanner.ResourceNameCache;
+import org.flywaydb.core.internal.scanner.Scanner;
+import org.flywaydb.core.internal.schemahistory.SchemaHistory;
+import org.flywaydb.core.internal.schemahistory.SchemaHistoryFactory;
+import org.flywaydb.core.internal.sqlscript.SqlScript;
+import org.flywaydb.core.internal.sqlscript.SqlScriptExecutorFactory;
+import org.flywaydb.core.internal.sqlscript.SqlScriptFactory;
+import org.flywaydb.core.internal.util.IOUtils;
+import org.flywaydb.core.internal.util.Pair;
+import org.flywaydb.core.internal.util.StringUtils;
+
+import java.sql.Connection;
+import java.util.*;
+
+/**
+ * This is the centre point of Flyway, and for most users, the only class they will ever have to deal with.
+ *
+ * It is THE public API from which all important Flyway functions such as clean, validate and migrate can be called.
+ *
+ *
To get started all you need to do is create a configured Flyway object and then invoke its principal methods.
+ * Note that a configured Flyway object is immutable. If you change the configuration you will end up creating a new Flyway
+ * object.
+ *
+ */
+public class Flyway {
+ private static final Log LOG = LogFactory.getLog(Flyway.class);
+
+ private final ClassicConfiguration configuration;
+
+ /**
+ * Whether the database connection info has already been printed in the logs.
+ */
+ private boolean dbConnectionInfoPrinted;
+
+ /**
+ * Designed so we can fail fast if the configuration is invalid
+ */
+ private ConfigurationValidator configurationValidator = new ConfigurationValidator();
+
+ /**
+ * Designed so we can fail fast if the SQL file resources are invalid
+ */
+ private ResourceNameValidator resourceNameValidator = new ResourceNameValidator();
+
+ /**
+ * This is your starting point. This creates a configuration which can be customized to your needs before being
+ * loaded into a new Flyway instance using the load() method.
+ *
In its simplest form, this is how you configure Flyway with all defaults to get started:
After that you have a fully-configured Flyway instance at your disposal which can be used to invoke Flyway
+ * functionality such as migrate() or clean().
+ *
+ * @return A new configuration from which Flyway can be loaded.
+ */
+ public static FluentConfiguration configure() {
+ return new FluentConfiguration();
+ }
+
+ /**
+ * This is your starting point. This creates a configuration which can be customized to your needs before being
+ * loaded into a new Flyway instance using the load() method.
+ *
In its simplest form, this is how you configure Flyway with all defaults to get started:
After that you have a fully-configured Flyway instance at your disposal which can be used to invoke Flyway
+ * functionality such as migrate() or clean().
+ *
+ * @param classLoader The class loader to use when loading classes and resources.
+ * @return A new configuration from which Flyway can be loaded.
+ */
+ public static FluentConfiguration configure(ClassLoader classLoader) {
+ return new FluentConfiguration(classLoader);
+ }
+
+ /**
+ * Creates a new instance of Flyway with this configuration. In general the Flyway.configure() factory method should
+ * be preferred over this constructor, unless you need to create or reuse separate Configuration objects.
+ *
+ * @param configuration The configuration to use.
+ */
+ public Flyway(Configuration configuration) {
+ this.configuration = new ClassicConfiguration(configuration);
+ }
+
+ /**
+ * @return The configuration that Flyway is using.
+ */
+ public Configuration getConfiguration() {
+ return new ClassicConfiguration(configuration);
+ }
+
+ /**
+ * Used to cache resource names for classpath scanning between commands
+ */
+ private ResourceNameCache resourceNameCache = new ResourceNameCache();
+
+ /**
+ * Used to cache LocationScanners between commands
+ */
+ private final LocationScannerCache locationScannerCache = new LocationScannerCache();
+
+ /**
+ *
Starts the database migration. All pending migrations will be applied in order.
+ * Calling migrate on an up-to-date database has no effect.
+ *
+ *
+ * @return The number of successfully applied migrations.
+ * @throws FlywayException when the migration failed.
+ */
+ public int migrate() throws FlywayException {
+ return execute(new Command() {
+ public Integer execute(MigrationResolver migrationResolver,
+ SchemaHistory schemaHistory, Database database, Schema[] schemas, CallbackExecutor callbackExecutor
+
+
+
+ ) {
+ if (configuration.isValidateOnMigrate()) {
+ doValidate(database, migrationResolver, schemaHistory, schemas, callbackExecutor,
+ true // Always ignore pending migrations when validating before migrating
+ );
+ }
+
+ if (!schemaHistory.exists()) {
+ List nonEmptySchemas = new ArrayList<>();
+ for (Schema schema : schemas) {
+ if (schema.exists() && !schema.empty()) {
+ nonEmptySchemas.add(schema);
+ }
+ }
+
+ if (!nonEmptySchemas.isEmpty()) {
+ if (configuration.isBaselineOnMigrate()) {
+ doBaseline(schemaHistory, callbackExecutor);
+ } else {
+ // Second check for MySQL which is sometimes flaky otherwise
+ if (!schemaHistory.exists()) {
+ throw new FlywayException("Found non-empty schema(s) "
+ + StringUtils.collectionToCommaDelimitedString(nonEmptySchemas)
+ + " but no schema history table. Use baseline()"
+ + " or set baselineOnMigrate to true to initialize the schema history table.");
+ }
+ }
+ } else {
+ if (configuration.getCreateSchemas()) {
+ new DbSchemas(database, schemas, schemaHistory).create(false);
+ } else {
+ LOG.warn("The configuration option 'createSchemas' is false.\n" +
+ "However the schema history table still needs a schema to reside in.\n" +
+ "You must manually create a schema for the schema history table to reside in.\n" +
+ "See http://flywaydb.org/documentation/migrations#the-createschemas-option-and-the-schema-history-table)");
+ }
+
+ schemaHistory.create(false);
+ }
+ }
+
+ return new DbMigrate(database, schemaHistory, schemas[0], migrationResolver, configuration,
+ callbackExecutor).migrate();
+ }
+ }, true);
+ }
+
+ private void doBaseline(SchemaHistory schemaHistory, CallbackExecutor callbackExecutor) {
+ new DbBaseline(schemaHistory, configuration.getBaselineVersion(), configuration.getBaselineDescription(),
+ callbackExecutor).baseline();
+ }
+
+ /**
+ *
Undoes the most recently applied versioned migration. If target is specified, Flyway will attempt to undo
+ * versioned migrations in the order they were applied until it hits one with a version below the target. If there
+ * is no versioned migration to undo, calling undo has no effect.
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ *
+ * @return The number of successfully undone migrations.
+ * @throws FlywayException when the undo failed.
+ */
+ public int undo() throws FlywayException {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("undo");
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+ /**
+ *
Validate applied migrations against resolved ones (on the filesystem or classpath)
+ * to detect accidental changes that may prevent the schema(s) from being recreated exactly.
+ *
Validation fails if
+ *
+ *
differences in migration names, types or checksums are found
+ *
versions have been applied that aren't resolved locally anymore
+ *
versions have been resolved that haven't been applied yet
+ *
+ *
+ *
+ *
+ * @throws FlywayException when the validation failed.
+ */
+ public void validate() throws FlywayException {
+ execute(new Command() {
+ public Void execute(MigrationResolver migrationResolver, SchemaHistory schemaHistory, Database database,
+ Schema[] schemas, CallbackExecutor callbackExecutor
+
+
+
+ ) {
+ doValidate(database, migrationResolver, schemaHistory, schemas, callbackExecutor,
+ configuration.isIgnorePendingMigrations());
+ return null;
+ }
+ }, true);
+ }
+
+ /**
+ * Performs the actual validation. All set up must have taken place beforehand.
+ *
+ * @param database The database-specific support.
+ * @param migrationResolver The migration resolver;
+ * @param schemaHistory The schema history table.
+ * @param schemas The schemas managed by Flyway.
+ * @param callbackExecutor The callback executor.
+ * @param ignorePending Whether to ignore pending migrations.
+ */
+ private void doValidate(Database database, MigrationResolver migrationResolver, SchemaHistory schemaHistory,
+ Schema[] schemas, CallbackExecutor callbackExecutor, boolean ignorePending) {
+ String validationError =
+ new DbValidate(database, schemaHistory, schemas[0], migrationResolver,
+ configuration, ignorePending, callbackExecutor).validate();
+
+ if (validationError != null) {
+ if (configuration.isCleanOnValidationError()) {
+ doClean(database, schemaHistory, schemas, callbackExecutor);
+ } else {
+ throw new FlywayException("Validate failed: " + validationError);
+ }
+ }
+ }
+
+ private void doClean(Database database, SchemaHistory schemaHistory, Schema[] schemas, CallbackExecutor callbackExecutor) {
+ new DbClean(database, schemaHistory, schemas, callbackExecutor, configuration.isCleanDisabled()).clean();
+ }
+
+ /**
+ *
Drops all objects (tables, views, procedures, triggers, ...) in the configured schemas.
+ * The schemas are cleaned in the order specified by the {@code schemas} property.
Retrieves the complete information about all the migrations including applied, pending and current migrations with
+ * details and status.
+ *
+ *
+ * @return All migrations sorted by version, oldest first.
+ * @throws FlywayException when the info retrieval failed.
+ */
+ public MigrationInfoService info() {
+ return execute(new Command() {
+ public MigrationInfoService execute(MigrationResolver migrationResolver, SchemaHistory schemaHistory,
+ final Database database, final Schema[] schemas, CallbackExecutor callbackExecutor
+
+
+
+ ) {
+ return new DbInfo(migrationResolver, schemaHistory, configuration, callbackExecutor).info();
+ }
+ }, true);
+ }
+
+ /**
+ *
Baselines an existing database, excluding all migrations up to and including baselineVersion.
+ *
+ *
+ *
+ * @throws FlywayException when the schema baselining failed.
+ */
+ public void baseline() throws FlywayException {
+ execute(new Command() {
+ public Void execute(MigrationResolver migrationResolver,
+ SchemaHistory schemaHistory, Database database, Schema[] schemas, CallbackExecutor callbackExecutor
+
+
+
+ ) {
+ if (configuration.getCreateSchemas()) {
+ new DbSchemas(database, schemas, schemaHistory).create(true);
+ } else {
+ LOG.warn("The configuration option 'createSchemas' is false.\n" +
+ "Even though Flyway is configured not to create any schemas, the schema history table still needs a schema to reside in.\n" +
+ "You must manually create a schema for the schema history table to reside in.\n" +
+ "See http://flywaydb.org/documentation/migrations#the-createschemas-option-and-the-schema-history-table");
+ }
+
+ doBaseline(schemaHistory, callbackExecutor);
+ return null;
+ }
+ }, false);
+ }
+
+ /**
+ * Repairs the Flyway schema history table. This will perform the following actions:
+ *
+ *
Remove any failed migrations on databases without DDL transactions (User objects left behind must still be cleaned up manually)
+ *
Realign the checksums, descriptions and types of the applied migrations with the ones of the available migrations
+ *
+ *
+ *
+ * @throws FlywayException when the schema history table repair failed.
+ */
+ public void repair() throws FlywayException {
+ execute(new Command() {
+ public Void execute(MigrationResolver migrationResolver,
+ SchemaHistory schemaHistory, Database database, Schema[] schemas, CallbackExecutor callbackExecutor
+
+
+
+ ) {
+ new DbRepair(database, migrationResolver, schemaHistory, callbackExecutor, configuration).repair();
+ return null;
+ }
+ }, true);
+ }
+
+ /**
+ * Creates the MigrationResolver.
+ *
+ * @param resourceProvider The resource provider.
+ * @param classProvider The class provider.
+ * @param sqlScriptFactory The SQL statement builder factory.
+ * @param parsingContext The parsing context.
+ * @return A new, fully configured, MigrationResolver instance.
+ */
+ private MigrationResolver createMigrationResolver(ResourceProvider resourceProvider,
+ ClassProvider classProvider,
+ SqlScriptExecutorFactory sqlScriptExecutorFactory,
+ SqlScriptFactory sqlScriptFactory,
+ ParsingContext parsingContext) {
+ return new CompositeMigrationResolver(resourceProvider, classProvider, configuration,
+ sqlScriptExecutorFactory, sqlScriptFactory, parsingContext, configuration.getResolvers());
+ }
+
+ /**
+ * Executes this command with proper resource handling and cleanup.
+ *
+ * @param command The command to execute.
+ * @param The type of the result.
+ * @return The result of the command.
+ */
+ /*private -> testing*/ T execute(Command command, boolean scannerRequired) {
+ T result;
+
+ VersionPrinter.printVersion(
+
+
+
+ );
+
+ configurationValidator.validate(configuration);
+
+
+
+
+
+
+
+
+
+
+
+
+ final Pair> resourceProviderClassProviderPair = createResourceAndClassProviders(scannerRequired);
+ final ResourceProvider resourceProvider = resourceProviderClassProviderPair.getLeft();
+ final ClassProvider classProvider = resourceProviderClassProviderPair.getRight();
+
+ if (configuration.isValidateMigrationNaming()) {
+ resourceNameValidator.validateSQLMigrationNaming(resourceProvider, configuration);
+ }
+
+ JdbcConnectionFactory jdbcConnectionFactory = new JdbcConnectionFactory(configuration.getDataSource(),
+ configuration.getConnectRetries()
+
+
+
+
+ );
+
+ final ParsingContext parsingContext = new ParsingContext();
+ final SqlScriptFactory sqlScriptFactory =
+ DatabaseFactory.createSqlScriptFactory(jdbcConnectionFactory, configuration, parsingContext);
+
+ final SqlScriptExecutorFactory noCallbackSqlScriptExecutorFactory = DatabaseFactory.createSqlScriptExecutorFactory(
+ jdbcConnectionFactory
+
+
+
+
+ );
+
+ jdbcConnectionFactory.setConnectionInitializer(new JdbcConnectionFactory.ConnectionInitializer() {
+ @Override
+ public void initialize(JdbcConnectionFactory jdbcConnectionFactory, Connection connection) {
+ if (configuration.getInitSql() == null) {
+ return;
+ }
+ StringResource resource = new StringResource(configuration.getInitSql());
+
+ SqlScript sqlScript = sqlScriptFactory.createSqlScript(resource, true, resourceProvider);
+ noCallbackSqlScriptExecutorFactory.createSqlScriptExecutor(connection
+
+
+
+ ).execute(sqlScript);
+ }
+ });
+
+ Database database = null;
+ try {
+ database = DatabaseFactory.createDatabase(configuration, !dbConnectionInfoPrinted, jdbcConnectionFactory
+
+
+
+ );
+
+ dbConnectionInfoPrinted = true;
+ LOG.debug("DDL Transactions Supported: " + database.supportsDdlTransactions());
+
+ Pair> schemas = prepareSchemas(database);
+ Schema defaultSchema = schemas.getLeft();
+
+
+
+
+
+
+
+ parsingContext.populate(database, configuration);
+
+ database.ensureSupported();
+
+ DefaultCallbackExecutor callbackExecutor = new DefaultCallbackExecutor(configuration, database, defaultSchema,
+ prepareCallbacks(database, resourceProvider, jdbcConnectionFactory, sqlScriptFactory
+
+
+
+ ));
+
+ SqlScriptExecutorFactory sqlScriptExecutorFactory = DatabaseFactory.createSqlScriptExecutorFactory(jdbcConnectionFactory
+
+
+
+
+ );
+
+ result = command.execute(
+ createMigrationResolver(resourceProvider, classProvider, sqlScriptExecutorFactory, sqlScriptFactory, parsingContext),
+ SchemaHistoryFactory.getSchemaHistory(configuration, noCallbackSqlScriptExecutorFactory, sqlScriptFactory,
+ database, defaultSchema
+
+
+
+ ),
+ database,
+ schemas.getRight().toArray(new Schema[0]),
+ callbackExecutor
+
+
+
+ );
+ } finally {
+ IOUtils.close(database);
+
+
+
+ showMemoryUsage();
+ }
+ return result;
+ }
+
+ private Pair> createResourceAndClassProviders(boolean scannerRequired) {
+ ResourceProvider resourceProvider;
+ ClassProvider classProvider;
+ if (!scannerRequired && configuration.isSkipDefaultResolvers() && configuration.isSkipDefaultCallbacks()) {
+ resourceProvider = NoopResourceProvider.INSTANCE;
+ //noinspection unchecked
+ classProvider = NoopClassProvider.INSTANCE;
+ } else {
+ if (configuration.getResourceProvider() != null && configuration.getJavaMigrationClassProvider() != null) {
+ // don't create the scanner at all in this case
+ resourceProvider = configuration.getResourceProvider();
+ classProvider = configuration.getJavaMigrationClassProvider();
+ } else {
+ Scanner scanner = new Scanner<>(
+ JavaMigration.class,
+ Arrays.asList(configuration.getLocations()),
+ configuration.getClassLoader(),
+ configuration.getEncoding()
+
+
+
+ , resourceNameCache
+ , locationScannerCache
+ );
+ // set the defaults
+ resourceProvider = scanner;
+ classProvider = scanner;
+ if (configuration.getResourceProvider() != null) {
+ resourceProvider = configuration.getResourceProvider();
+ }
+ if (configuration.getJavaMigrationClassProvider() != null) {
+ classProvider = configuration.getJavaMigrationClassProvider();
+ }
+ }
+ }
+
+ return Pair.of(resourceProvider, classProvider);
+ }
+
+ private void showMemoryUsage() {
+ Runtime runtime = Runtime.getRuntime();
+ long free = runtime.freeMemory();
+ long total = runtime.totalMemory();
+ long used = total - free;
+
+ long totalMB = total / (1024 * 1024);
+ long usedMB = used / (1024 * 1024);
+ LOG.debug("Memory usage: " + usedMB + " of " + totalMB + "M");
+ }
+
+ private Pair> prepareSchemas(Database database) {
+ String defaultSchemaName = configuration.getDefaultSchema();
+ String[] schemaNames = configuration.getSchemas();
+
+ if (!isDefaultSchemaValid(defaultSchemaName, schemaNames)) {
+ throw new FlywayException("The defaultSchema property is specified but is not a member of the schemas property");
+ }
+
+ LOG.debug("Schemas: " + StringUtils.arrayToCommaDelimitedString(schemaNames));
+ LOG.debug("Default schema: " + defaultSchemaName);
+
+ List schemas = new ArrayList<>();
+
+ if (schemaNames.length == 0) {
+ Schema currentSchema = database.getMainConnection().getCurrentSchema();
+ if (currentSchema == null) {
+ throw new FlywayException("Unable to determine schema for the schema history table." +
+ " Set a default schema for the connection or specify one using the defaultSchema property!");
+ }
+ schemas.add(currentSchema);
+ } else {
+ for (String schemaName : schemaNames) {
+ schemas.add(database.getMainConnection().getSchema(schemaName));
+ }
+ }
+
+ if (defaultSchemaName == null && schemaNames.length > 0) {
+ defaultSchemaName = schemaNames[0];
+ }
+
+ Schema defaultSchema = (defaultSchemaName != null)
+ ? database.getMainConnection().getSchema(defaultSchemaName)
+ : database.getMainConnection().getCurrentSchema();
+
+ return Pair.of(defaultSchema, schemas);
+ }
+
+ private boolean isDefaultSchemaValid(String defaultSchema, String[] schemas) {
+ // No default schema specified
+ if (defaultSchema == null) {
+ return true;
+ }
+ // Default schema is one of those Flyway is managing
+ for (String schema : schemas) {
+ if (defaultSchema.equals(schema)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private List prepareCallbacks(Database database, ResourceProvider resourceProvider,
+ JdbcConnectionFactory jdbcConnectionFactory,
+ SqlScriptFactory sqlScriptFactory
+
+
+
+
+ ) {
+ List effectiveCallbacks = new ArrayList<>();
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ effectiveCallbacks.addAll(Arrays.asList(configuration.getCallbacks()));
+
+ if (!configuration.isSkipDefaultCallbacks()) {
+ SqlScriptExecutorFactory sqlScriptExecutorFactory =
+ DatabaseFactory.createSqlScriptExecutorFactory(jdbcConnectionFactory
+
+
+
+
+ );
+
+ effectiveCallbacks.addAll(
+ new SqlScriptCallbackFactory(
+ resourceProvider,
+ sqlScriptExecutorFactory,
+ sqlScriptFactory,
+ configuration
+ ).getCallbacks());
+ }
+
+
+
+
+
+ return effectiveCallbacks;
+ }
+
+ /**
+ * A Flyway command that can be executed.
+ *
+ * @param The result type of the command.
+ */
+ /*private -> testing*/ interface Command {
+ /**
+ * Execute the operation.
+ *
+ * @param migrationResolver The migration resolver to use.
+ * @param schemaHistory The schema history table.
+ * @param database The database-specific support for these connections.
+ * @param schemas The schemas managed by Flyway.
+ * @param callbackExecutor The callback executor.
+ * @return The result of the operation.
+ */
+ T execute(MigrationResolver migrationResolver, SchemaHistory schemaHistory,
+ Database database, Schema[] schemas, CallbackExecutor callbackExecutor
+
+
+
+ );
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/ClassProvider.java a/flyway-core/src/main/java/org/flywaydb/core/api/ClassProvider.java
new file mode 100644
index 0000000..e02bc11
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/ClassProvider.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api;
+
+import java.util.Collection;
+
+/**
+ * A facility to obtain classes.
+ */
+public interface ClassProvider {
+ /**
+ * Retrieve all classes which implement the specified interface.
+ *
+ * @return The non-abstract classes that were found.
+ */
+ Collection> getClasses();
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/ErrorCode.java a/flyway-core/src/main/java/org/flywaydb/core/api/ErrorCode.java
new file mode 100644
index 0000000..035396c
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/ErrorCode.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api;
+
+public enum ErrorCode {
+ FAULT,
+ ERROR,
+ JDBC_DRIVER,
+ DB_CONNECTION,
+ DUPLICATE_VERSIONED_MIGRATION,
+ DUPLICATE_REPEATABLE_MIGRATION,
+ DUPLICATE_UNDO_MIGRATION,
+ CONFIGURATION;
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/FlywayException.java a/flyway-core/src/main/java/org/flywaydb/core/api/FlywayException.java
new file mode 100644
index 0000000..1d53a8b
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/FlywayException.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api;
+
+/**
+ * Exception thrown when Flyway encounters a problem.
+ */
+public class FlywayException extends RuntimeException {
+
+ private ErrorCode errorCode = ErrorCode.ERROR;
+
+ /**
+ * Creates a new FlywayException with this message, cause, and error code.
+ *
+ * @param message The exception message.
+ * @param cause The exception cause.
+ * @param errorCode The error code.
+ */
+ public FlywayException(String message, Throwable cause, ErrorCode errorCode) {
+ super(message, cause);
+ this.errorCode = errorCode;
+ }
+
+ /**
+ * Creates a new FlywayException with this message and error code
+ *
+ * @param message The exception message.
+ * @param errorCode The error code.
+ */
+ public FlywayException(String message, ErrorCode errorCode) {
+ super(message);
+ this.errorCode = errorCode;
+ }
+
+ /**
+ * Creates a new FlywayException with this message and this cause.
+ *
+ * @param message The exception message.
+ * @param cause The exception cause.
+ */
+ public FlywayException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Creates a new FlywayException with this cause. For use in subclasses that override getMessage().
+ *
+ * @param cause The exception cause.
+ */
+ public FlywayException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Creates a new FlywayException with this message.
+ *
+ * @param message The exception message.
+ */
+ public FlywayException(String message) {
+ super(message);
+ }
+
+ /**
+ * Creates a new FlywayException. For use in subclasses that override getMessage().
+ */
+ public FlywayException() {
+ super();
+ }
+
+ public ErrorCode getErrorCode() {
+ return errorCode;
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/InfoOutputProvider.java a/flyway-core/src/main/java/org/flywaydb/core/api/InfoOutputProvider.java
new file mode 100644
index 0000000..2b7016d
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/InfoOutputProvider.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api;
+
+import org.flywaydb.core.internal.output.InfoOutput;
+
+interface InfoOutputProvider {
+ InfoOutput getInfoOutput();
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/Location.java a/flyway-core/src/main/java/org/flywaydb/core/api/Location.java
new file mode 100644
index 0000000..d800c08
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/Location.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api;
+
+import org.flywaydb.core.api.logging.Log;
+import org.flywaydb.core.api.logging.LogFactory;
+
+import java.io.File;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A location to load migrations from.
+ */
+public final class Location implements Comparable {
+ private static final Log LOG = LogFactory.getLog(Location.class);
+
+ /**
+ * The prefix for classpath locations.
+ */
+ private static final String CLASSPATH_PREFIX = "classpath:";
+
+ /**
+ * The prefix for filesystem locations.
+ */
+ public static final String FILESYSTEM_PREFIX = "filesystem:";
+
+ /**
+ * The prefix part of the location. Can be either classpath: or filesystem:.
+ */
+ private final String prefix;
+
+ /**
+ * The path part of the location.
+ */
+ private String rawPath;
+
+ /**
+ * The first folder in the path. This will equal rawPath if the path does not contain any wildcards
+ */
+ private String rootPath;
+
+ private Pattern pathRegex = null;
+
+ /**
+ * Creates a new location.
+ *
+ * @param descriptor The location descriptor.
+ */
+ public Location(String descriptor) {
+ String normalizedDescriptor = descriptor.trim();
+
+ if (normalizedDescriptor.contains(":")) {
+ prefix = normalizedDescriptor.substring(0, normalizedDescriptor.indexOf(":") + 1);
+ rawPath = normalizedDescriptor.substring(normalizedDescriptor.indexOf(":") + 1);
+ } else {
+ prefix = CLASSPATH_PREFIX;
+ rawPath = normalizedDescriptor;
+ }
+
+ if (isClassPath()) {
+ if (rawPath.contains(".")) {
+ LOG.warn("Use of dots (.) as path separators will be deprecated in Flyway 7. Path: " + rawPath);
+ }
+ rawPath = rawPath.replace(".", "/");
+ if (rawPath.startsWith("/")) {
+ rawPath = rawPath.substring(1);
+ }
+ if (rawPath.endsWith("/")) {
+ rawPath = rawPath.substring(0, rawPath.length() - 1);
+ }
+ processRawPath();
+ } else if (isFileSystem()) {
+ processRawPath();
+ rootPath = new File(rootPath).getPath();
+
+ if (pathRegex == null) {
+ // if the original path contained no wildcards, also normalise it
+ rawPath = new File(rawPath).getPath();
+ }
+ } else {
+ throw new FlywayException("Unknown prefix for location (should be either filesystem: or classpath:): "
+ + normalizedDescriptor);
+ }
+
+ if (rawPath.endsWith(File.separator)) {
+ rawPath = rawPath.substring(0, rawPath.length() - 1);
+ }
+ }
+
+ /**
+ * Process the rawPath into a rootPath and a regex.
+ * Supported wildcards:
+ * **: Match any 0 or more directories
+ * *: Match any sequence of non-seperator characters
+ * ?: Match any single character
+ */
+ private void processRawPath() {
+ if (rawPath.contains("*") || rawPath.contains("?")) {
+ // we need to figure out the root, and create the regex
+
+ String seperator = isFileSystem() ? File.separator : "/";
+ String escapedSeperator = seperator.replace("\\", "\\\\").replace("/", "\\/");
+
+ // split on either of the path seperators
+ String[] pathSplit = rawPath.split("[\\\\/]");
+
+ StringBuilder rootPart = new StringBuilder();
+ StringBuilder patternPart = new StringBuilder();
+
+ boolean endsInFile = false;
+ boolean skipSeperator = false;
+ boolean inPattern = false;
+ for (String pathPart : pathSplit) {
+ endsInFile = false;
+
+ if (pathPart.contains("*") || pathPart.contains("?")) {
+ inPattern = true;
+ }
+
+ if (inPattern) {
+ if (skipSeperator) {
+ skipSeperator = false;
+ } else {
+ patternPart.append("/");
+ }
+
+ String regex;
+ if ("**".equals(pathPart)) {
+ regex = "([^/]+/)*?";
+
+ // this pattern contains the ending seperator, so make sure we skip appending it after
+ skipSeperator = true;
+ } else {
+ endsInFile = pathPart.contains(".");
+
+ regex = pathPart;
+ regex = regex.replace(".", "\\.");
+ regex = regex.replace("?", "[^/]");
+ regex = regex.replace("*", "[^/]+?");
+ }
+
+ patternPart.append(regex);
+ } else {
+ rootPart.append(seperator).append(pathPart);
+ }
+ }
+
+ // We always append a seperator before each part, so ensure we skip it when setting the final rootPath
+ rootPath = rootPart.length() > 0 ? rootPart.toString().substring(1) : "";
+
+ // Again, skip first seperator
+ String pattern = patternPart.toString().substring(1);
+
+ // Replace the temporary / with the actual escaped seperator
+ pattern = pattern.replace("/", escapedSeperator);
+
+ // Append the rootpath if it is non-empty
+ if (rootPart.length() > 0) {
+ pattern = rootPath.replace(seperator, escapedSeperator) + escapedSeperator + pattern;
+ }
+
+ // if the path did not end in a file, then append the file match pattern
+ if (!endsInFile) {
+ pattern = pattern + escapedSeperator + "(?.*)";
+ }
+
+ pathRegex = Pattern.compile(pattern);
+ } else {
+ rootPath = rawPath;
+ }
+ }
+
+ /**
+ * @return Whether the given path matches this locations regex. Will always return true when the location did not contain any wildcards.
+ */
+ public boolean matchesPath(String path) {
+ if (pathRegex == null) {
+ return true;
+ }
+
+ return pathRegex.matcher(path).matches();
+ }
+
+ /**
+ * Returns the path relative to this location. If the location path contains wildcards, the returned path will be relative
+ * to the last non-wildcard folder in the path.
+ * @return the path relative to this location
+ */
+ public String getPathRelativeToThis(String path) {
+ if (pathRegex != null && pathRegex.pattern().contains("?")) {
+ Matcher matcher = pathRegex.matcher(path);
+ if (matcher.matches()) {
+ String relPath = matcher.group("relpath");
+ if (relPath != null && relPath.length() > 0) {
+ return relPath;
+ }
+ }
+ }
+
+ return rootPath.length() > 0 ? path.substring(rootPath.length() + 1) : path;
+ }
+
+ /**
+ * Checks whether this denotes a location on the classpath.
+ *
+ * @return {@code true} if it does, {@code false} if it doesn't.
+ */
+ public boolean isClassPath() {
+ return CLASSPATH_PREFIX.equals(prefix);
+ }
+
+ /**
+ * Checks whether this denotes a location on the filesystem.
+ *
+ * @return {@code true} if it does, {@code false} if it doesn't.
+ */
+ public boolean isFileSystem() {
+ return FILESYSTEM_PREFIX.equals(prefix);
+ }
+
+ /**
+ * Checks whether this location is a parent of this other location.
+ *
+ * @param other The other location.
+ * @return {@code true} if it is, {@code false} if it isn't.
+ */
+ @SuppressWarnings("SimplifiableIfStatement")
+ public boolean isParentOf(Location other) {
+ if (pathRegex != null || other.pathRegex != null) {
+ return false;
+ }
+
+ if (isClassPath() && other.isClassPath()) {
+ return (other.getDescriptor() + "/").startsWith(getDescriptor() + "/");
+ }
+ if (isFileSystem() && other.isFileSystem()) {
+ return (other.getDescriptor() + File.separator).startsWith(getDescriptor() + File.separator);
+ }
+ return false;
+ }
+
+ /**
+ * @return The prefix part of the location. Can be either classpath: or filesystem:.
+ */
+ public String getPrefix() {
+ return prefix;
+ }
+
+ /**
+ * @return The root part of the path part of the location.
+ */
+ public String getRootPath() {
+ return rootPath;
+ }
+
+ /**
+ * @return The path part of the location.
+ */
+ public String getPath() {
+ return rawPath;
+ }
+
+ /**
+ * @return The the regex that matches in original path. Null if the original path did not contain any wildcards.
+ */
+ public Pattern getPathRegex() {
+ return pathRegex;
+ }
+
+ /**
+ * @return The complete location descriptor.
+ */
+ public String getDescriptor() {
+ return prefix + rawPath;
+ }
+
+ @SuppressWarnings("NullableProblems")
+ public int compareTo(Location o) {
+ return getDescriptor().compareTo(o.getDescriptor());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Location location = (Location) o;
+
+ return getDescriptor().equals(location.getDescriptor());
+ }
+
+ @Override
+ public int hashCode() {
+ return getDescriptor().hashCode();
+ }
+
+ /**
+ * @return The complete location descriptor.
+ */
+ @Override
+ public String toString() {
+ return getDescriptor();
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/MigrationInfo.java a/flyway-core/src/main/java/org/flywaydb/core/api/MigrationInfo.java
new file mode 100644
index 0000000..a7895ae
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/MigrationInfo.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api;
+
+import java.util.Date;
+
+/**
+ * Info about a migration.
+ */
+public interface MigrationInfo extends Comparable {
+ /**
+ * @return The type of migration (BASELINE, SQL, JDBC, ...)
+ */
+ MigrationType getType();
+
+ /**
+ * @return The target version of this migration.
+ */
+ Integer getChecksum();
+
+ /**
+ * @return The schema version after the migration is complete.
+ */
+ MigrationVersion getVersion();
+
+ /**
+ * @return The description of the migration.
+ */
+ String getDescription();
+
+ /**
+ * @return The name of the script to execute for this migration, relative to its classpath or filesystem location.
+ */
+ String getScript();
+
+ /**
+ * @return The state of the migration (PENDING, SUCCESS, ...)
+ */
+ MigrationState getState();
+
+ /**
+ * @return The timestamp when this migration was installed. (Only for applied migrations)
+ */
+ Date getInstalledOn();
+
+ /**
+ * @return The user that installed this migration. (Only for applied migrations)
+ */
+ String getInstalledBy();
+
+ /**
+ * @return The rank of this installed migration. This is the most precise way to sort applied migrations by installation order.
+ * Migrations that were applied later have a higher rank. (Only for applied migrations)
+ */
+ Integer getInstalledRank();
+
+ /**
+ * @return The execution time (in millis) of this migration. (Only for applied migrations)
+ */
+ Integer getExecutionTime();
+
+ /**
+ * @return The physical location of the migration on disk.
+ */
+ String getPhysicalLocation();
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/MigrationInfoService.java a/flyway-core/src/main/java/org/flywaydb/core/api/MigrationInfoService.java
new file mode 100644
index 0000000..7888461
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/MigrationInfoService.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api;
+
+/**
+ * Info about all migrations, including applied, current and pending with details and status.
+ */
+public interface MigrationInfoService extends InfoOutputProvider {
+ /**
+ * Retrieves the full set of infos about applied, current and future migrations.
+ *
+ * @return The full set of infos. An empty array if none.
+ */
+ MigrationInfo[] all();
+
+ /**
+ * Retrieves the information of the current applied migration, if any.
+ *
+ * @return The info. {@code null} if no migrations have been applied yet.
+ */
+ MigrationInfo current();
+
+ /**
+ * Retrieves the full set of infos about pending migrations, available locally, but not yet applied to the DB.
+ *
+ * @return The pending migrations. An empty array if none.
+ */
+ MigrationInfo[] pending();
+
+ /**
+ * Retrieves the full set of infos about the migrations applied to the DB.
+ *
+ * @return The applied migrations. An empty array if none.
+ */
+ MigrationInfo[] applied();
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/MigrationState.java a/flyway-core/src/main/java/org/flywaydb/core/api/MigrationState.java
new file mode 100644
index 0000000..1e27976
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/MigrationState.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api;
+
+/**
+ * The state of a migration.
+ */
+public enum MigrationState {
+ /**
+ * This migration has not been applied yet.
+ */
+ PENDING("Pending", true, false, false),
+
+ /**
+ * This migration has not been applied yet, and won't be applied because target is set to a lower version.
+ */
+ ABOVE_TARGET("Above Target", true, false, false),
+
+ /**
+ * This migration was not applied against this DB, because the schema history table was baselined with a higher version.
+ */
+ BELOW_BASELINE("Below Baseline", true, false, false),
+
+ /**
+ * This migration has baselined this DB.
+ */
+ BASELINE("Baseline", true, true, false),
+
+ /**
+ *
This usually indicates a problem.
+ *
+ * This migration was not applied against this DB, because a migration with a higher version has already been
+ * applied. This probably means some checkins happened out of order.
+ *
+ *
Fix by increasing the version number, run clean and migrate again or rerun migration with outOfOrder enabled.
+ * This migration was applied against this DB, but it is not available locally.
+ * This usually results from multiple older migration files being consolidated into a single one.
+ *
+ * This migration was applied against this DB, but it is not available locally.
+ * This usually results from multiple older migration files being consolidated into a single one.
+ *
+ *
This should rarely, if ever, occur in practice.
+ */
+ MISSING_FAILED("Failed (Missing)", false, true, true),
+
+ /**
+ * This migration succeeded.
+ */
+ SUCCESS("Success", true, true, false),
+
+ /**
+ * This versioned migration succeeded, but has since been undone.
+ */
+ UNDONE("Undone", true, true, false),
+
+ /**
+ * This undo migration is ready to be applied if desired.
+ */
+ AVAILABLE("Available", true, false, false),
+
+ /**
+ * This migration failed.
+ */
+ FAILED("Failed", true, true, true),
+
+ /**
+ *
This migration succeeded.
+ *
+ * This migration succeeded, but it was applied out of order.
+ * Rerunning the entire migration history might produce different results!
+ *
+ * This migration has been applied against the DB, but it is not available locally.
+ * Its version is higher than the highest version available locally.
+ * It was most likely successfully installed by a future version of this deployable.
+ *
+ * This migration has been applied against the DB, but it is not available locally.
+ * Its version is higher than the highest version available locally.
+ * It most likely failed during the installation of a future version of this deployable.
+ *
+ */
+ FUTURE_FAILED("Failed (Future)", false, true, true),
+
+ /**
+ * This is a repeatable migration that is outdated and should be re-applied.
+ */
+ OUTDATED("Outdated", true, true, false),
+
+ /**
+ * This is a repeatable migration that is outdated and has already been superseded by a newer run.
+ */
+ SUPERSEDED("Superseded", true, true, false);
+
+ /**
+ * The name suitable for display to the end-user.
+ */
+ private final String displayName;
+
+ /**
+ * Flag indicating if this migration is available on the classpath or not.
+ */
+ private final boolean resolved;
+
+ /**
+ * Flag indicating if this migration has been applied or not.
+ */
+ private final boolean applied;
+
+ /**
+ * Flag indicating if this migration has failed when it was applied or not.
+ */
+ private final boolean failed;
+
+ /**
+ * Creates a new MigrationState.
+ *
+ * @param displayName The name suitable for display to the end-user.
+ * @param resolved Flag indicating if this migration is available on the classpath or not.
+ * @param applied Flag indicating if this migration has been applied or not.
+ * @param failed Flag indicating if this migration has failed when it was applied or not.
+ */
+ MigrationState(String displayName, boolean resolved, boolean applied, boolean failed) {
+ this.displayName = displayName;
+ this.resolved = resolved;
+ this.applied = applied;
+ this.failed = failed;
+ }
+
+ /**
+ * @return The name suitable for display to the end-user.
+ */
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ /**
+ * @return Flag indicating if this migration has been applied or not.
+ */
+ public boolean isApplied() {
+ return applied;
+ }
+
+ /**
+ * @return Flag indicating if this migration has been resolved or not.
+ */
+ public boolean isResolved() {
+ return resolved;
+ }
+
+ /**
+ * @return Flag indicating if this migration has failed or not.
+ */
+ public boolean isFailed() {
+ return failed;
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/MigrationType.java a/flyway-core/src/main/java/org/flywaydb/core/api/MigrationType.java
new file mode 100644
index 0000000..02e03fa
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/MigrationType.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api;
+
+/**
+ * Type of migration.
+ */
+public enum MigrationType {
+ /**
+ * Schema creation migration.
+ */
+ SCHEMA(true, false),
+
+ /**
+ * Baseline migration.
+ */
+ BASELINE(true, false),
+
+ /**
+ * SQL migrations.
+ */
+ SQL(false, false),
+
+ /**
+ * Undo SQL migrations.
+ */
+ UNDO_SQL(false, true),
+
+ /**
+ * JDBC Java-based migrations.
+ */
+ JDBC(false, false),
+
+ /**
+ * Undo JDBC java-based migrations.
+ */
+ UNDO_JDBC(false, true),
+
+ /**
+ * Spring JDBC Java-based migrations.
+ *
+ * @deprecated Will be removed in Flyway 7.0. Use JDBC instead.
+ */
+ @Deprecated
+ SPRING_JDBC(false, false),
+
+ /**
+ * Undo Spring JDBC java-based migrations.
+ *
+ * @deprecated Will be removed in Flyway 7.0. Use UNDO_JDBC instead.
+ */
+ @Deprecated
+ UNDO_SPRING_JDBC(false, true),
+
+ /**
+ * Migrations using custom MigrationResolvers.
+ */
+ CUSTOM(false, false),
+
+ /**
+ * Undo migrations using custom MigrationResolvers.
+ */
+ UNDO_CUSTOM(false, true);
+
+ private final boolean synthetic;
+ private final boolean undo;
+
+ MigrationType(boolean synthetic, boolean undo) {
+ this.synthetic = synthetic;
+ this.undo = undo;
+ }
+
+ /**
+ * @return Whether this is a synthetic migration type, which is only ever present in the schema history table,
+ * but never discovered by migration resolvers.
+ */
+ public boolean isSynthetic() {
+ return synthetic;
+ }
+
+ /**
+ * @return Whether this is an undo migration, which has undone an earlier migration present in the schema history table.
+ */
+ public boolean isUndo() {
+ return undo;
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/MigrationVersion.java a/flyway-core/src/main/java/org/flywaydb/core/api/MigrationVersion.java
new file mode 100644
index 0000000..2f08f0f
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/MigrationVersion.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * A version of a migration.
+ *
+ * @author Axel Fontaine
+ */
+public final class MigrationVersion implements Comparable {
+ /**
+ * Version for an empty schema.
+ */
+ public static final MigrationVersion EMPTY = new MigrationVersion(null, "<< Empty Schema >>");
+
+ /**
+ * Latest version.
+ */
+ public static final MigrationVersion LATEST = new MigrationVersion(BigInteger.valueOf(-1), "<< Latest Version >>");
+
+ /**
+ * Current version. Only a marker. For the real version use Flyway.info().current() instead.
+ */
+ public static final MigrationVersion CURRENT = new MigrationVersion(BigInteger.valueOf(-2), "<< Current Version >>");
+
+ /**
+ * Regex for matching proper version format
+ */
+ private static final Pattern SPLIT_REGEX = Pattern.compile("\\.(?=\\d)");
+
+ /**
+ * The individual parts this version string is composed of. Ex. 1.2.3.4.0 -> [1, 2, 3, 4, 0]
+ */
+ private final List versionParts;
+
+ /**
+ * The printable text to represent the version.
+ */
+ private final String displayText;
+
+ /**
+ * Create a MigrationVersion from a version String.
+ *
+ * @param version The version String. The value {@code current} will be interpreted as MigrationVersion.CURRENT,
+ * a marker for the latest version that has been applied to the database.
+ * @return The MigrationVersion
+ */
+ @SuppressWarnings("ConstantConditions")
+ public static MigrationVersion fromVersion(String version) {
+ if ("current".equalsIgnoreCase(version)) return CURRENT;
+ if ("latest".equalsIgnoreCase(version) || LATEST.getVersion().equals(version)) return LATEST;
+ if (version == null) return EMPTY;
+ return new MigrationVersion(version);
+ }
+
+ /**
+ * Creates a Version using this version string.
+ *
+ * @param version The version in one of the following formats: 6, 6.0, 005, 1.2.3.4, 201004200021. {@code null}
+ * means that this version refers to an empty schema.
+ */
+ private MigrationVersion(String version) {
+ String normalizedVersion = version.replace('_', '.');
+ this.versionParts = tokenize(normalizedVersion);
+ this.displayText = normalizedVersion;
+ }
+
+ /**
+ * Creates a Version using this version string.
+ *
+ * @param version The version in one of the following formats: 6, 6.0, 005, 1.2.3.4, 201004200021. {@code null}
+ * means that this version refers to an empty schema.
+ * @param displayText The alternative text to display instead of the version number.
+ */
+ private MigrationVersion(BigInteger version, String displayText) {
+ this.versionParts = new ArrayList<>();
+ this.versionParts.add(version);
+ this.displayText = displayText;
+ }
+
+ /**
+ * @return The textual representation of the version.
+ */
+ @Override
+ public String toString() {
+ return displayText;
+ }
+
+ /**
+ * @return Numeric version as String
+ */
+ public String getVersion() {
+ if (this.equals(EMPTY)) return null;
+ if (this.equals(LATEST)) return Long.toString(Long.MAX_VALUE);
+ return displayText;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ MigrationVersion version1 = (MigrationVersion) o;
+
+ return compareTo(version1) == 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return versionParts == null ? 0 : versionParts.hashCode();
+ }
+
+ /**
+ * Convenience method for quickly checking whether this version is at least as new as this other version.
+ *
+ * @param otherVersion The other version.
+ * @return {@code true} if this version is equal or newer, {@code false} if it is older.
+ */
+ public boolean isAtLeast(String otherVersion) {
+ return compareTo(MigrationVersion.fromVersion(otherVersion)) >= 0;
+ }
+
+ /**
+ * Convenience method for quickly checking whether this version is newer than this other version.
+ *
+ * @param otherVersion The other version.
+ * @return {@code true} if this version is newer, {@code false} if it is not.
+ */
+ public boolean isNewerThan(String otherVersion) {
+ return compareTo(MigrationVersion.fromVersion(otherVersion)) > 0;
+ }
+
+ /**
+ * Convenience method for quickly checking whether this major version is newer than this other major version.
+ *
+ * @param otherVersion The other version.
+ * @return {@code true} if this major version is newer, {@code false} if it is not.
+ */
+ public boolean isMajorNewerThan(String otherVersion) {
+ return getMajor().compareTo(MigrationVersion.fromVersion(otherVersion).getMajor()) > 0;
+ }
+
+ /**
+ * @return The major version.
+ */
+ public BigInteger getMajor() {
+ return versionParts.get(0);
+ }
+
+ /**
+ * @return The major version as a string.
+ */
+ public String getMajorAsString() {
+ return versionParts.get(0).toString();
+ }
+
+ /**
+ * @return The minor version as a string.
+ */
+ public String getMinorAsString() {
+ if (versionParts.size() == 1) {
+ return "0";
+ }
+ return versionParts.get(1).toString();
+ }
+
+ @Override
+ public int compareTo(MigrationVersion o) {
+ if (o == null) {
+ return 1;
+ }
+
+ if (this == EMPTY) {
+ if (o == EMPTY) return 0;
+ else return -1;
+ }
+
+ if (this == CURRENT) {
+ return o == CURRENT ? 0 : -1;
+ }
+
+ if (this == LATEST) {
+ if (o == LATEST) return 0;
+ else return 1;
+ }
+
+ if (o == EMPTY) {
+ return 1;
+ }
+
+ if (o == CURRENT) {
+ return 1;
+ }
+
+ if (o == LATEST) {
+ return -1;
+ }
+ final List parts1 = versionParts;
+ final List parts2 = o.versionParts;
+ int largestNumberOfParts = Math.max(parts1.size(), parts2.size());
+ for (int i = 0; i < largestNumberOfParts; i++) {
+ final int compared = getOrZero(parts1, i).compareTo(getOrZero(parts2, i));
+ if (compared != 0) {
+ return compared;
+ }
+ }
+ return 0;
+ }
+
+ private BigInteger getOrZero(List elements, int i) {
+ return i < elements.size() ? elements.get(i) : BigInteger.ZERO;
+ }
+
+ /**
+ * Splits this string into list of Long
+ *
+ * @param versionStr The string to split.
+ * @return The resulting array.
+ */
+ private List tokenize(String versionStr) {
+ List parts = new ArrayList<>();
+ for (String part : SPLIT_REGEX.split(versionStr)) {
+ parts.add(toBigInteger(versionStr, part));
+ }
+
+ for (int i = parts.size() - 1; i > 0; i--) {
+ if (!parts.get(i).equals(BigInteger.ZERO)) {
+ break;
+ }
+ parts.remove(i);
+ }
+
+ return parts;
+ }
+
+ private BigInteger toBigInteger(String versionStr, String part) {
+ try {
+ return new BigInteger(part);
+ } catch (NumberFormatException e) {
+ throw new FlywayException("Version may only contain 0..9 and . (dot). Invalid version: " + versionStr);
+ }
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/ResourceProvider.java a/flyway-core/src/main/java/org/flywaydb/core/api/ResourceProvider.java
new file mode 100644
index 0000000..9fda9bb
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/ResourceProvider.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api;
+
+import org.flywaydb.core.internal.resource.LoadableResource;
+
+import java.util.Collection;
+
+/**
+ * A facility to obtain loadable resources.
+ */
+public interface ResourceProvider {
+ /**
+ * Retrieves the resource with this name.
+ *
+ * @param name The name of the resource.
+ * @return The resource or {@code null} if not found.
+ */
+ LoadableResource getResource(String name);
+
+ /**
+ * Retrieve all resources whose name begins with this prefix and ends with any of these suffixes.
+ *
+ * @param prefix The prefix.
+ * @param suffixes The suffixes.
+ * @return The matching resources.
+ */
+ Collection getResources(String prefix, String[] suffixes);
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/android/ContextHolder.java a/flyway-core/src/main/java/org/flywaydb/core/api/android/ContextHolder.java
new file mode 100644
index 0000000..b10abcd
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/android/ContextHolder.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.android;
+
+import android.content.Context;
+
+/**
+ * Holds an Android context. The context must be set for Flyway to be able to scan assets and classes for migrations.
+ *
+ *
+ * You can set this within an activity using ContextHolder.setContext(this);
+ *
+ */
+public class ContextHolder {
+ private ContextHolder() {}
+
+ /**
+ * The Android context to use.
+ */
+ private static Context context;
+
+ /**
+ * @return The Android context to use to be able to scan assets and classes for migrations.
+ */
+ public static Context getContext() {
+ return context;
+ }
+
+ /**
+ * @param context The Android context to use to be able to scan assets and classes for migrations.
+ */
+ public static void setContext(Context context) {
+ ContextHolder.context = context;
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/android/package-info.java a/flyway-core/src/main/java/org/flywaydb/core/api/android/package-info.java
new file mode 100644
index 0000000..694c407
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/android/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Android-specific helper classes.
+ */
+package org.flywaydb.core.api.android;
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/callback/BaseCallback.java a/flyway-core/src/main/java/org/flywaydb/core/api/callback/BaseCallback.java
new file mode 100644
index 0000000..07fdf00
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/callback/BaseCallback.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.callback;
+
+/**
+ * Base implementation of Callback from which one can inherit. This is a convenience class that assumes by default that
+ * all events are handled and all handlers can run within a transaction.
+ */
+public abstract class BaseCallback implements Callback {
+ @Override
+ public boolean supports(Event event, Context context) {
+ return true;
+ }
+
+ @Override
+ public boolean canHandleInTransaction(Event event, Context context) {
+ return true;
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/callback/Callback.java a/flyway-core/src/main/java/org/flywaydb/core/api/callback/Callback.java
new file mode 100644
index 0000000..eae83cf
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/callback/Callback.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.callback;
+
+/**
+ * This is the main callback interface that should be implemented to handle Flyway lifecycle events.
+ */
+public interface Callback {
+ /**
+ * Whether this callback supports this event or not. This is primarily meant as a way to optimize event handling
+ * by avoiding unnecessary connection state setups for events that will not be handled anyway.
+ *
+ * @param event The event to check.
+ * @param context The context for this event.
+ * @return {@code true} if it can be handled, {@code false} if not.
+ */
+ boolean supports(Event event, Context context);
+
+ /**
+ * Whether this event can be handled in a transaction or whether it must be handled outside a transaction instead.
+ * In the vast majority of the cases the answer will be
+ * {@code true}. Only in the rare cases where non-transactional statements are executed should this return {@code false}.
+ * This method is called before {@link #handle(Event, Context)} in order to determine in advance whether a transaction
+ * can be used or not.
+ *
+ * @param event The event to check.
+ * @param context The context for this event.
+ * @return {@code true} if it can be handled within a transaction (almost all cases). {@code false} if it must be
+ * handled outside a transaction instead (very rare).
+ */
+ boolean canHandleInTransaction(Event event, Context context);
+
+ /**
+ * Handles this Flyway lifecycle event.
+ *
+ * @param event The event to handle.
+ * @param context The context for this event.
+ */
+ void handle(Event event, Context context);
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/callback/Context.java a/flyway-core/src/main/java/org/flywaydb/core/api/callback/Context.java
new file mode 100644
index 0000000..0c9acb9
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/callback/Context.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.callback;
+
+import org.flywaydb.core.api.MigrationInfo;
+import org.flywaydb.core.api.configuration.Configuration;
+
+import java.sql.Connection;
+
+/**
+ * The context relevant to an event.
+ */
+public interface Context {
+ /**
+ * @return The configuration currently in use.
+ */
+ Configuration getConfiguration();
+
+ /**
+ * @return The JDBC connection being used. Transaction are managed by Flyway.
+ * When the context is passed to the {@link Callback#handle(Event, Context)} method, a transaction will already have
+ * been started if required and will be automatically committed or rolled back afterwards.
+ */
+ Connection getConnection();
+
+ /**
+ * @return The info about the migration being handled. Only relevant for the BEFORE_EACH_* and AFTER_EACH_* events.
+ * {@code null} in all other cases.
+ */
+ MigrationInfo getMigrationInfo();
+
+ /**
+ * @return The info about the statement being handled. Only relevant for the statement-level events.
+ * {@code null} in all other cases.
+ *
Flyway Pro and Flyway Enterprise only
+ */
+ Statement getStatement();
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/callback/Error.java a/flyway-core/src/main/java/org/flywaydb/core/api/callback/Error.java
new file mode 100644
index 0000000..14d96c5
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/callback/Error.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.callback;
+
+/**
+ * An error that occurred while executing a statement.
+ *
Flyway Pro and Flyway Enterprise only
+ */
+public interface Error {
+ /**
+ * @return The error code.
+ */
+ int getCode();
+
+ /**
+ * @return The error state.
+ */
+ String getState();
+
+ /**
+ * @return The error message.
+ */
+ String getMessage();
+
+ /**
+ * Checks whether this error has already been handled.
+ *
+ * @return {@code true} {@code true} if this error has already be handled or {@code false} if it should flow
+ * via the default error handler.
+ */
+ boolean isHandled();
+
+ /**
+ * Sets whether this error has already been handled.
+ *
+ * @param handled {@code true} if this error has already be handled or {@code false} if it should flow via the
+ * default error handler.
+ */
+ void setHandled(boolean handled);
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/callback/Event.java a/flyway-core/src/main/java/org/flywaydb/core/api/callback/Event.java
new file mode 100644
index 0000000..7cc501d
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/callback/Event.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.callback;
+
+/**
+ * The Flyway lifecycle events that can be handled in callbacks.
+ */
+public enum Event {
+ /**
+ * Fired before clean is executed. This event will be fired in a separate transaction from the actual clean operation.
+ */
+ BEFORE_CLEAN("beforeClean"),
+ /**
+ * Fired after clean has succeeded. This event will be fired in a separate transaction from the actual clean operation.
+ */
+ AFTER_CLEAN("afterClean"),
+ /**
+ * Fired after clean has failed. This event will be fired in a separate transaction from the actual clean operation.
+ */
+ AFTER_CLEAN_ERROR("afterCleanError"),
+
+ /**
+ * Fired before migrate is executed. This event will be fired in a separate transaction from the actual migrate operation.
+ */
+ BEFORE_MIGRATE("beforeMigrate"),
+ /**
+ * Fired before each individual migration is executed. This event will be fired within the same transaction (if any)
+ * as the migration and can be used for things like setting up connection parameters that are required by migrations.
+ */
+ BEFORE_EACH_MIGRATE("beforeEachMigrate"),
+ /**
+ * Fired before each individual statement in a migration is executed. This event will be fired within the same transaction (if any)
+ * as the migration and can be used for things like asserting a statement complies with policy (for example: no grant statements allowed).
+ *
Flyway Pro and Enterprise Edition only
+ */
+ BEFORE_EACH_MIGRATE_STATEMENT("beforeEachMigrateStatement"),
+ /**
+ * Fired after each individual statement in a migration that succeeded. This event will be fired within the same transaction (if any)
+ * as the migration.
+ *
Flyway Pro and Enterprise Edition only
+ */
+ AFTER_EACH_MIGRATE_STATEMENT("afterEachMigrateStatement"),
+ /**
+ * Fired after each individual statement in a migration that failed. This event will be fired within the same transaction (if any)
+ * as the migration.
+ *
Flyway Pro and Enterprise Edition only
+ */
+ AFTER_EACH_MIGRATE_STATEMENT_ERROR("afterEachMigrateStatementError"),
+ /**
+ * Fired after each individual migration that succeeded. This event will be fired within the same transaction (if any)
+ * as the migration.
+ */
+ AFTER_EACH_MIGRATE("afterEachMigrate"),
+ /**
+ * Fired after each individual migration that failed. This event will be fired within the same transaction (if any)
+ * as the migration.
+ */
+ AFTER_EACH_MIGRATE_ERROR("afterEachMigrateError"),
+ /**
+ * Fired after migrate has succeeded. This event will be fired in a separate transaction from the actual migrate operation.
+ */
+ AFTER_MIGRATE("afterMigrate"),
+ /**
+ * Fired after migrate has failed. This event will be fired in a separate transaction from the actual migrate operation.
+ */
+ AFTER_MIGRATE_ERROR("afterMigrateError"),
+
+ /**
+ * Fired before undo is executed. This event will be fired in a separate transaction from the actual undo operation.
+ *
Flyway Pro and Enterprise Edition only
+ */
+ BEFORE_UNDO("beforeUndo"),
+ /**
+ * Fired before each individual undo is executed. This event will be fired within the same transaction (if any)
+ * as the undo and can be used for things like setting up connection parameters that are required by undo.
+ *
Flyway Pro and Enterprise Edition only
+ */
+ BEFORE_EACH_UNDO("beforeEachUndo"),
+ /**
+ * Fired before each individual statement in an undo migration is executed. This event will be fired within the same transaction (if any)
+ * as the migration and can be used for things like asserting a statement complies with policy (for example: no grant statements allowed).
+ *
Flyway Pro and Enterprise Edition only
+ */
+ BEFORE_EACH_UNDO_STATEMENT("beforeEachUndoStatement"),
+ /**
+ * Fired after each individual statement in an undo migration that succeeded. This event will be fired within the same transaction (if any)
+ * as the migration.
+ *
Flyway Pro and Enterprise Edition only
+ */
+ AFTER_EACH_UNDO_STATEMENT("afterEachUndoStatement"),
+ /**
+ * Fired after each individual statement in an undo migration that failed. This event will be fired within the same transaction (if any)
+ * as the migration.
+ *
Flyway Pro and Enterprise Edition only
+ */
+ AFTER_EACH_UNDO_STATEMENT_ERROR("afterEachUndoStatementError"),
+ /**
+ * Fired after each individual undo that succeeded. This event will be fired within the same transaction (if any)
+ * as the undo.
+ *
Flyway Pro and Enterprise Edition only
+ */
+ AFTER_EACH_UNDO("afterEachUndo"),
+ /**
+ * Fired after each individual undo that failed. This event will be fired within the same transaction (if any)
+ * as the undo.
+ *
Flyway Pro and Enterprise Edition only
+ */
+ AFTER_EACH_UNDO_ERROR("afterEachUndoError"),
+ /**
+ * Fired after undo has succeeded. This event will be fired in a separate transaction from the actual undo operation.
+ *
Flyway Pro and Enterprise Edition only
+ */
+ AFTER_UNDO("afterUndo"),
+ /**
+ * Fired after undo has failed. This event will be fired in a separate transaction from the actual undo operation.
+ *
Flyway Pro and Enterprise Edition only
+ */
+ AFTER_UNDO_ERROR("afterUndoError"),
+
+ /**
+ * Fired before validate is executed. This event will be fired in a separate transaction from the actual validate operation.
+ */
+ BEFORE_VALIDATE("beforeValidate"),
+ /**
+ * Fired after validate has succeeded. This event will be fired in a separate transaction from the actual validate operation.
+ */
+ AFTER_VALIDATE("afterValidate"),
+ /**
+ * Fired after validate has failed. This event will be fired in a separate transaction from the actual validate operation.
+ */
+ AFTER_VALIDATE_ERROR("afterValidateError"),
+
+ /**
+ * Fired before baseline is executed. This event will be fired in a separate transaction from the actual baseline operation.
+ */
+ BEFORE_BASELINE("beforeBaseline"),
+ /**
+ * Fired after baseline has succeeded. This event will be fired in a separate transaction from the actual baseline operation.
+ */
+ AFTER_BASELINE("afterBaseline"),
+ /**
+ * Fired after baseline has failed. This event will be fired in a separate transaction from the actual baseline operation.
+ */
+ AFTER_BASELINE_ERROR("afterBaselineError"),
+
+ /**
+ * Fired before repair is executed. This event will be fired in a separate transaction from the actual repair operation.
+ */
+ BEFORE_REPAIR("beforeRepair"),
+ /**
+ * Fired after repair has succeeded. This event will be fired in a separate transaction from the actual repair operation.
+ */
+ AFTER_REPAIR("afterRepair"),
+ /**
+ * Fired after repair has failed. This event will be fired in a separate transaction from the actual repair operation.
+ */
+ AFTER_REPAIR_ERROR("afterRepairError"),
+
+ /**
+ * Fired before info is executed. This event will be fired in a separate transaction from the actual info operation.
+ */
+ BEFORE_INFO("beforeInfo"),
+ /**
+ * Fired after info has succeeded. This event will be fired in a separate transaction from the actual info operation.
+ */
+ AFTER_INFO("afterInfo"),
+ /**
+ * Fired after info has failed. This event will be fired in a separate transaction from the actual info operation.
+ */
+ AFTER_INFO_ERROR("afterInfoError");
+
+ private final String id;
+
+ Event(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @return The id of an event. Examples: {@code beforeClean}, {@code afterEachMigrate}, ...
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Retrieves the event with this id.
+ * @param id The id.
+ * @return The event. {@code null} if not found.
+ */
+ public static Event fromId(String id) {
+ for (Event event : values()) {
+ if (event.id.equals(id)) {
+ return event;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return id;
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/callback/Statement.java a/flyway-core/src/main/java/org/flywaydb/core/api/callback/Statement.java
new file mode 100644
index 0000000..891b02b
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/callback/Statement.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.callback;
+
+import java.util.List;
+
+/**
+ * The statement relevant to an event.
+ *
Flyway Pro and Flyway Enterprise only
+ */
+public interface Statement {
+ /**
+ * @return The SQL statement.
+ */
+ String getSql();
+
+ /**
+ * @return The warnings that were raised during the execution of the statement.
+ * {@code null} if the statement hasn't been executed yet.
+ */
+ List getWarnings();
+
+ /**
+ * @return The errors that were thrown during the execution of the statement.
+ * {@code null} if the statement hasn't been executed yet.
+ */
+ List getErrors();
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/callback/Warning.java a/flyway-core/src/main/java/org/flywaydb/core/api/callback/Warning.java
new file mode 100644
index 0000000..eaec707
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/callback/Warning.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.callback;
+
+/**
+ * A warning that occurred while executing a statement.
+ *
Flyway Pro and Flyway Enterprise only
+ */
+public interface Warning {
+ /**
+ * @return The warning code.
+ */
+ int getCode();
+
+ /**
+ * @return The warning state.
+ */
+ String getState();
+
+ /**
+ * @return The warning message.
+ */
+ String getMessage();
+
+ /**
+ * Checks whether this warning has already been handled.
+ *
+ * @return {@code true} {@code true} if this warning has already be handled or {@code false} if it should flow
+ * via the default warning handler.
+ */
+ boolean isHandled();
+
+ /**
+ * Sets whether this warning has already been handled.
+ *
+ * @param handled {@code true} if this warning has already be handled or {@code false} if it should flow via the
+ * default warning handler.
+ */
+ void setHandled(boolean handled);
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/callback/package-info.java a/flyway-core/src/main/java/org/flywaydb/core/api/callback/package-info.java
new file mode 100644
index 0000000..b92cd6f
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/callback/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Interfaces for Flyway lifecycle callbacks.
+ */
+package org.flywaydb.core.api.callback;
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/configuration/ClassicConfiguration.java a/flyway-core/src/main/java/org/flywaydb/core/api/configuration/ClassicConfiguration.java
new file mode 100644
index 0000000..cbca07f
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/configuration/ClassicConfiguration.java
@@ -0,0 +1,1985 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.configuration;
+
+import org.flywaydb.core.api.ErrorCode;
+import org.flywaydb.core.api.FlywayException;
+import org.flywaydb.core.api.Location;
+import org.flywaydb.core.api.MigrationVersion;
+import org.flywaydb.core.api.callback.Callback;
+import org.flywaydb.core.api.logging.Log;
+import org.flywaydb.core.api.logging.LogFactory;
+import org.flywaydb.core.api.migration.JavaMigration;
+import org.flywaydb.core.api.resolver.MigrationResolver;
+import org.flywaydb.core.api.ClassProvider;
+import org.flywaydb.core.internal.configuration.ConfigUtils;
+import org.flywaydb.core.internal.jdbc.DriverDataSource;
+import org.flywaydb.core.internal.license.Edition;
+import org.flywaydb.core.api.ResourceProvider;
+import org.flywaydb.core.internal.util.ClassUtils;
+import org.flywaydb.core.internal.util.Locations;
+import org.flywaydb.core.internal.util.StringUtils;
+
+import javax.sql.DataSource;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import static org.flywaydb.core.internal.configuration.ConfigUtils.removeBoolean;
+import static org.flywaydb.core.internal.configuration.ConfigUtils.removeInteger;
+
+/**
+ * JavaBean-style configuration for Flyway. This is primarily meant for compatibility with scenarios where the
+ * new FluentConfiguration isn't an easy fit, such as Spring XML bean configuration.
+ *
+ * This configuration can then be passed to Flyway using the new Flyway(Configuration) constructor.
+ *
+ */
+public class ClassicConfiguration implements Configuration {
+ private static final Log LOG = LogFactory.getLog(ClassicConfiguration.class);
+
+ private String driver;
+ private String url;
+ private String user;
+ private String password;
+
+ /**
+ * The dataSource to use to access the database. Must have the necessary privileges to execute ddl.
+ */
+ private DataSource dataSource;
+
+ /**
+ * The maximum number of retries when attempting to connect to the database. After each failed attempt, Flyway will
+ * wait 1 second before attempting to connect again, up to the maximum number of times specified by connectRetries.
+ * (default: 0)
+ */
+ private int connectRetries;
+
+ /**
+ * The SQL statements to run to initialize a new database connection immediately after opening it.
+ * (default: {@code null})
+ */
+ private String initSql;
+
+ /**
+ * The ClassLoader to use for resolving migrations on the classpath. (default: Thread.currentThread().getContextClassLoader() )
+ */
+ private ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+
+ /**
+ * The locations to scan recursively for migrations.
+ *
The location type is determined by its prefix.
+ * Unprefixed locations or locations starting with {@code classpath:} point to a package on the classpath and may
+ * contain both sql and java-based migrations.
+ * Locations starting with {@code filesystem:} point to a directory on the filesystem and may only contain sql
+ * migrations.
+ *
+ * (default: db/migration)
+ */
+ private Locations locations = new Locations("db/migration");
+
+ /**
+ * The encoding of Sql migrations. (default: UTF-8)
+ */
+ private Charset encoding = StandardCharsets.UTF_8;
+
+ /**
+ * The default schema managed by Flyway. This schema name is case-sensitive. If not specified, but
+ * schemaNames is, Flyway uses the first schema in that list. If that is also not specified, Flyway uses
+ * the default schema for the database connection.
+ *
Consequences:
+ *
+ *
This schema will be the one containing the schema history table.
+ *
This schema will be the default for the database connection (provided the database supports this concept).
+ *
+ */
+ private String defaultSchemaName = null;
+
+ /**
+ * The schemas managed by Flyway. These schema names are case-sensitive. If not specified, Flyway uses
+ * the default schema for the database connection. If defaultSchemaName is not specified, then the first of
+ * this list also acts as default schema.
+ *
Consequences:
+ *
+ *
Flyway will automatically attempt to create all these schemas, unless they already exist.
+ *
The schemas will be cleaned in the order of this list.
+ *
If Flyway created them, the schemas themselves will be dropped when cleaning.
The tablespace where to create the schema history table that will be used by Flyway.
+ *
If not specified, Flyway uses the default tablespace for the database connection.
+ * This setting is only relevant for databases that do support the notion of tablespaces. Its value is simply
+ * ignored for all others.
+ */
+ private String tablespace;
+
+ /**
+ * The target version up to which Flyway should consider migrations.
+ * Migrations with a higher version number will be ignored.
+ * Special values:
+ *
+ *
{@code current}: designates the current version of the schema
+ *
{@code latest}: the latest version of the schema, as defined by the migration with the highest version
+ *
+ * Defaults to {@code latest}.
+ */
+ private MigrationVersion target;
+
+ /**
+ * Whether placeholders should be replaced. (default: true)
+ */
+ private boolean placeholderReplacement = true;
+
+ /**
+ * The map of <placeholder, replacementValue> to apply to sql migration scripts.
+ */
+ private Map placeholders = new HashMap<>();
+
+ /**
+ * The prefix of every placeholder. (default: ${ )
+ */
+ private String placeholderPrefix = "${";
+
+ /**
+ * The suffix of every placeholder. (default: } )
+ */
+ private String placeholderSuffix = "}";
+
+ /**
+ * The file name prefix for versioned SQL migrations. (default: V)
+ *
+ *
Versioned SQL migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to V1_1__My_description.sql
+ */
+ private String sqlMigrationPrefix = "V";
+
+
+
+
+
+
+
+
+
+
+
+
+ /**
+ * Custom Resource provider to use when looking up resources
+ */
+ private ResourceProvider resourceProvider = null;
+
+
+ /**
+ * Custom ClassProvider for looking up JavaMigration classes
+ */
+ private ClassProvider javaMigrationClassProvider = null;
+
+ /**
+ * The file name prefix for repeatable SQL migrations. (default: R)
+ *
+ *
Repeatable sql migrations have the following file name structure: prefixSeparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to R__My_description.sql
+ */
+ private String repeatableSqlMigrationPrefix = "R";
+
+ /**
+ * The file name separator for sql migrations. (default: __)
+ *
+ *
Sql migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to V1_1__My_description.sql
+ */
+ private String sqlMigrationSeparator = "__";
+
+ /**
+ * The file name suffixes for SQL migrations. (default: .sql)
+ *
SQL migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to V1_1__My_description.sql
+ *
Multiple suffixes (like .sql,.pkg,.pkb) can be specified for easier compatibility with other tools such as
+ * editors with specific file associations.
+ */
+ private String[] sqlMigrationSuffixes = {".sql"};
+
+ /**
+ * The manually added Java-based migrations. These are not Java-based migrations discovered through classpath
+ * scanning and instantiated by Flyway. Instead these are manually added instances of JavaMigration.
+ * This is particularly useful when working with a dependency injection container, where you may want the DI
+ * container to instantiate the class and wire up its dependencies for you. (default: none)
+ */
+ private JavaMigration[] javaMigrations = {};
+
+ /**
+ * Ignore missing migrations when reading the schema history table. These are migrations that were performed by an
+ * older deployment of the application that are no longer available in this version. For example: we have migrations
+ * available on the classpath with versions 1.0 and 3.0. The schema history table indicates that a migration with version 2.0
+ * (unknown to us) has also been applied. Instead of bombing out (fail fast) with an exception, a
+ * warning is logged and Flyway continues normally. This is useful for situations where one must be able to deploy
+ * a newer version of the application even though it doesn't contain migrations included with an older one anymore.
+ * Note that if the most recently applied migration is removed, Flyway has no way to know it is missing and will
+ * mark it as future instead.
+ *
+ * {@code true} to continue normally and log a warning, {@code false} to fail fast with an exception.
+ * (default: {@code false})
+ */
+ private boolean ignoreMissingMigrations;
+
+ /**
+ * Ignore ignored migrations when reading the schema history table. These are migrations that were added in between
+ * already migrated migrations in this version. For example: we have migrations available on the classpath with
+ * versions from 1.0 to 3.0. The schema history table indicates that version 1 was finished on 1.0.15, and the next
+ * 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
+ * by migrate command, but by default is rejected by validate. When ignoreIgnoredMigrations is enabled, such case
+ * will not be reported by validate command. This is useful for situations where one must be able to deliver
+ * complete set of migrations in a delivery package for multiple versions of the product, and allows for further
+ * development of older versions.
+ *
+ * {@code true} to continue normally, {@code false} to fail fast with an exception.
+ * (default: {@code false})
+ */
+ private boolean ignoreIgnoredMigrations;
+
+ /**
+ * Ignore pending migrations when reading the schema history table. These are migrations that are available on the
+ * classpath but have not yet been performed by an application deployment.
+ * This can be useful for verifying that in-development migration changes don't contain any validation-breaking changes
+ * of migrations that have already been applied to a production environment, e.g. as part of a CI/CD process, without
+ * failing because of the existence of new migration versions.
+ *
+ * {@code true} to continue normally, {@code false} to fail fast with an exception.
+ * (default: {@code false})
+ */
+ private boolean ignorePendingMigrations;
+
+ /**
+ * Ignore future migrations when reading the schema history table. These are migrations that were performed by a
+ * newer deployment of the application that are not yet available in this version. For example: we have migrations
+ * available on the classpath up to version 3.0. The schema history table indicates that a migration to version 4.0
+ * (unknown to us) has already been applied. Instead of bombing out (fail fast) with an exception, a
+ * warning is logged and Flyway continues normally. This is useful for situations where one must be able to redeploy
+ * an older version of the application after the database has been migrated by a newer one. (default: {@code true})
+ */
+ private boolean ignoreFutureMigrations = true;
+
+ /**
+ * Whether to validate migrations and callbacks whose scripts do not obey the correct naming convention. A failure can be
+ * useful to check that errors such as case sensitivity in migration prefixes have been corrected.
+ * {@code false} to continue normally, {@code true} to fail fast with an exception. (default: {@code false})
+ */
+ private boolean validateMigrationNaming = false;
+
+ /**
+ * Whether to automatically call validate or not when running migrate. (default: {@code true})
+ */
+ private boolean validateOnMigrate = true;
+
+ /**
+ * Whether to automatically call clean or not when a validation error occurs. (default: {@code false})
+ *
This is exclusively intended as a convenience for development. even though we
+ * strongly recommend not to change migration scripts once they have been checked into SCM and run, this provides a
+ * way of dealing with this case in a smooth manner. The database will be wiped clean automatically, ensuring that
+ * the next migration will bring you back to the state checked into SCM.
This is especially useful for production environments where running clean can be quite a career limiting move.
+ */
+ private boolean cleanDisabled;
+
+ /**
+ * The version to tag an existing schema with when executing baseline. (default: 1)
+ */
+ private MigrationVersion baselineVersion = MigrationVersion.fromVersion("1");
+
+ /**
+ * The description to tag an existing schema with when executing baseline. (default: << Flyway Baseline >>)
+ */
+ private String baselineDescription = "<< Flyway Baseline >>";
+
+ /**
+ *
+ * Whether to automatically call baseline when migrate is executed against a non-empty schema with no schema history table.
+ * This schema will then be initialized with the {@code baselineVersion} before executing the migrations.
+ * Only migrations above {@code baselineVersion} will then be applied.
+ *
+ *
+ * This is useful for initial Flyway production deployments on projects with an existing DB.
+ *
+ *
+ * Be careful when enabling this as it removes the safety net that ensures
+ * Flyway does not migrate the wrong database in case of a configuration mistake! (default: {@code false})
+ *
+ */
+ private boolean baselineOnMigrate;
+
+ /**
+ * Allows migrations to be run "out of order".
+ *
If you already have versions 1 and 3 applied, and now a version 2 is found,
+ * it will be applied too instead of being ignored.
+ *
(default: {@code false})
+ */
+ private boolean outOfOrder;
+
+ /**
+ * This is a list of custom callbacks that fire before and after tasks are executed. You can
+ * add as many custom callbacks as you want. (default: none)
+ */
+ private final List callbacks = new ArrayList<>();
+
+ /**
+ * Whether Flyway should skip the default callbacks. If true, only custom callbacks are used.
+ *
(default: false)
+ */
+ private boolean skipDefaultCallbacks;
+
+ /**
+ * The custom MigrationResolvers to be used in addition to the built-in ones for resolving Migrations to apply.
+ *
(default: none)
+ */
+ private MigrationResolver[] resolvers = new MigrationResolver[0];
+
+ /**
+ * Whether Flyway should skip the default resolvers. If true, only custom resolvers are used.
+ *
(default: false)
+ */
+ private boolean skipDefaultResolvers;
+
+ /**
+ * Whether to allow mixing transactional and non-transactional statements within the same migration.
+ *
+ * {@code true} if mixed migrations should be allowed. {@code false} if an error should be thrown instead. (default: {@code false})
+ */
+ private boolean mixed;
+
+ /**
+ * Whether to group all pending migrations together in the same transaction when applying them (only recommended for databases with support for DDL transactions).
+ *
+ * {@code true} if migrations should be grouped. {@code false} if they should be applied individually instead. (default: {@code false})
+ */
+ private boolean group;
+
+ /**
+ * The username that will be recorded in the schema history table as having applied the migration.
+ *
+ * {@code null} for the current database user of the connection. (default: {@code null}).
+ */
+ private String installedBy;
+
+ /**
+ * Whether Flyway should attempt to create the schemas specified in the schemas property
+ *
+ * {@code true} if flyway should create the schemas. {@code false} if flyway should not. (default: {@code true})
+ */
+ private boolean createSchemas = true;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /**
+ * Creates a new default configuration.
+ */
+ public ClassicConfiguration() {
+ // Nothing to do.
+ }
+
+ /**
+ * Creates a new default configuration with this classloader.
+ *
+ * @param classLoader The ClassLoader to use for loading migrations, resolvers, etc from the classpath. (default: Thread.currentThread().getContextClassLoader() )
+ */
+ public ClassicConfiguration(ClassLoader classLoader) {
+ if (classLoader != null) {
+ this.classLoader = classLoader;
+ }
+ }
+
+ /**
+ * Creates a new configuration with the same values as this existing one.
+ *
+ * @param configuration The configuration to use.
+ */
+ public ClassicConfiguration(Configuration configuration) {
+ this(configuration.getClassLoader());
+ configure(configuration);
+ }
+
+ @Override
+ public Location[] getLocations() {
+ return locations.getLocations().toArray(new Location[0]);
+ }
+
+ @Override
+ public Charset getEncoding() {
+ return encoding;
+ }
+
+ @Override
+ public String getDefaultSchema() { return defaultSchemaName; }
+
+ @Override
+ public String[] getSchemas() { return schemaNames; }
+
+ @Override
+ public String getTable() {
+ return table;
+ }
+
+ @Override
+ public String getTablespace() {
+ return tablespace;
+ }
+
+ @Override
+ public MigrationVersion getTarget() {
+ return target;
+ }
+
+ @Override
+ public boolean isPlaceholderReplacement() {
+ return placeholderReplacement;
+ }
+
+ @Override
+ public Map getPlaceholders() {
+ return placeholders;
+ }
+
+ @Override
+ public String getPlaceholderPrefix() {
+ return placeholderPrefix;
+ }
+
+ @Override
+ public String getPlaceholderSuffix() {
+ return placeholderSuffix;
+ }
+
+ @Override
+ public String getSqlMigrationPrefix() {
+ return sqlMigrationPrefix;
+ }
+
+ @Override
+ public String getRepeatableSqlMigrationPrefix() {
+ return repeatableSqlMigrationPrefix;
+ }
+
+ @Override
+ public String getSqlMigrationSeparator() {
+ return sqlMigrationSeparator;
+ }
+
+ @Override
+ public String[] getSqlMigrationSuffixes() {
+ return sqlMigrationSuffixes;
+ }
+
+ @Override
+ public JavaMigration[] getJavaMigrations() {
+ return javaMigrations;
+ }
+
+ @Override
+ public boolean isIgnoreMissingMigrations() {
+ return ignoreMissingMigrations;
+ }
+
+ @Override
+ public boolean isIgnoreIgnoredMigrations() {
+ return ignoreIgnoredMigrations;
+ }
+
+ @Override
+ public boolean isIgnorePendingMigrations() {
+ return ignorePendingMigrations;
+ }
+
+ @Override
+ public boolean isIgnoreFutureMigrations() {
+ return ignoreFutureMigrations;
+ }
+
+ @Override
+ public boolean isValidateMigrationNaming() {
+ return validateMigrationNaming;
+ }
+
+ @Override
+ public boolean isValidateOnMigrate() {
+ return validateOnMigrate;
+ }
+
+ @Override
+ public boolean isCleanOnValidationError() {
+ return cleanOnValidationError;
+ }
+
+ @Override
+ public boolean isCleanDisabled() {
+ return cleanDisabled;
+ }
+
+ @Override
+ public MigrationVersion getBaselineVersion() {
+ return baselineVersion;
+ }
+
+ @Override
+ public String getBaselineDescription() {
+ return baselineDescription;
+ }
+
+ @Override
+ public boolean isBaselineOnMigrate() {
+ return baselineOnMigrate;
+ }
+
+ @Override
+ public boolean isOutOfOrder() {
+ return outOfOrder;
+ }
+
+ @Override
+ public MigrationResolver[] getResolvers() {
+ return resolvers;
+ }
+
+ @Override
+ public boolean isSkipDefaultResolvers() {
+ return skipDefaultResolvers;
+ }
+
+ @Override
+ public DataSource getDataSource() {
+ if (dataSource == null &&
+ (StringUtils.hasLength(driver) || StringUtils.hasLength(user) || StringUtils.hasLength(password))) {
+ LOG.warn("Discarding INCOMPLETE dataSource configuration! " + ConfigUtils.URL + " must be set.");
+ }
+ return dataSource;
+ }
+
+ @Override
+ public int getConnectRetries() {
+ return connectRetries;
+ }
+
+ @Override
+ public String getInitSql() {
+ return initSql;
+ }
+
+ @Override
+ public ClassLoader getClassLoader() {
+ return classLoader;
+ }
+
+ @Override
+ public boolean isMixed() {
+ return mixed;
+ }
+
+ @Override
+ public String getInstalledBy() {
+ return installedBy;
+ }
+
+ @Override
+ public boolean isGroup() {
+ return group;
+ }
+
+ @Override
+ public String[] getErrorOverrides() {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("errorOverrides");
+
+
+
+
+ }
+
+ @Override
+ public OutputStream getDryRunOutput() {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("dryRunOutput");
+
+
+
+
+ }
+
+ @Override
+ public String getLicenseKey() {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("licenseKey");
+
+
+
+
+ }
+
+ /**
+ * Whether Flyway should output a table with the results of queries when executing migrations.
+ *
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @return {@code true} to output the results table (default: {@code true})
+ */
+ @Override
+ public boolean outputQueryResults() {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("outputQueryResults");
+
+
+
+
+ }
+
+ @Override
+ public ResourceProvider getResourceProvider() {
+ return resourceProvider;
+ }
+
+ @Override
+ public ClassProvider getJavaMigrationClassProvider() {
+ return javaMigrationClassProvider;
+ }
+
+ @Override
+ public boolean getCreateSchemas() {
+ return createSchemas;
+ }
+
+ /**
+ * Sets the stream where to output the SQL statements of a migration dry run. {@code null} to execute the SQL statements
+ * directly against the database. The stream when be closing when Flyway finishes writing the output.
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param dryRunOutput The output file or {@code null} to execute the SQL statements directly against the database.
+ */
+ public void setDryRunOutput(OutputStream dryRunOutput) {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("dryRunOutput");
+
+
+
+
+ }
+
+ /**
+ * Sets the file where to output the SQL statements of a migration dry run. {@code null} to execute the SQL statements
+ * directly against the database. If the file specified is in a non-existent directory, Flyway will create all
+ * directories and parent directories as needed.
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param dryRunOutput The output file or {@code null} to execute the SQL statements directly against the database.
+ */
+ public void setDryRunOutputAsFile(File dryRunOutput) {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("dryRunOutput");
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+ /**
+ * Sets the file where to output the SQL statements of a migration dry run. {@code null} to execute the SQL statements
+ * directly against the database. If the file specified is in a non-existent directory, Flyway will create all
+ * directories and parent directories as needed.
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param dryRunOutputFileName The name of the output file or {@code null} to execute the SQL statements directly
+ * against the database.
+ */
+ public void setDryRunOutputAsFileName(String dryRunOutputFileName) {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("dryRunOutput");
+
+
+
+
+ }
+
+ /**
+ * Rules for the built-in error handler that let you override specific SQL states and errors codes in order to force
+ * specific errors or warnings to be treated as debug messages, info messages, warnings or errors.
+ *
Each error override has the following format: {@code STATE:12345:W}.
+ * It is a 5 character SQL state (or * to match all SQL states), a colon,
+ * the SQL error code (or * to match all SQL error codes), a colon and finally
+ * the desired behavior that should override the initial one.
+ *
The following behaviors are accepted:
+ *
+ *
{@code D} to force a debug message
+ *
{@code D-} to force a debug message, but do not show the original sql state and error code
+ *
{@code I} to force an info message
+ *
{@code I-} to force an info message, but do not show the original sql state and error code
+ *
{@code W} to force a warning
+ *
{@code W-} to force a warning, but do not show the original sql state and error code
+ *
{@code E} to force an error
+ *
{@code E-} to force an error, but do not show the original sql state and error code
+ *
+ *
Example 1: to force Oracle stored procedure compilation issues to produce
+ * errors instead of warnings, the following errorOverride can be used: {@code 99999:17110:E}
+ *
Example 2: to force SQL Server PRINT messages to be displayed as info messages (without SQL state and error
+ * code details) instead of warnings, the following errorOverride can be used: {@code S0001:0:I-}
+ *
Example 3: to force all errors with SQL error code 123 to be treated as warnings instead,
+ * the following errorOverride can be used: {@code *:123:W}
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param errorOverrides The ErrorOverrides or an empty array if none are defined. (default: none)
+ */
+ public void setErrorOverrides(String... errorOverrides) {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("errorOverrides");
+
+
+
+
+ }
+
+ /**
+ * Whether to group all pending migrations together in the same transaction when applying them (only recommended for databases with support for DDL transactions).
+ *
+ * @param group {@code true} if migrations should be grouped. {@code false} if they should be applied individually instead. (default: {@code false})
+ */
+ public void setGroup(boolean group) {
+ this.group = group;
+ }
+
+ /**
+ * The username that will be recorded in the schema history table as having applied the migration.
+ *
+ * @param installedBy The username or {@code null} for the current database user of the connection. (default: {@code null}).
+ */
+ public void setInstalledBy(String installedBy) {
+ if ("".equals(installedBy)) {
+ installedBy = null;
+ }
+ this.installedBy = installedBy;
+ }
+
+ /**
+ * Whether to allow mixing transactional and non-transactional statements within the same migration. Enabling this
+ * automatically causes the entire affected migration to be run without a transaction.
+ *
+ *
Note that this is only applicable for PostgreSQL, Aurora PostgreSQL, SQL Server and SQLite which all have
+ * statements that do not run at all within a transaction.
+ *
This is not to be confused with implicit transaction, as they occur in MySQL or Oracle, where even though a
+ * DDL statement was run within a transaction, the database will issue an implicit commit before and after
+ * its execution.
+ *
+ * @param mixed {@code true} if mixed migrations should be allowed. {@code false} if an error should be thrown instead. (default: {@code false})
+ */
+ public void setMixed(boolean mixed) {
+ this.mixed = mixed;
+ }
+
+ /**
+ * Ignore missing migrations when reading the schema history table. These are migrations that were performed by an
+ * older deployment of the application that are no longer available in this version. For example: we have migrations
+ * available on the classpath with versions 1.0 and 3.0. The schema history table indicates that a migration with version 2.0
+ * (unknown to us) has also been applied. Instead of bombing out (fail fast) with an exception, a
+ * warning is logged and Flyway continues normally. This is useful for situations where one must be able to deploy
+ * a newer version of the application even though it doesn't contain migrations included with an older one anymore.
+ * Note that if the most recently applied migration is removed, Flyway has no way to know it is missing and will
+ * mark it as future instead.
+ *
+ * @param ignoreMissingMigrations {@code true} to continue normally and log a warning, {@code false} to fail fast with an exception.
+ * (default: {@code false})
+ */
+ public void setIgnoreMissingMigrations(boolean ignoreMissingMigrations) {
+ this.ignoreMissingMigrations = ignoreMissingMigrations;
+ }
+
+ /**
+ * Ignore ignored migrations when reading the schema history table. These are migrations that were added in between
+ * already migrated migrations in this version. For example: we have migrations available on the classpath with
+ * versions from 1.0 to 3.0. The schema history table indicates that version 1 was finished on 1.0.15, and the next
+ * 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
+ * by migrate command, but by default is rejected by validate. When ignoreIgnoredMigrations is enabled, such case
+ * will not be reported by validate command. This is useful for situations where one must be able to deliver
+ * complete set of migrations in a delivery package for multiple versions of the product, and allows for further
+ * development of older versions.
+ *
+ * @param ignoreIgnoredMigrations {@code true} to continue normally, {@code false} to fail fast with an exception.
+ * (default: {@code false})
+ */
+ public void setIgnoreIgnoredMigrations(boolean ignoreIgnoredMigrations) {
+ this.ignoreIgnoredMigrations = ignoreIgnoredMigrations;
+ }
+
+ /**
+ * Ignore pending migrations when reading the schema history table. These are migrations that are available
+ * but have not yet been applied. This can be useful for verifying that in-development migration changes
+ * don't contain any validation-breaking changes of migrations that have already been applied to a production
+ * environment, e.g. as part of a CI/CD process, without failing because of the existence of new migration versions.
+ *
+ * @param ignorePendingMigrations {@code true} to continue normally, {@code false} to fail fast with an exception.
+ * (default: {@code false})
+ */
+ public void setIgnorePendingMigrations(boolean ignorePendingMigrations) {
+ this.ignorePendingMigrations = ignorePendingMigrations;
+ }
+
+ /**
+ * Whether to ignore future migrations when reading the schema history table. These are migrations that were performed by a
+ * newer deployment of the application that are not yet available in this version. For example: we have migrations
+ * available on the classpath up to version 3.0. The schema history table indicates that a migration to version 4.0
+ * (unknown to us) has already been applied. Instead of bombing out (fail fast) with an exception, a
+ * warning is logged and Flyway continues normally. This is useful for situations where one must be able to redeploy
+ * an older version of the application after the database has been migrated by a newer one.
+ *
+ * @param ignoreFutureMigrations {@code true} to continue normally and log a warning, {@code false} to fail
+ * fast with an exception. (default: {@code true})
+ */
+ public void setIgnoreFutureMigrations(boolean ignoreFutureMigrations) {
+ this.ignoreFutureMigrations = ignoreFutureMigrations;
+ }
+
+ /**
+ * Whether to validate migrations and callbacks whose scripts do not obey the correct naming convention. A failure can be
+ * useful to check that errors such as case sensitivity in migration prefixes have been corrected.
+ *
+ * @param validateMigrationNaming {@code false} to continue normally, {@code true} to fail
+ * fast with an exception. (default: {@code false})
+ */
+ public void setValidateMigrationNaming(boolean validateMigrationNaming) {
+ this.validateMigrationNaming = validateMigrationNaming;
+ }
+
+ /**
+ * Whether to automatically call validate or not when running migrate.
+ *
+ * @param validateOnMigrate {@code true} if validate should be called. {@code false} if not. (default: {@code true})
+ */
+ public void setValidateOnMigrate(boolean validateOnMigrate) {
+ this.validateOnMigrate = validateOnMigrate;
+ }
+
+ /**
+ * Whether to automatically call clean or not when a validation error occurs.
+ *
This is exclusively intended as a convenience for development. even though we
+ * strongly recommend not to change migration scripts once they have been checked into SCM and run, this provides a
+ * way of dealing with this case in a smooth manner. The database will be wiped clean automatically, ensuring that
+ * the next migration will bring you back to the state checked into SCM.
+ *
Warning ! Do not enable in production !
+ *
+ * @param cleanOnValidationError {@code true} if clean should be called. {@code false} if not. (default: {@code false})
+ */
+ public void setCleanOnValidationError(boolean cleanOnValidationError) {
+ this.cleanOnValidationError = cleanOnValidationError;
+ }
+
+ /**
+ * Whether to disable clean.
+ *
This is especially useful for production environments where running clean can be quite a career limiting move.
+ *
+ * @param cleanDisabled {@code true} to disable clean. {@code false} to leave it enabled. (default: {@code false})
+ */
+ public void setCleanDisabled(boolean cleanDisabled) {
+ this.cleanDisabled = cleanDisabled;
+ }
+
+ /**
+ * Sets the locations to scan recursively for migrations.
+ *
The location type is determined by its prefix.
+ * Unprefixed locations or locations starting with {@code classpath:} point to a package on the classpath and may
+ * contain both SQL and Java-based migrations.
+ * Locations starting with {@code filesystem:} point to a directory on the filesystem, may only
+ * contain SQL migrations and are only scanned recursively down non-hidden directories.
+ *
+ * @param locations Locations to scan recursively for migrations. (default: db/migration)
+ */
+ public void setLocationsAsStrings(String... locations) {
+ this.locations = new Locations(locations);
+ }
+
+ /**
+ * Sets the locations to scan recursively for migrations.
+ *
The location type is determined by its prefix.
+ * Unprefixed locations or locations starting with {@code classpath:} point to a package on the classpath and may
+ * contain both SQL and Java-based migrations.
+ * Locations starting with {@code filesystem:} point to a directory on the filesystem, may only
+ * contain SQL migrations and are only scanned recursively down non-hidden directories.
+ *
+ * @param locations Locations to scan recursively for migrations. (default: db/migration)
+ */
+ public void setLocations(Location... locations) {
+ this.locations = new Locations(Arrays.asList(locations));
+ }
+
+ /**
+ * Sets the encoding of Sql migrations.
+ *
+ * @param encoding The encoding of Sql migrations. (default: UTF-8)
+ */
+ public void setEncoding(Charset encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * Sets the encoding of Sql migrations.
+ *
+ * @param encoding The encoding of Sql migrations. (default: UTF-8)
+ */
+ public void setEncodingAsString(String encoding) {
+ this.encoding = Charset.forName(encoding);
+ }
+
+ /**
+ * Sets the default schema managed by Flyway. This schema name is case-sensitive. If not specified, but
+ * Schemas is, Flyway uses the first schema in that list. If that is also not specified, Flyway uses the default
+ * schema for the database connection.
+ *
Consequences:
+ *
+ *
This schema will be the one containing the schema history table.
+ *
This schema will be the default for the database connection (provided the database supports this concept).
+ *
+ *
+ * @param schema The default schema managed by Flyway.
+ */
+ public void setDefaultSchema(String schema) {
+ this.defaultSchemaName = schema;
+ }
+
+ /**
+ * Sets the schemas managed by Flyway. These schema names are case-sensitive. If not specified, Flyway uses
+ * the default schema for the database connection. If defaultSchema is not specified, then the first of
+ * this list also acts as default schema.
+ *
Consequences:
+ *
+ *
Flyway will automatically attempt to create all these schemas, unless they already exist.
+ *
The schemas will be cleaned in the order of this list.
+ *
If Flyway created them, the schemas themselves will be dropped when cleaning.
+ *
+ *
+ * @param schemas The schemas managed by Flyway. May not be {@code null}. Must contain at least one element.
+ */
+ public void setSchemas(String... schemas) {
+ this.schemaNames = schemas;
+ }
+
+ /**
+ *
Sets the name of the schema history table that will be used by Flyway.
By default (single-schema mode)
+ * the schema history table is placed in the default schema for the connection provided by the datasource.
When
+ * the flyway.schemas property is set (multi-schema mode), the schema history table is placed in the first schema
+ * of the list.
+ *
+ * @param table The name of the schema history table that will be used by Flyway. (default: flyway_schema_history)
+ */
+ public void setTable(String table) {
+ this.table = table;
+ }
+
+ /**
+ *
Sets the tablespace where to create the schema history table that will be used by Flyway.
+ *
If not specified, Flyway uses the default tablespace for the database connection.This setting is only relevant
+ * for databases that do support the notion of tablespaces. Its value is simply
+ * ignored for all others.
+ *
+ * @param tablespace The tablespace where to create the schema history table that will be used by Flyway.
+ */
+ public void setTablespace(String tablespace) {
+ this.tablespace = tablespace;
+ }
+
+ /**
+ * Sets the target version up to which Flyway should consider migrations.
+ * Migrations with a higher version number will be ignored.
+ * Special values:
+ *
+ *
{@code current}: designates the current version of the schema
+ *
{@code latest}: the latest version of the schema, as defined by the migration with the highest version
+ *
+ * Defaults to {@code latest}.
+ */
+ public void setTarget(MigrationVersion target) {
+ this.target = target;
+ }
+
+ /**
+ * Sets the target version up to which Flyway should consider migrations.
+ * Migrations with a higher version number will be ignored.
+ * Special values:
+ *
+ *
{@code current}: designates the current version of the schema
+ *
{@code latest}: the latest version of the schema, as defined by the migration with the highest version
+ *
+ * Defaults to {@code latest}.
+ */
+ public void setTargetAsString(String target) {
+ this.target = MigrationVersion.fromVersion(target);
+ }
+
+ /**
+ * Sets whether placeholders should be replaced.
+ *
+ * @param placeholderReplacement Whether placeholders should be replaced. (default: true)
+ */
+ public void setPlaceholderReplacement(boolean placeholderReplacement) {
+ this.placeholderReplacement = placeholderReplacement;
+ }
+
+ /**
+ * Sets the placeholders to replace in sql migration scripts.
+ *
+ * @param placeholders The map of <placeholder, replacementValue> to apply to sql migration scripts.
+ */
+ public void setPlaceholders(Map placeholders) {
+ this.placeholders = placeholders;
+ }
+
+ /**
+ * Sets the prefix of every placeholder.
+ *
+ * @param placeholderPrefix The prefix of every placeholder. (default: ${ )
+ */
+ public void setPlaceholderPrefix(String placeholderPrefix) {
+ if (!StringUtils.hasLength(placeholderPrefix)) {
+ throw new FlywayException("placeholderPrefix cannot be empty!", ErrorCode.CONFIGURATION);
+ }
+ this.placeholderPrefix = placeholderPrefix;
+ }
+
+ /**
+ * Sets the suffix of every placeholder.
+ *
+ * @param placeholderSuffix The suffix of every placeholder. (default: } )
+ */
+ public void setPlaceholderSuffix(String placeholderSuffix) {
+ if (!StringUtils.hasLength(placeholderSuffix)) {
+ throw new FlywayException("placeholderSuffix cannot be empty!", ErrorCode.CONFIGURATION);
+ }
+ this.placeholderSuffix = placeholderSuffix;
+ }
+
+ /**
+ * Sets the file name prefix for sql migrations.
+ *
Sql migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to V1_1__My_description.sql
+ *
+ * @param sqlMigrationPrefix The file name prefix for sql migrations (default: V)
+ */
+ public void setSqlMigrationPrefix(String sqlMigrationPrefix) {
+ this.sqlMigrationPrefix = sqlMigrationPrefix;
+ }
+
+ @Override
+ public String getUndoSqlMigrationPrefix() {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("undoSqlMigrationPrefix");
+
+
+
+
+ }
+
+ /**
+ * Sets the file name prefix for undo SQL migrations. (default: U)
+ *
Undo SQL migrations are responsible for undoing the effects of the versioned migration with the same version.
+ *
They have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to U1.1__My_description.sql
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param undoSqlMigrationPrefix The file name prefix for undo SQL migrations. (default: U)
+ */
+ public void setUndoSqlMigrationPrefix(String undoSqlMigrationPrefix) {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("undoSqlMigrationPrefix");
+
+
+
+
+ }
+
+ /**
+ * The manually added Java-based migrations. These are not Java-based migrations discovered through classpath
+ * scanning and instantiated by Flyway. Instead these are manually added instances of JavaMigration.
+ * This is particularly useful when working with a dependency injection container, where you may want the DI
+ * container to instantiate the class and wire up its dependencies for you.
+ *
+ * @param javaMigrations The manually added Java-based migrations. An empty array if none. (default: none)
+ */
+ public void setJavaMigrations(JavaMigration... javaMigrations) {
+ if (javaMigrations == null) {
+ throw new FlywayException("javaMigrations cannot be null", ErrorCode.CONFIGURATION);
+ }
+ this.javaMigrations = javaMigrations;
+ }
+
+ @Override
+ public boolean isStream() {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("stream");
+
+
+
+
+ }
+
+ /**
+ * Whether to stream SQL migrations when executing them. Streaming doesn't load the entire migration in memory at
+ * once. Instead each statement is loaded individually. This is particularly useful for very large SQL migrations
+ * composed of multiple MB or even GB of reference data, as this dramatically reduces Flyway's memory consumption.
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param stream {@code true} to stream SQL migrations. {@code false} to fully loaded them in memory instead. (default: {@code false})
+ */
+ public void setStream(boolean stream) {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("stream");
+
+
+
+
+ }
+
+ @Override
+ public boolean isBatch() {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("batch");
+
+
+
+
+ }
+
+ /**
+ * Whether to batch SQL statements when executing them. Batching can save up to 99 percent of network roundtrips by
+ * sending up to 100 statements at once over the network to the database, instead of sending each statement
+ * individually. This is particularly useful for very large SQL migrations composed of multiple MB or even GB of
+ * reference data, as this can dramatically reduce the network overhead. This is supported for INSERT, UPDATE,
+ * DELETE, MERGE and UPSERT statements. All other statements are automatically executed without batching.
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param batch {@code true} to batch SQL statements. {@code false} to execute them individually instead. (default: {@code false})
+ */
+ public void setBatch(boolean batch) {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("batch");
+
+
+
+
+ }
+
+ /**
+ * Sets the file name prefix for repeatable sql migrations.
+ *
Repeatable sql migrations have the following file name structure: prefixSeparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to R__My_description.sql
+ *
+ * @param repeatableSqlMigrationPrefix The file name prefix for repeatable sql migrations (default: R)
+ */
+ public void setRepeatableSqlMigrationPrefix(String repeatableSqlMigrationPrefix) {
+ this.repeatableSqlMigrationPrefix = repeatableSqlMigrationPrefix;
+ }
+
+ /**
+ * Sets the file name separator for sql migrations.
+ *
Sql migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to V1_1__My_description.sql
+ *
+ * @param sqlMigrationSeparator The file name separator for sql migrations (default: __)
+ */
+ public void setSqlMigrationSeparator(String sqlMigrationSeparator) {
+ if (!StringUtils.hasLength(sqlMigrationSeparator)) {
+ throw new FlywayException("sqlMigrationSeparator cannot be empty!", ErrorCode.CONFIGURATION);
+ }
+
+ this.sqlMigrationSeparator = sqlMigrationSeparator;
+ }
+
+ /**
+ * The file name suffixes for SQL migrations. (default: .sql)
+ *
SQL migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to V1_1__My_description.sql
+ *
Multiple suffixes (like .sql,.pkg,.pkb) can be specified for easier compatibility with other tools such as
+ * editors with specific file associations.
+ *
+ * @param sqlMigrationSuffixes The file name suffixes for SQL migrations.
+ */
+ public void setSqlMigrationSuffixes(String... sqlMigrationSuffixes) {
+ this.sqlMigrationSuffixes = sqlMigrationSuffixes;
+ }
+
+ /**
+ * Sets the datasource to use. Must have the necessary privileges to execute ddl.
+ *
+ * @param dataSource The datasource to use. Must have the necessary privileges to execute ddl.
+ */
+ public void setDataSource(DataSource dataSource) {
+ driver = null;
+ url = null;
+ user = null;
+ password = null;
+ this.dataSource = dataSource;
+ }
+
+ /**
+ * Sets the datasource to use. Must have the necessary privileges to execute ddl.
+ *
To use a custom ClassLoader, setClassLoader() must be called prior to calling this method.
+ *
+ * @param url The JDBC URL of the database.
+ * @param user The user of the database.
+ * @param password The password of the database.
+ */
+ public void setDataSource(String url, String user, String password) {
+ this.dataSource = new DriverDataSource(classLoader, null, url, user, password);
+ }
+
+ /**
+ * The maximum number of retries when attempting to connect to the database. After each failed attempt, Flyway will
+ * wait 1 second before attempting to connect again, up to the maximum number of times specified by connectRetries.
+ *
+ * @param connectRetries The maximum number of retries (default: 0).
+ */
+ public void setConnectRetries(int connectRetries) {
+ if (connectRetries < 0) {
+ throw new FlywayException("Invalid number of connectRetries (must be 0 or greater): " + connectRetries, ErrorCode.CONFIGURATION);
+ }
+ this.connectRetries = connectRetries;
+ }
+
+ /**
+ * The SQL statements to run to initialize a new database connection immediately after opening it.
+ *
+ * @param initSql The SQL statements. (default: {@code null})
+ */
+ public void setInitSql(String initSql) {
+ this.initSql = initSql;
+ }
+
+ /**
+ * Sets the version to tag an existing schema with when executing baseline.
+ *
+ * @param baselineVersion The version to tag an existing schema with when executing baseline. (default: 1)
+ */
+ public void setBaselineVersion(MigrationVersion baselineVersion) {
+ this.baselineVersion = baselineVersion;
+ }
+
+ /**
+ * Sets the version to tag an existing schema with when executing baseline.
+ *
+ * @param baselineVersion The version to tag an existing schema with when executing baseline. (default: 1)
+ */
+ public void setBaselineVersionAsString(String baselineVersion) {
+ this.baselineVersion = MigrationVersion.fromVersion(baselineVersion);
+ }
+
+ /**
+ * Sets the description to tag an existing schema with when executing baseline.
+ *
+ * @param baselineDescription The description to tag an existing schema with when executing baseline. (default: << Flyway Baseline >>)
+ */
+ public void setBaselineDescription(String baselineDescription) {
+ this.baselineDescription = baselineDescription;
+ }
+
+ /**
+ *
+ * Whether to automatically call baseline when migrate is executed against a non-empty schema with no schema history table.
+ * This schema will then be baselined with the {@code baselineVersion} before executing the migrations.
+ * Only migrations above {@code baselineVersion} will then be applied.
+ *
+ *
+ * This is useful for initial Flyway production deployments on projects with an existing DB.
+ *
+ *
+ * Be careful when enabling this as it removes the safety net that ensures
+ * Flyway does not migrate the wrong database in case of a configuration mistake!
+ *
+ *
+ * @param baselineOnMigrate {@code true} if baseline should be called on migrate for non-empty schemas, {@code false} if not. (default: {@code false})
+ */
+ public void setBaselineOnMigrate(boolean baselineOnMigrate) {
+ this.baselineOnMigrate = baselineOnMigrate;
+ }
+
+ /**
+ * Allows migrations to be run "out of order".
+ *
If you already have versions 1 and 3 applied, and now a version 2 is found,
+ * it will be applied too instead of being ignored.
+ *
+ * @param outOfOrder {@code true} if outOfOrder migrations should be applied, {@code false} if not. (default: {@code false})
+ */
+ public void setOutOfOrder(boolean outOfOrder) {
+ this.outOfOrder = outOfOrder;
+ }
+
+ /**
+ * Gets the callbacks for lifecycle notifications.
+ *
+ * @return The callbacks for lifecycle notifications. An empty array if none. (default: none)
+ */
+ @Override
+ public Callback[] getCallbacks() {
+ return callbacks.toArray(new Callback[0]);
+ }
+
+ @Override
+ public boolean isSkipDefaultCallbacks() {
+ return skipDefaultCallbacks;
+ }
+
+ /**
+ * Set the callbacks for lifecycle notifications.
+ *
+ * @param callbacks The callbacks for lifecycle notifications. (default: none)
+ */
+ public void setCallbacks(Callback... callbacks) {
+ this.callbacks.clear();
+ this.callbacks.addAll(Arrays.asList(callbacks));
+ }
+
+ /**
+ * Set the callbacks for lifecycle notifications.
+ *
+ * @param callbacks The fully qualified class names of the callbacks for lifecycle notifications. (default: none)
+ */
+ public void setCallbacksAsClassNames(String... callbacks) {
+ this.callbacks.clear();
+ for (String callback : callbacks) {
+ Object o = ClassUtils.instantiate(callback, classLoader);
+ if (o instanceof Callback) {
+ this.callbacks.add((Callback) o);
+ } else {
+ throw new FlywayException("Invalid callback: " + callback + " (must implement org.flywaydb.core.api.callback.Callback)", ErrorCode.CONFIGURATION);
+ }
+ }
+ }
+
+ /**
+ * Whether Flyway should skip the default callbacks. If true, only custom callbacks are used.
+ *
+ * @param skipDefaultCallbacks Whether default built-in callbacks should be skipped.
(default: false)
+ */
+ public void setSkipDefaultCallbacks(boolean skipDefaultCallbacks) {
+ this.skipDefaultCallbacks = skipDefaultCallbacks;
+ }
+
+ /**
+ * Sets custom MigrationResolvers to be used in addition to the built-in ones for resolving Migrations to apply.
+ *
+ * @param resolvers The custom MigrationResolvers to be used in addition to the built-in ones for resolving Migrations to apply. (default: empty list)
+ */
+ public void setResolvers(MigrationResolver... resolvers) {
+ this.resolvers = resolvers;
+ }
+
+ /**
+ * Sets custom MigrationResolvers to be used in addition to the built-in ones for resolving Migrations to apply.
+ *
+ * @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)
+ */
+ public void setResolversAsClassNames(String... resolvers) {
+ List resolverList = ClassUtils.instantiateAll(resolvers, classLoader);
+ setResolvers(resolverList.toArray(new MigrationResolver[resolvers.length]));
+ }
+
+ /**
+ * Whether Flyway should skip the default resolvers. If true, only custom resolvers are used.
+ *
+ * @param skipDefaultResolvers Whether default built-in resolvers should be skipped.
(default: false)
+ */
+ public void setSkipDefaultResolvers(boolean skipDefaultResolvers) {
+ this.skipDefaultResolvers = skipDefaultResolvers;
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ @Override
+ public boolean isOracleSqlplus() {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("oracle.sqlplus");
+
+
+
+
+ }
+
+ /**
+ * Whether to Flyway's support for Oracle SQL*Plus commands should be activated.
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param oracleSqlplus {@code true} to active SQL*Plus support. {@code false} to fail fast instead. (default: {@code false})
+ */
+ public void setOracleSqlplus(boolean oracleSqlplus) {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("oracle.sqlplus");
+
+
+
+
+ }
+
+ @Override
+ public boolean isOracleSqlplusWarn() {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("oracle.sqlplusWarn");
+
+
+
+
+ }
+
+ /**
+ * Whether Flyway should issue a warning instead of an error whenever it encounters an Oracle SQL*Plus statement
+ * it doesn't yet support.
+ *
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param oracleSqlplusWarn {@code true} to issue a warning. {@code false} to fail fast instead. (default: {@code false})
+ */
+ public void setOracleSqlplusWarn(boolean oracleSqlplusWarn) {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("oracle.sqlplusWarn");
+
+
+
+
+ }
+
+ /**
+ * Whether Flyway should attempt to create the schemas specified in the schemas property
+ *
+ * @param createSchemas @{code true} to attempt to create the schemas (default: {@code true})
+ */
+ public void setShouldCreateSchemas(boolean createSchemas) {
+ this.createSchemas = createSchemas;
+ }
+
+ /**
+ * Your Flyway license key (FL01...). Not yet a Flyway Pro or Enterprise Edition customer?
+ * Request your Flyway trial license key
+ * to try out Flyway Pro and Enterprise Edition features free for 30 days.
+ *
+ *
+ *
+ * @return {@code true} to output the results table (default: {@code true})
+ */
+ private void setOutputQueryResults(boolean outputQueryResults) {
+
+ throw new org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException("outputQueryResults");
+
+
+
+
+ }
+
+ /**
+ * Configures Flyway with these properties. This overwrites any existing configuration. Property names are
+ * documented in the flyway maven plugin.
+ *
To use a custom ClassLoader, setClassLoader() must be called prior to calling this method.
+ *
+ * @param properties Properties used for configuration.
+ * @throws FlywayException when the configuration failed.
+ */
+ public void configure(Properties properties) {
+ configure(ConfigUtils.propertiesToMap(properties));
+ }
+
+ /**
+ * Configures Flyway with these properties. This overwrites any existing configuration. Property names are
+ * documented in the flyway maven plugin.
+ *
To use a custom ClassLoader, it must be passed to the Flyway constructor prior to calling this method.
+ *
+ * @param props Properties used for configuration.
+ * @throws FlywayException when the configuration failed.
+ */
+ public void configure(Map props) {
+ // Make copy to prevent removing elements from the original.
+ props = new HashMap<>(props);
+
+ String driverProp = props.remove(ConfigUtils.DRIVER);
+ if (driverProp != null) {
+ dataSource = null;
+ driver = driverProp;
+ }
+ String urlProp = props.remove(ConfigUtils.URL);
+ if (urlProp != null) {
+ dataSource = null;
+ url = urlProp;
+ }
+ String userProp = props.remove(ConfigUtils.USER);
+ if (userProp != null) {
+ dataSource = null;
+ user = userProp;
+ }
+ String passwordProp = props.remove(ConfigUtils.PASSWORD);
+ if (passwordProp != null) {
+ dataSource = null;
+ password = passwordProp;
+ }
+ if (StringUtils.hasText(url) && (StringUtils.hasText(urlProp) ||
+ StringUtils.hasText(driverProp) || StringUtils.hasText(userProp) || StringUtils.hasText(passwordProp))) {
+ setDataSource(new DriverDataSource(classLoader, driver, url, user, password));
+ }
+ Integer connectRetriesProp = removeInteger(props, ConfigUtils.CONNECT_RETRIES);
+ if (connectRetriesProp != null) {
+ setConnectRetries(connectRetriesProp);
+ }
+ String initSqlProp = props.remove(ConfigUtils.INIT_SQL);
+ if (initSqlProp != null) {
+ setInitSql(initSqlProp);
+ }
+ String locationsProp = props.remove(ConfigUtils.LOCATIONS);
+ if (locationsProp != null) {
+ setLocationsAsStrings(StringUtils.tokenizeToStringArray(locationsProp, ","));
+ }
+ Boolean placeholderReplacementProp = removeBoolean(props, ConfigUtils.PLACEHOLDER_REPLACEMENT);
+ if (placeholderReplacementProp != null) {
+ setPlaceholderReplacement(placeholderReplacementProp);
+ }
+ String placeholderPrefixProp = props.remove(ConfigUtils.PLACEHOLDER_PREFIX);
+ if (placeholderPrefixProp != null) {
+ setPlaceholderPrefix(placeholderPrefixProp);
+ }
+ String placeholderSuffixProp = props.remove(ConfigUtils.PLACEHOLDER_SUFFIX);
+ if (placeholderSuffixProp != null) {
+ setPlaceholderSuffix(placeholderSuffixProp);
+ }
+ String sqlMigrationPrefixProp = props.remove(ConfigUtils.SQL_MIGRATION_PREFIX);
+ if (sqlMigrationPrefixProp != null) {
+ setSqlMigrationPrefix(sqlMigrationPrefixProp);
+ }
+ String undoSqlMigrationPrefixProp = props.remove(ConfigUtils.UNDO_SQL_MIGRATION_PREFIX);
+ if (undoSqlMigrationPrefixProp != null) {
+ setUndoSqlMigrationPrefix(undoSqlMigrationPrefixProp);
+ }
+ String repeatableSqlMigrationPrefixProp = props.remove(ConfigUtils.REPEATABLE_SQL_MIGRATION_PREFIX);
+ if (repeatableSqlMigrationPrefixProp != null) {
+ setRepeatableSqlMigrationPrefix(repeatableSqlMigrationPrefixProp);
+ }
+ String sqlMigrationSeparatorProp = props.remove(ConfigUtils.SQL_MIGRATION_SEPARATOR);
+ if (sqlMigrationSeparatorProp != null) {
+ setSqlMigrationSeparator(sqlMigrationSeparatorProp);
+ }
+ String sqlMigrationSuffixesProp = props.remove(ConfigUtils.SQL_MIGRATION_SUFFIXES);
+ if (sqlMigrationSuffixesProp != null) {
+ setSqlMigrationSuffixes(StringUtils.tokenizeToStringArray(sqlMigrationSuffixesProp, ","));
+ }
+ String encodingProp = props.remove(ConfigUtils.ENCODING);
+ if (encodingProp != null) {
+ setEncodingAsString(encodingProp);
+ }
+ String defaultSchemaProp = props.remove(ConfigUtils.DEFAULT_SCHEMA);
+ if (defaultSchemaProp != null) {
+ setDefaultSchema(defaultSchemaProp);
+ }
+ String schemasProp = props.remove(ConfigUtils.SCHEMAS);
+ if (schemasProp != null) {
+ setSchemas(StringUtils.tokenizeToStringArray(schemasProp, ","));
+ }
+ String tableProp = props.remove(ConfigUtils.TABLE);
+ if (tableProp != null) {
+ setTable(tableProp);
+ }
+ String tablespaceProp = props.remove(ConfigUtils.TABLESPACE);
+ if (tablespaceProp != null) {
+ setTablespace(tablespaceProp);
+ }
+ Boolean cleanOnValidationErrorProp = removeBoolean(props, ConfigUtils.CLEAN_ON_VALIDATION_ERROR);
+ if (cleanOnValidationErrorProp != null) {
+ setCleanOnValidationError(cleanOnValidationErrorProp);
+ }
+ Boolean cleanDisabledProp = removeBoolean(props, ConfigUtils.CLEAN_DISABLED);
+ if (cleanDisabledProp != null) {
+ setCleanDisabled(cleanDisabledProp);
+ }
+ Boolean validateOnMigrateProp = removeBoolean(props, ConfigUtils.VALIDATE_ON_MIGRATE);
+ if (validateOnMigrateProp != null) {
+ setValidateOnMigrate(validateOnMigrateProp);
+ }
+ String baselineVersionProp = props.remove(ConfigUtils.BASELINE_VERSION);
+ if (baselineVersionProp != null) {
+ setBaselineVersion(MigrationVersion.fromVersion(baselineVersionProp));
+ }
+ String baselineDescriptionProp = props.remove(ConfigUtils.BASELINE_DESCRIPTION);
+ if (baselineDescriptionProp != null) {
+ setBaselineDescription(baselineDescriptionProp);
+ }
+ Boolean baselineOnMigrateProp = removeBoolean(props, ConfigUtils.BASELINE_ON_MIGRATE);
+ if (baselineOnMigrateProp != null) {
+ setBaselineOnMigrate(baselineOnMigrateProp);
+ }
+ Boolean ignoreMissingMigrationsProp = removeBoolean(props, ConfigUtils.IGNORE_MISSING_MIGRATIONS);
+ if (ignoreMissingMigrationsProp != null) {
+ setIgnoreMissingMigrations(ignoreMissingMigrationsProp);
+ }
+ Boolean ignoreIgnoredMigrationsProp = removeBoolean(props, ConfigUtils.IGNORE_IGNORED_MIGRATIONS);
+ if (ignoreIgnoredMigrationsProp != null) {
+ setIgnoreIgnoredMigrations(ignoreIgnoredMigrationsProp);
+ }
+ Boolean ignorePendingMigrationsProp = removeBoolean(props, ConfigUtils.IGNORE_PENDING_MIGRATIONS);
+ if (ignorePendingMigrationsProp != null) {
+ setIgnorePendingMigrations(ignorePendingMigrationsProp);
+ }
+ Boolean ignoreFutureMigrationsProp = removeBoolean(props, ConfigUtils.IGNORE_FUTURE_MIGRATIONS);
+ if (ignoreFutureMigrationsProp != null) {
+ setIgnoreFutureMigrations(ignoreFutureMigrationsProp);
+ }
+ Boolean validateMigrationNamingProp = removeBoolean(props, ConfigUtils.VALIDATE_MIGRATION_NAMING);
+ if (validateMigrationNamingProp != null) {
+ setValidateMigrationNaming(validateMigrationNamingProp);
+ }
+ String targetProp = props.remove(ConfigUtils.TARGET);
+ if (targetProp != null) {
+ setTarget(MigrationVersion.fromVersion(targetProp));
+ }
+ Boolean outOfOrderProp = removeBoolean(props, ConfigUtils.OUT_OF_ORDER);
+ if (outOfOrderProp != null) {
+ setOutOfOrder(outOfOrderProp);
+ }
+ Boolean outputQueryResultsProp = removeBoolean(props, ConfigUtils.OUTPUT_QUERY_RESULTS);
+ if (outputQueryResultsProp != null) {
+ setOutputQueryResults(outputQueryResultsProp);
+ }
+ String resolversProp = props.remove(ConfigUtils.RESOLVERS);
+ if (StringUtils.hasLength(resolversProp)) {
+ setResolversAsClassNames(StringUtils.tokenizeToStringArray(resolversProp, ","));
+ }
+ Boolean skipDefaultResolversProp = removeBoolean(props, ConfigUtils.SKIP_DEFAULT_RESOLVERS);
+ if (skipDefaultResolversProp != null) {
+ setSkipDefaultResolvers(skipDefaultResolversProp);
+ }
+ String callbacksProp = props.remove(ConfigUtils.CALLBACKS);
+ if (StringUtils.hasLength(callbacksProp)) {
+ setCallbacksAsClassNames(StringUtils.tokenizeToStringArray(callbacksProp, ","));
+ }
+ Boolean skipDefaultCallbacksProp = removeBoolean(props, ConfigUtils.SKIP_DEFAULT_CALLBACKS);
+ if (skipDefaultCallbacksProp != null) {
+ setSkipDefaultCallbacks(skipDefaultCallbacksProp);
+ }
+
+ Map placeholdersFromProps = new HashMap<>(getPlaceholders());
+ Iterator> iterator = props.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry entry = iterator.next();
+ String propertyName = entry.getKey();
+
+ if (propertyName.startsWith(ConfigUtils.PLACEHOLDERS_PROPERTY_PREFIX)
+ && propertyName.length() > ConfigUtils.PLACEHOLDERS_PROPERTY_PREFIX.length()) {
+ String placeholderName = propertyName.substring(ConfigUtils.PLACEHOLDERS_PROPERTY_PREFIX.length());
+ String placeholderValue = entry.getValue();
+ placeholdersFromProps.put(placeholderName, placeholderValue);
+ iterator.remove();
+ }
+ }
+ setPlaceholders(placeholdersFromProps);
+
+ Boolean mixedProp = removeBoolean(props, ConfigUtils.MIXED);
+ if (mixedProp != null) {
+ setMixed(mixedProp);
+ }
+
+ Boolean groupProp = removeBoolean(props, ConfigUtils.GROUP);
+ if (groupProp != null) {
+ setGroup(groupProp);
+ }
+
+ String installedByProp = props.remove(ConfigUtils.INSTALLED_BY);
+ if (installedByProp != null) {
+ setInstalledBy(installedByProp);
+ }
+
+ String dryRunOutputProp = props.remove(ConfigUtils.DRYRUN_OUTPUT);
+ if (dryRunOutputProp != null) {
+ setDryRunOutputAsFileName(dryRunOutputProp);
+ }
+
+ String errorOverridesProp = props.remove(ConfigUtils.ERROR_OVERRIDES);
+ if (errorOverridesProp != null) {
+ setErrorOverrides(StringUtils.tokenizeToStringArray(errorOverridesProp, ","));
+ }
+
+ Boolean streamProp = removeBoolean(props, ConfigUtils.STREAM);
+ if (streamProp != null) {
+ setStream(streamProp);
+ }
+
+ Boolean batchProp = removeBoolean(props, ConfigUtils.BATCH);
+ if (batchProp != null) {
+ setBatch(batchProp);
+ }
+
+ Boolean oracleSqlplusProp = removeBoolean(props, ConfigUtils.ORACLE_SQLPLUS);
+ if (oracleSqlplusProp != null) {
+ setOracleSqlplus(oracleSqlplusProp);
+ }
+
+ Boolean oracleSqlplusWarnProp = removeBoolean(props, ConfigUtils.ORACLE_SQLPLUS_WARN);
+ if (oracleSqlplusWarnProp != null) {
+ setOracleSqlplusWarn(oracleSqlplusWarnProp);
+ }
+
+ Boolean createSchemasProp = removeBoolean(props, ConfigUtils.CREATE_SCHEMAS);
+ if (createSchemasProp != null) {
+ setShouldCreateSchemas(createSchemasProp);
+ }
+
+ String licenseKeyProp = props.remove(ConfigUtils.LICENSE_KEY);
+ if (licenseKeyProp != null) {
+ setLicenseKey(licenseKeyProp);
+ }
+
+ ConfigUtils.checkConfigurationForUnrecognisedProperties(props, "flyway.");
+ }
+
+ /**
+ * Configures Flyway using FLYWAY_* environment variables.
+ */
+ public void configureUsingEnvVars() {
+ configure(ConfigUtils.environmentVariablesToPropertyMap());
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/configuration/Configuration.java a/flyway-core/src/main/java/org/flywaydb/core/api/configuration/Configuration.java
new file mode 100644
index 0000000..fa8a0f3
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/configuration/Configuration.java
@@ -0,0 +1,543 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.configuration;
+
+import org.flywaydb.core.api.Location;
+import org.flywaydb.core.api.MigrationVersion;
+import org.flywaydb.core.api.callback.Callback;
+import org.flywaydb.core.api.migration.JavaMigration;
+import org.flywaydb.core.api.resolver.MigrationResolver;
+import org.flywaydb.core.api.ClassProvider;
+import org.flywaydb.core.api.ResourceProvider;
+
+import javax.sql.DataSource;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+/**
+ * Flyway configuration.
+ */
+public interface Configuration {
+ /**
+ * Retrieves the ClassLoader to use for loading migrations, resolvers, etc from the classpath.
+ *
+ * @return The ClassLoader to use for loading migrations, resolvers, etc from the classpath.
+ * (default: Thread.currentThread().getContextClassLoader() )
+ */
+ ClassLoader getClassLoader();
+
+ /**
+ * Retrieves the dataSource to use to access the database. Must have the necessary privileges to execute ddl.
+ *
+ * @return The dataSource to use to access the database. Must have the necessary privileges to execute ddl.
+ */
+ DataSource getDataSource();
+
+ /**
+ * The maximum number of retries when attempting to connect to the database. After each failed attempt, Flyway will
+ * wait 1 second before attempting to connect again, up to the maximum number of times specified by connectRetries.
+ *
+ * @return The maximum number of retries when attempting to connect to the database. (default: 0)
+ */
+ int getConnectRetries();
+
+ /**
+ * The SQL statements to run to initialize a new database connection immediately after opening it.
+ *
+ * @return The SQL statements. (default: {@code null})
+ */
+ String getInitSql();
+
+ /**
+ * Retrieves the version to tag an existing schema with when executing baseline.
+ *
+ * @return The version to tag an existing schema with when executing baseline. (default: 1)
+ */
+ MigrationVersion getBaselineVersion();
+
+ /**
+ * Retrieves the description to tag an existing schema with when executing baseline.
+ *
+ * @return The description to tag an existing schema with when executing baseline. (default: << Flyway Baseline >>)
+ */
+ String getBaselineDescription();
+
+ /**
+ * Retrieves the custom MigrationResolvers to be used in addition to the built-in ones for resolving Migrations to apply.
+ *
+ * @return The custom MigrationResolvers to be used in addition to the built-in ones for resolving Migrations to apply. An empty array if none.
+ * (default: none)
+ */
+ MigrationResolver[] getResolvers();
+
+ /**
+ * Whether Flyway should skip the default resolvers. If true, only custom resolvers are used.
+ *
+ * @return Whether default built-in resolvers should be skipped. (default: false)
+ */
+ boolean isSkipDefaultResolvers();
+
+ /**
+ * Gets the callbacks for lifecycle notifications.
+ *
+ * @return The callbacks for lifecycle notifications. An empty array if none. (default: none)
+ */
+ Callback[] getCallbacks();
+
+ /**
+ * Whether Flyway should skip the default callbacks. If true, only custom callbacks are used.
+ *
+ * @return Whether default built-in callbacks should be skipped. (default: false)
+ */
+ boolean isSkipDefaultCallbacks();
+
+ /**
+ * The file name prefix for versioned SQL migrations.
+ *
Versioned SQL migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to V1.1__My_description.sql
+ *
+ * @return The file name prefix for sql migrations. (default: V)
+ */
+ String getSqlMigrationPrefix();
+
+ /**
+ * The file name prefix for undo SQL migrations.
+ *
Undo SQL migrations are responsible for undoing the effects of the versioned migration with the same version.
+ *
They have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to U1.1__My_description.sql
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @return The file name prefix for undo sql migrations. (default: U)
+ */
+ String getUndoSqlMigrationPrefix();
+
+ /**
+ * Retrieves the file name prefix for repeatable SQL migrations.
+ *
Repeatable SQL migrations have the following file name structure: prefixSeparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to R__My_description.sql
+ *
+ * @return The file name prefix for repeatable sql migrations. (default: R)
+ */
+ String getRepeatableSqlMigrationPrefix();
+
+ /**
+ * Retrieves the file name separator for sql migrations.
+ *
Sql migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to V1_1__My_description.sql
+ *
+ * @return The file name separator for sql migrations. (default: __)
+ */
+ String getSqlMigrationSeparator();
+
+ /**
+ * The file name suffixes for SQL migrations. (default: .sql)
+ *
SQL migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to V1_1__My_description.sql
+ *
Multiple suffixes (like .sql,.pkg,.pkb) can be specified for easier compatibility with other tools such as
+ * editors with specific file associations.
+ *
+ * @return The file name suffixes for SQL migrations.
+ */
+ String[] getSqlMigrationSuffixes();
+
+ /**
+ * The manually added Java-based migrations. These are not Java-based migrations discovered through classpath
+ * scanning and instantiated by Flyway. Instead these are manually added instances of JavaMigration.
+ * This is particularly useful when working with a dependency injection container, where you may want the DI
+ * container to instantiate the class and wire up its dependencies for you.
+ *
+ * @return The manually added Java-based migrations. An empty array if none. (default: none)
+ */
+ JavaMigration[] getJavaMigrations();
+
+ /**
+ * Checks whether placeholders should be replaced.
+ *
+ * @return Whether placeholders should be replaced. (default: true)
+ */
+ boolean isPlaceholderReplacement();
+
+ /**
+ * Retrieves the suffix of every placeholder.
+ *
+ * @return The suffix of every placeholder. (default: } )
+ */
+ String getPlaceholderSuffix();
+
+ /**
+ * Retrieves the prefix of every placeholder.
+ *
+ * @return The prefix of every placeholder. (default: ${ )
+ */
+ String getPlaceholderPrefix();
+
+ /**
+ * Retrieves the map of <placeholder, replacementValue> to apply to sql migration scripts.
+ *
+ * @return The map of <placeholder, replacementValue> to apply to sql migration scripts.
+ */
+ Map getPlaceholders();
+
+ /**
+ * Gets the target version up to which Flyway should consider migrations.
+ * Migrations with a higher version number will be ignored.
+ * Special values:
+ *
+ *
{@code current}: designates the current version of the schema
+ *
{@code latest}: the latest version of the schema, as defined by the migration with the highest version
+ *
+ * Defaults to {@code latest}.
+ * @return The target version up to which Flyway should consider migrations. Defaults to {@code latest}
+ */
+ MigrationVersion getTarget();
+
+ /**
+ *
Retrieves the name of the schema history table that will be used by Flyway.
By default (single-schema
+ * mode) the schema history table is placed in the default schema for the connection provided by the datasource.
+ * When the flyway.schemas property is set (multi-schema mode), the schema history table is placed in the first
+ * schema of the list.
+ *
+ * @return The name of the schema history table that will be used by Flyway. (default: flyway_schema_history)
+ */
+ String getTable();
+
+ /**
+ *
The tablespace where to create the schema history table that will be used by Flyway.
+ *
If not specified, Flyway uses the default tablespace for the database connection.
+ * This setting is only relevant for databases that do support the notion of tablespaces. Its value is simply
+ * ignored for all others.
+ *
+ * @return The tablespace where to create the schema history table that will be used by Flyway.
+ */
+ String getTablespace();
+
+ /**
+ * The default schema managed by Flyway. This schema name is case-sensitive. If not specified, but schemas
+ * is, Flyway uses the first schema in that list. If that is also not specified, Flyway uses the default schema for the
+ * database connection.
+ *
Consequences:
+ *
+ *
This schema will be the one containing the schema history table.
+ *
This schema will be the default for the database connection (provided the database supports this concept).
+ *
+ *
+ * @return The schemas managed by Flyway. (default: The first schema specified in getSchemas(), and failing that
+ * the default schema for the database connection)
+ */
+ String getDefaultSchema();
+
+ /**
+ * The schemas managed by Flyway. These schema names are case-sensitive. If not specified, Flyway uses
+ * the default schema for the database connection. If defaultSchemaName is not specified, then the first of
+ * this list also acts as default schema.
+ *
Consequences:
+ *
+ *
Flyway will automatically attempt to create all these schemas, unless they already exist.
+ *
The schemas will be cleaned in the order of this list.
+ *
If Flyway created them, the schemas themselves will be dropped when cleaning.
+ *
+ *
+ * @return The schemas managed by Flyway. (default: The default schema for the database connection)
+ */
+ String[] getSchemas();
+
+ /**
+ * Retrieves the encoding of Sql migrations.
+ *
+ * @return The encoding of Sql migrations. (default: UTF-8)
+ */
+ Charset getEncoding();
+
+ /**
+ * Retrieves the locations to scan recursively for migrations.
+ *
The location type is determined by its prefix.
+ * Unprefixed locations or locations starting with {@code classpath:} point to a package on the classpath and may
+ * contain both SQL and Java-based migrations.
+ * Locations starting with {@code filesystem:} point to a directory on the filesystem, may only
+ * contain SQL migrations and are only scanned recursively down non-hidden directories.
+ * Whether to automatically call baseline when migrate is executed against a non-empty schema with no schema history table.
+ * This schema will then be initialized with the {@code baselineVersion} before executing the migrations.
+ * Only migrations above {@code baselineVersion} will then be applied.
+ *
+ *
+ * This is useful for initial Flyway production deployments on projects with an existing DB.
+ *
+ *
+ * Be careful when enabling this as it removes the safety net that ensures
+ * Flyway does not migrate the wrong database in case of a configuration mistake!
+ *
+ *
+ * @return {@code true} if baseline should be called on migrate for non-empty schemas, {@code false} if not. (default: {@code false})
+ */
+ boolean isBaselineOnMigrate();
+
+ /**
+ * Allows migrations to be run "out of order".
+ *
If you already have versions 1 and 3 applied, and now a version 2 is found,
+ * it will be applied too instead of being ignored.
+ *
+ * @return {@code true} if outOfOrder migrations should be applied, {@code false} if not. (default: {@code false})
+ */
+ boolean isOutOfOrder();
+
+ /**
+ * Ignore missing migrations when reading the schema history table. These are migrations that were performed by an
+ * older deployment of the application that are no longer available in this version. For example: we have migrations
+ * available on the classpath with versions 1.0 and 3.0. The schema history table indicates that a migration with version 2.0
+ * (unknown to us) has also been applied. Instead of bombing out (fail fast) with an exception, a
+ * warning is logged and Flyway continues normally. This is useful for situations where one must be able to deploy
+ * a newer version of the application even though it doesn't contain migrations included with an older one anymore.
+ * Note that if the most recently applied migration is removed, Flyway has no way to know it is missing and will
+ * mark it as future instead.
+ *
+ * @return {@code true} to continue normally and log a warning, {@code false} to fail fast with an exception.
+ * (default: {@code false})
+ */
+ boolean isIgnoreMissingMigrations();
+
+ /**
+ * Ignore ignored migrations when reading the schema history table. These are migrations that were added in between
+ * already migrated migrations in this version. For example: we have migrations available on the classpath with
+ * versions from 1.0 to 3.0. The schema history table indicates that version 1 was finished on 1.0.15, and the next
+ * 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
+ * by migrate command, but by default is rejected by validate. When ignoreIgnoredMigrations is enabled, such case
+ * will not be reported by validate command. This is useful for situations where one must be able to deliver
+ * complete set of migrations in a delivery package for multiple versions of the product, and allows for further
+ * development of older versions.
+ *
+ * @return {@code true} to continue normally, {@code false} to fail fast with an exception.
+ * (default: {@code false})
+ */
+ boolean isIgnoreIgnoredMigrations();
+
+ /**
+ * Ignore pending migrations when reading the schema history table. These are migrations that are available
+ * but have not yet been applied. This can be useful for verifying that in-development migration changes
+ * don't contain any validation-breaking changes of migrations that have already been applied to a production
+ * environment, e.g. as part of a CI/CD process, without failing because of the existence of new migration versions.
+ *
+ * @return {@code true} to continue normally, {@code false} to fail fast with an exception.
+ * (default: {@code false})
+ */
+ boolean isIgnorePendingMigrations();
+
+ /**
+ * Ignore future migrations when reading the schema history table. These are migrations that were performed by a
+ * newer deployment of the application that are not yet available in this version. For example: we have migrations
+ * available on the classpath up to version 3.0. The schema history table indicates that a migration to version 4.0
+ * (unknown to us) has already been applied. Instead of bombing out (fail fast) with an exception, a
+ * warning is logged and Flyway continues normally. This is useful for situations where one must be able to redeploy
+ * an older version of the application after the database has been migrated by a newer one.
+ *
+ * @return {@code true} to continue normally and log a warning, {@code false} to fail fast with an exception.
+ * (default: {@code true})
+ */
+ boolean isIgnoreFutureMigrations();
+
+ /**
+ * Whether to validate migrations and callbacks whose scripts do not obey the correct naming convention. A failure can be
+ * useful to check that errors such as case sensitivity in migration prefixes have been corrected.
+ *
+ * @return {@code false} to continue normally, {@code true} to fail fast with an exception. (default: {@code false})
+ */
+ boolean isValidateMigrationNaming();
+
+ /**
+ * Whether to automatically call validate or not when running migrate.
+ *
+ * @return {@code true} if validate should be called. {@code false} if not. (default: {@code true})
+ */
+ boolean isValidateOnMigrate();
+
+ /**
+ * Whether to automatically call clean or not when a validation error occurs.
+ *
This is exclusively intended as a convenience for development. even though we
+ * strongly recommend not to change migration scripts once they have been checked into SCM and run, this provides a
+ * way of dealing with this case in a smooth manner. The database will be wiped clean automatically, ensuring that
+ * the next migration will bring you back to the state checked into SCM.
+ *
Warning ! Do not enable in production !
+ *
+ * @return {@code true} if clean should be called. {@code false} if not. (default: {@code false})
+ */
+ boolean isCleanOnValidationError();
+
+ /**
+ * Whether to disable clean.
+ *
This is especially useful for production environments where running clean can be quite a career limiting move.
+ *
+ * @return {@code true} to disable clean. {@code false} to leave it enabled. (default: {@code false})
+ */
+ boolean isCleanDisabled();
+
+ /**
+ * Whether to allow mixing transactional and non-transactional statements within the same migration. Enabling this
+ * automatically causes the entire affected migration to be run without a transaction.
+ *
+ *
Note that this is only applicable for PostgreSQL, Aurora PostgreSQL, SQL Server and SQLite which all have
+ * statements that do not run at all within a transaction.
+ *
This is not to be confused with implicit transaction, as they occur in MySQL or Oracle, where even though a
+ * DDL statement was run within a transaction, the database will issue an implicit commit before and after
+ * its execution.
+ *
+ * @return {@code true} if mixed migrations should be allowed. {@code false} if an error should be thrown instead. (default: {@code false})
+ */
+ boolean isMixed();
+
+ /**
+ * Whether to group all pending migrations together in the same transaction when applying them (only recommended for databases with support for DDL transactions).
+ *
+ * @return {@code true} if migrations should be grouped. {@code false} if they should be applied individually instead. (default: {@code false})
+ */
+ boolean isGroup();
+
+ /**
+ * The username that will be recorded in the schema history table as having applied the migration.
+ *
+ * @return The username or {@code null} for the current database user of the connection. (default: {@code null}).
+ */
+ String getInstalledBy();
+
+ /**
+ * Rules for the built-in error handler that let you override specific SQL states and errors codes in order to force
+ * specific errors or warnings to be treated as debug messages, info messages, warnings or errors.
+ *
Each error override has the following format: {@code STATE:12345:W}.
+ * It is a 5 character SQL state (or * to match all SQL states), a colon,
+ * the SQL error code (or * to match all SQL error codes), a colon and finally
+ * the desired behavior that should override the initial one.
+ *
The following behaviors are accepted:
+ *
+ *
{@code D} to force a debug message
+ *
{@code D-} to force a debug message, but do not show the original sql state and error code
+ *
{@code I} to force an info message
+ *
{@code I-} to force an info message, but do not show the original sql state and error code
+ *
{@code W} to force a warning
+ *
{@code W-} to force a warning, but do not show the original sql state and error code
+ *
{@code E} to force an error
+ *
{@code E-} to force an error, but do not show the original sql state and error code
+ *
+ *
Example 1: to force Oracle stored procedure compilation issues to produce
+ * errors instead of warnings, the following errorOverride can be used: {@code 99999:17110:E}
+ *
Example 2: to force SQL Server PRINT messages to be displayed as info messages (without SQL state and error
+ * code details) instead of warnings, the following errorOverride can be used: {@code S0001:0:I-}
+ *
Example 3: to force all errors with SQL error code 123 to be treated as warnings instead,
+ * the following errorOverride can be used: {@code *:123:W}
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @return The ErrorOverrides or an empty array if none are defined. (default: none)
+ */
+ String[] getErrorOverrides();
+
+ /**
+ * The stream where to output the SQL statements of a migration dry run. {@code null} if the SQL statements
+ * are executed against the database directly.
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @return The stream or {@code null} if the SQL statements are executed against the database directly.
+ */
+ OutputStream getDryRunOutput();
+
+ /**
+ * Whether to stream SQL migrations when executing them. Streaming doesn't load the entire migration in memory at
+ * once. Instead each statement is loaded individually. This is particularly useful for very large SQL migrations
+ * composed of multiple MB or even GB of reference data, as this dramatically reduces Flyway's memory consumption.
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @return {@code true} to stream SQL migrations. {@code false} to fully loaded them in memory instead. (default: {@code false})
+ */
+ boolean isStream();
+
+ /**
+ * Whether to batch SQL statements when executing them. Batching can save up to 99 percent of network roundtrips by
+ * sending up to 100 statements at once over the network to the database, instead of sending each statement
+ * individually. This is particularly useful for very large SQL migrations composed of multiple MB or even GB of
+ * reference data, as this can dramatically reduce the network overhead. This is supported for INSERT, UPDATE,
+ * DELETE, MERGE and UPSERT statements. All other statements are automatically executed without batching.
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @return {@code true} to batch SQL statements. {@code false} to execute them individually instead. (default: {@code false})
+ */
+ boolean isBatch();
+
+ /**
+ * Whether to Flyway's support for Oracle SQL*Plus commands should be activated.
+ *
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @return {@code true} to active SQL*Plus support. {@code false} to fail fast instead. (default: {@code false})
+ */
+ boolean isOracleSqlplus();
+
+ /**
+ * Whether Flyway should issue a warning instead of an error whenever it encounters an Oracle SQL*Plus statement
+ * it doesn't yet support.
+ *
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @return {@code true} to issue a warning. {@code false} to fail fast instead. (default: {@code false})
+ */
+ boolean isOracleSqlplusWarn();
+
+ /**
+ * Your Flyway license key (FL01...). Not yet a Flyway Pro or Enterprise Edition customer?
+ * Request your Flyway trial license key
+ * to try out Flyway Pro and Enterprise Edition features free for 30 days.
+ *
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @return Your Flyway license key.
+ */
+ String getLicenseKey();
+
+ /**
+ * Whether Flyway should output a table with the results of queries when executing migrations.
+ *
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @return {@code true} to output the results table (default: {@code true})
+ */
+ boolean outputQueryResults();
+
+ /**
+ * Retrieves the custom ResourceProvider to be used to look up resources. If not set, the default strategy will be used.
+ *
+ * @return The custom ResourceProvider to be used to look up resources
+ * (default: null)
+ */
+ ResourceProvider getResourceProvider();
+
+ /**
+ * Retrieves the custom ClassProvider to be used to look up {@link JavaMigration} classes. If not set, the default strategy will be used.
+ *
+ * @return The custom ClassProvider to be used to look up {@link JavaMigration} classes
+ * (default: null)
+ */
+ ClassProvider getJavaMigrationClassProvider();
+
+ /**
+ * Whether Flyway should attempt to create the schemas specified in the schemas property
+ *
+ * @return @{code true} to attempt to create the schemas (default: {@code true})
+ */
+ boolean getCreateSchemas();
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/configuration/FluentConfiguration.java a/flyway-core/src/main/java/org/flywaydb/core/api/configuration/FluentConfiguration.java
new file mode 100644
index 0000000..3c1758c
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/configuration/FluentConfiguration.java
@@ -0,0 +1,1146 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.configuration;
+
+import org.flywaydb.core.Flyway;
+import org.flywaydb.core.api.FlywayException;
+import org.flywaydb.core.api.Location;
+import org.flywaydb.core.api.MigrationVersion;
+import org.flywaydb.core.api.callback.Callback;
+import org.flywaydb.core.api.migration.JavaMigration;
+import org.flywaydb.core.api.resolver.MigrationResolver;
+import org.flywaydb.core.api.ClassProvider;
+import org.flywaydb.core.internal.configuration.ConfigUtils;
+import org.flywaydb.core.api.ResourceProvider;
+import org.flywaydb.core.internal.util.ClassUtils;
+
+import javax.sql.DataSource;
+import java.io.File;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Fluent configuration for Flyway. This is the preferred means of configuring the Flyway API.
+ *
+ * This configuration can be passed to Flyway using the new Flyway(Configuration) constructor.
+ *
+ */
+public class FluentConfiguration implements Configuration {
+ private final ClassicConfiguration config;
+
+ /**
+ * Creates a new default configuration.
+ */
+ public FluentConfiguration() {
+ config = new ClassicConfiguration();
+ }
+
+ /**
+ * Creates a new default configuration with this class loader.
+ *
+ * @param classLoader The ClassLoader to use for loading migrations, resolvers, etc from the classpath. (default: Thread.currentThread().getContextClassLoader() )
+ */
+ public FluentConfiguration(ClassLoader classLoader) {
+ config = new ClassicConfiguration(classLoader);
+ }
+
+ /**
+ * Loads this configuration into a new Flyway instance.
+ *
+ * @return The new fully-configured Flyway instance.
+ */
+ public Flyway load() {
+ return new Flyway(this);
+ }
+
+ /**
+ * Configure with the same values as this existing configuration.
+ *
+ * @param configuration The configuration to use.
+ */
+ public FluentConfiguration configuration(Configuration configuration) {
+ config.configure(configuration);
+ return this;
+ }
+
+ @Override
+ public Location[] getLocations() {
+ return config.getLocations();
+ }
+
+ @Override
+ public Charset getEncoding() {
+ return config.getEncoding();
+ }
+
+ @Override
+ public String getDefaultSchema() { return config.getDefaultSchema(); }
+
+ @Override
+ public String[] getSchemas() { return config.getSchemas(); }
+
+ @Override
+ public String getTable() {
+ return config.getTable();
+ }
+
+ @Override
+ public String getTablespace() {
+ return config.getTablespace();
+ }
+
+ @Override
+ public MigrationVersion getTarget() {
+ return config.getTarget();
+ }
+
+ @Override
+ public boolean isPlaceholderReplacement() {
+ return config.isPlaceholderReplacement();
+ }
+
+ @Override
+ public Map getPlaceholders() {
+ return config.getPlaceholders();
+ }
+
+ @Override
+ public String getPlaceholderPrefix() {
+ return config.getPlaceholderPrefix();
+ }
+
+ @Override
+ public String getPlaceholderSuffix() {
+ return config.getPlaceholderSuffix();
+ }
+
+ @Override
+ public String getSqlMigrationPrefix() {
+ return config.getSqlMigrationPrefix();
+ }
+
+ @Override
+ public String getRepeatableSqlMigrationPrefix() {
+ return config.getRepeatableSqlMigrationPrefix();
+ }
+
+ @Override
+ public String getSqlMigrationSeparator() {
+ return config.getSqlMigrationSeparator();
+ }
+
+ @Override
+ public String[] getSqlMigrationSuffixes() {
+ return config.getSqlMigrationSuffixes();
+ }
+
+ @Override
+ public JavaMigration[] getJavaMigrations() {
+ return config.getJavaMigrations();
+ }
+
+ @Override
+ public boolean isIgnoreMissingMigrations() {
+ return config.isIgnoreMissingMigrations();
+ }
+
+ @Override
+ public boolean isIgnoreIgnoredMigrations() {
+ return config.isIgnoreIgnoredMigrations();
+ }
+
+ @Override
+ public boolean isIgnorePendingMigrations() {
+ return config.isIgnorePendingMigrations();
+ }
+
+ @Override
+ public boolean isIgnoreFutureMigrations() {
+ return config.isIgnoreFutureMigrations();
+ }
+
+ @Override
+ public boolean isValidateMigrationNaming() { return config.isValidateMigrationNaming(); }
+
+ @Override
+ public boolean isValidateOnMigrate() {
+ return config.isValidateOnMigrate();
+ }
+
+ @Override
+ public boolean isCleanOnValidationError() {
+ return config.isCleanOnValidationError();
+ }
+
+ @Override
+ public boolean isCleanDisabled() {
+ return config.isCleanDisabled();
+ }
+
+ @Override
+ public MigrationVersion getBaselineVersion() {
+ return config.getBaselineVersion();
+ }
+
+ @Override
+ public String getBaselineDescription() {
+ return config.getBaselineDescription();
+ }
+
+ @Override
+ public boolean isBaselineOnMigrate() {
+ return config.isBaselineOnMigrate();
+ }
+
+ @Override
+ public boolean isOutOfOrder() {
+ return config.isOutOfOrder();
+ }
+
+ @Override
+ public MigrationResolver[] getResolvers() {
+ return config.getResolvers();
+ }
+
+ @Override
+ public boolean isSkipDefaultResolvers() {
+ return config.isSkipDefaultResolvers();
+ }
+
+ @Override
+ public DataSource getDataSource() {
+ return config.getDataSource();
+ }
+
+ @Override
+ public int getConnectRetries() {
+ return config.getConnectRetries();
+ }
+
+ @Override
+ public String getInitSql() {
+ return config.getInitSql();
+ }
+
+ @Override
+ public ClassLoader getClassLoader() {
+ return config.getClassLoader();
+ }
+
+ @Override
+ public boolean isMixed() {
+ return config.isMixed();
+ }
+
+ @Override
+ public String getInstalledBy() {
+ return config.getInstalledBy();
+ }
+
+ @Override
+ public boolean isGroup() {
+ return config.isGroup();
+ }
+
+ @Override
+ public String[] getErrorOverrides() {
+ return config.getErrorOverrides();
+ }
+
+ @Override
+ public OutputStream getDryRunOutput() {
+ return config.getDryRunOutput();
+ }
+
+ @Override
+ public boolean isStream() {
+ return config.isStream();
+ }
+
+ @Override
+ public boolean isBatch() {
+ return config.isBatch();
+ }
+
+ @Override
+ public boolean isOracleSqlplus() {
+ return config.isOracleSqlplus();
+ }
+
+ @Override
+ public boolean isOracleSqlplusWarn() {
+ return config.isOracleSqlplusWarn();
+ }
+
+ @Override
+ public String getLicenseKey() {
+ return config.getLicenseKey();
+ }
+
+ @Override
+ public ResourceProvider getResourceProvider() {
+ return config.getResourceProvider();
+ }
+
+ @Override
+ public ClassProvider getJavaMigrationClassProvider() {
+ return config.getJavaMigrationClassProvider();
+ }
+
+ @Override
+ public boolean outputQueryResults() {
+ return config.outputQueryResults();
+ }
+
+ @Override
+ public boolean getCreateSchemas() {
+ return config.getCreateSchemas();
+ }
+
+ /**
+ * Sets the stream where to output the SQL statements of a migration dry run. {@code null} to execute the SQL statements
+ * directly against the database. The stream when be closing when Flyway finishes writing the output.
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param dryRunOutput The output file or {@code null} to execute the SQL statements directly against the database.
+ */
+ public FluentConfiguration dryRunOutput(OutputStream dryRunOutput) {
+ config.setDryRunOutput(dryRunOutput);
+ return this;
+ }
+
+ /**
+ * Sets the file where to output the SQL statements of a migration dry run. {@code null} to execute the SQL statements
+ * directly against the database. If the file specified is in a non-existent directory, Flyway will create all
+ * directories and parent directories as needed.
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param dryRunOutput The output file or {@code null} to execute the SQL statements directly against the database.
+ */
+ public FluentConfiguration dryRunOutput(File dryRunOutput) {
+ config.setDryRunOutputAsFile(dryRunOutput);
+ return this;
+ }
+
+ /**
+ * Sets the file where to output the SQL statements of a migration dry run. {@code null} to execute the SQL statements
+ * directly against the database. If the file specified is in a non-existent directory, Flyway will create all
+ * directories and parent directories as needed.
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param dryRunOutputFileName The name of the output file or {@code null} to execute the SQL statements directly
+ * against the database.
+ */
+ public FluentConfiguration dryRunOutput(String dryRunOutputFileName) {
+ config.setDryRunOutputAsFileName(dryRunOutputFileName);
+ return this;
+ }
+
+ /**
+ * Rules for the built-in error handler that let you override specific SQL states and errors codes in order to force
+ * specific errors or warnings to be treated as debug messages, info messages, warnings or errors.
+ *
Each error override has the following format: {@code STATE:12345:W}.
+ * It is a 5 character SQL state (or * to match all SQL states), a colon,
+ * the SQL error code (or * to match all SQL error codes), a colon and finally
+ * the desired behavior that should override the initial one.
+ *
The following behaviors are accepted:
+ *
+ *
{@code D} to force a debug message
+ *
{@code D-} to force a debug message, but do not show the original sql state and error code
+ *
{@code I} to force an info message
+ *
{@code I-} to force an info message, but do not show the original sql state and error code
+ *
{@code W} to force a warning
+ *
{@code W-} to force a warning, but do not show the original sql state and error code
+ *
{@code E} to force an error
+ *
{@code E-} to force an error, but do not show the original sql state and error code
+ *
+ *
Example 1: to force Oracle stored procedure compilation issues to produce
+ * errors instead of warnings, the following errorOverride can be used: {@code 99999:17110:E}
+ *
Example 2: to force SQL Server PRINT messages to be displayed as info messages (without SQL state and error
+ * code details) instead of warnings, the following errorOverride can be used: {@code S0001:0:I-}
+ *
Example 3: to force all errors with SQL error code 123 to be treated as warnings instead,
+ * the following errorOverride can be used: {@code *:123:W}
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param errorOverrides The ErrorOverrides or an empty array if none are defined. (default: none)
+ */
+ public FluentConfiguration errorOverrides(String... errorOverrides) {
+ config.setErrorOverrides(errorOverrides);
+ return this;
+ }
+
+ /**
+ * Whether to group all pending migrations together in the same transaction when applying them (only recommended for databases with support for DDL transactions).
+ *
+ * @param group {@code true} if migrations should be grouped. {@code false} if they should be applied individually instead. (default: {@code false})
+ */
+ public FluentConfiguration group(boolean group) {
+ config.setGroup(group);
+ return this;
+ }
+
+ /**
+ * The username that will be recorded in the schema history table as having applied the migration.
+ *
+ * @param installedBy The username or {@code null} for the current database user of the connection. (default: {@code null}).
+ */
+ public FluentConfiguration installedBy(String installedBy) {
+ config.setInstalledBy(installedBy);
+ return this;
+ }
+
+ /**
+ * Whether to allow mixing transactional and non-transactional statements within the same migration. Enabling this
+ * automatically causes the entire affected migration to be run without a transaction.
+ *
+ *
Note that this is only applicable for PostgreSQL, Aurora PostgreSQL, SQL Server and SQLite which all have
+ * statements that do not run at all within a transaction.
+ *
This is not to be confused with implicit transaction, as they occur in MySQL or Oracle, where even though a
+ * DDL statement was run within a transaction, the database will issue an implicit commit before and after
+ * its execution.
+ *
+ * @param mixed {@code true} if mixed migrations should be allowed. {@code false} if an error should be thrown instead. (default: {@code false})
+ */
+ public FluentConfiguration mixed(boolean mixed) {
+ config.setMixed(mixed);
+ return this;
+ }
+
+ /**
+ * Ignore missing migrations when reading the schema history table. These are migrations that were performed by an
+ * older deployment of the application that are no longer available in this version. For example: we have migrations
+ * available on the classpath with versions 1.0 and 3.0. The schema history table indicates that a migration with version 2.0
+ * (unknown to us) has also been applied. Instead of bombing out (fail fast) with an exception, a
+ * warning is logged and Flyway continues normally. This is useful for situations where one must be able to deploy
+ * a newer version of the application even though it doesn't contain migrations included with an older one anymore.
+ * Note that if the most recently applied migration is removed, Flyway has no way to know it is missing and will
+ * mark it as future instead.
+ *
+ * @param ignoreMissingMigrations {@code true} to continue normally and log a warning, {@code false} to fail fast with an exception.
+ * (default: {@code false})
+ */
+ public FluentConfiguration ignoreMissingMigrations(boolean ignoreMissingMigrations) {
+ config.setIgnoreMissingMigrations(ignoreMissingMigrations);
+ return this;
+ }
+
+ /**
+ * Ignore ignored migrations when reading the schema history table. These are migrations that were added in between
+ * already migrated migrations in this version. For example: we have migrations available on the classpath with
+ * versions from 1.0 to 3.0. The schema history table indicates that version 1 was finished on 1.0.15, and the next
+ * 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
+ * by migrate command, but by default is rejected by validate. When ignoreIgnoredMigrations is enabled, such case
+ * will not be reported by validate command. This is useful for situations where one must be able to deliver
+ * complete set of migrations in a delivery package for multiple versions of the product, and allows for further
+ * development of older versions.
+ *
+ * @param ignoreIgnoredMigrations {@code true} to continue normally, {@code false} to fail fast with an exception.
+ * (default: {@code false})
+ */
+ public FluentConfiguration ignoreIgnoredMigrations(boolean ignoreIgnoredMigrations) {
+ config.setIgnoreIgnoredMigrations(ignoreIgnoredMigrations);
+ return this;
+ }
+
+ /**
+ * Ignore pending migrations when reading the schema history table. These are migrations that are available
+ * but have not yet been applied. This can be useful for verifying that in-development migration changes
+ * don't contain any validation-breaking changes of migrations that have already been applied to a production
+ * environment, e.g. as part of a CI/CD process, without failing because of the existence of new migration versions.
+ *
+ * @param ignorePendingMigrations {@code true} to continue normally, {@code false} to fail fast with an exception.
+ * (default: {@code false})
+ */
+ public FluentConfiguration ignorePendingMigrations(boolean ignorePendingMigrations) {
+ config.setIgnorePendingMigrations(ignorePendingMigrations);
+ return this;
+ }
+
+ /**
+ * Whether to ignore future migrations when reading the schema history table. These are migrations that were performed by a
+ * newer deployment of the application that are not yet available in this version. For example: we have migrations
+ * available on the classpath up to version 3.0. The schema history table indicates that a migration to version 4.0
+ * (unknown to us) has already been applied. Instead of bombing out (fail fast) with an exception, a
+ * warning is logged and Flyway continues normally. This is useful for situations where one must be able to redeploy
+ * an older version of the application after the database has been migrated by a newer one.
+ *
+ * @param ignoreFutureMigrations {@code true} to continue normally and log a warning, {@code false} to fail
+ * fast with an exception. (default: {@code true})
+ */
+ public FluentConfiguration ignoreFutureMigrations(boolean ignoreFutureMigrations) {
+ config.setIgnoreFutureMigrations(ignoreFutureMigrations);
+ return this;
+ }
+
+ /**
+ * Whether to validate migrations and callbacks whose scripts do not obey the correct naming convention. A failure can be
+ * useful to check that errors such as case sensitivity in migration prefixes have been corrected.
+ *
+ * @param validateMigrationNaming {@code false} to continue normally, {@code true} to fail
+ * fast with an exception. (default: {@code false})
+ */
+ public FluentConfiguration validateMigrationNaming(boolean validateMigrationNaming){
+ config.setValidateMigrationNaming(validateMigrationNaming);
+ return this;
+ }
+
+ /**
+ * Whether to automatically call validate or not when running migrate.
+ *
+ * @param validateOnMigrate {@code true} if validate should be called. {@code false} if not. (default: {@code true})
+ */
+ public FluentConfiguration validateOnMigrate(boolean validateOnMigrate) {
+ config.setValidateOnMigrate(validateOnMigrate);
+ return this;
+ }
+
+ /**
+ * Whether to automatically call clean or not when a validation error occurs.
+ *
This is exclusively intended as a convenience for development. even though we
+ * strongly recommend not to change migration scripts once they have been checked into SCM and run, this provides a
+ * way of dealing with this case in a smooth manner. The database will be wiped clean automatically, ensuring that
+ * the next migration will bring you back to the state checked into SCM.
+ *
Warning ! Do not enable in production !
+ *
+ * @param cleanOnValidationError {@code true} if clean should be called. {@code false} if not. (default: {@code false})
+ */
+ public FluentConfiguration cleanOnValidationError(boolean cleanOnValidationError) {
+ config.setCleanOnValidationError(cleanOnValidationError);
+ return this;
+ }
+
+ /**
+ * Whether to disable clean.
+ *
This is especially useful for production environments where running clean can be quite a career limiting move.
+ *
+ * @param cleanDisabled {@code true} to disable clean. {@code false} to leave it enabled. (default: {@code false})
+ */
+ public FluentConfiguration cleanDisabled(boolean cleanDisabled) {
+ config.setCleanDisabled(cleanDisabled);
+ return this;
+ }
+
+ /**
+ * Sets the locations to scan recursively for migrations.
+ *
The location type is determined by its prefix.
+ * Unprefixed locations or locations starting with {@code classpath:} point to a package on the classpath and may
+ * contain both SQL and Java-based migrations.
+ * Locations starting with {@code filesystem:} point to a directory on the filesystem, may only
+ * contain SQL migrations and are only scanned recursively down non-hidden directories.
+ *
+ * @param locations Locations to scan recursively for migrations. (default: db/migration)
+ */
+ public FluentConfiguration locations(String... locations) {
+ config.setLocationsAsStrings(locations);
+ return this;
+ }
+
+ /**
+ * Sets the locations to scan recursively for migrations.
+ *
The location type is determined by its prefix.
+ * Unprefixed locations or locations starting with {@code classpath:} point to a package on the classpath and may
+ * contain both SQL and Java-based migrations.
+ * Locations starting with {@code filesystem:} point to a directory on the filesystem, may only
+ * contain SQL migrations and are only scanned recursively down non-hidden directories.
+ *
+ * @param locations Locations to scan recursively for migrations. (default: db/migration)
+ */
+ public FluentConfiguration locations(Location... locations) {
+ config.setLocations(locations);
+ return this;
+ }
+
+ /**
+ * Sets the encoding of Sql migrations.
+ *
+ * @param encoding The encoding of Sql migrations. (default: UTF-8)
+ */
+ public FluentConfiguration encoding(String encoding) {
+ config.setEncodingAsString(encoding);
+ return this;
+ }
+
+ /**
+ * Sets the encoding of Sql migrations.
+ *
+ * @param encoding The encoding of Sql migrations. (default: UTF-8)
+ */
+ public FluentConfiguration encoding(Charset encoding) {
+ config.setEncoding(encoding);
+ return this;
+ }
+
+ /**
+ * Sets the default schema managed by Flyway. This schema name is case-sensitive. If not specified, but
+ * schemas is, Flyway uses the first schema in that list. If that is also not specified, Flyway uses the default
+ * schema for the database connection.
+ *
Consequences:
+ *
+ *
This schema will be the one containing the schema history table.
+ *
This schema will be the default for the database connection (provided the database supports this concept).
+ *
+ *
+ * @param schema The default schema managed by Flyway.
+ */
+ public FluentConfiguration defaultSchema(String schema) {
+ config.setDefaultSchema(schema);
+ return this;
+ }
+
+ /**
+ * Sets the schemas managed by Flyway. These schema names are case-sensitive. If not specified, Flyway uses
+ * the default schema for the database connection. If defaultSchemaName is not specified, then the first of
+ * this list also acts as default schema.
+ *
Consequences:
+ *
+ *
Flyway will automatically attempt to create all these schemas, unless they already exist.
+ *
The schemas will be cleaned in the order of this list.
+ *
If Flyway created them, the schemas themselves will be dropped when cleaning.
+ *
+ *
+ * @param schemas The schemas managed by Flyway. May not be {@code null}. Must contain at least one element.
+ */
+ public FluentConfiguration schemas(String... schemas) {
+ config.setSchemas(schemas);
+ return this;
+ }
+
+ /**
+ *
Sets the name of the schema history table that will be used by Flyway.
By default (single-schema mode)
+ * the schema history table is placed in the default schema for the connection provided by the datasource.
When
+ * the flyway.schemas property is set (multi-schema mode), the schema history table is placed in the first schema
+ * of the list.
+ *
+ * @param table The name of the schema history table that will be used by Flyway. (default: flyway_schema_history)
+ */
+ public FluentConfiguration table(String table) {
+ config.setTable(table);
+ return this;
+ }
+
+ /**
+ *
Sets the tablespace where to create the schema history table that will be used by Flyway.
+ *
If not specified, Flyway uses the default tablespace for the database connection.
+ * This setting is only relevant for databases that do support the notion of tablespaces. Its value is simply
+ * ignored for all others.
+ *
+ * @param tablespace The tablespace where to create the schema history table that will be used by Flyway.
+ */
+ public FluentConfiguration tablespace(String tablespace) {
+ config.setTablespace(tablespace);
+ return this;
+ }
+
+ /**
+ * Sets the target version up to which Flyway should consider migrations.
+ * Migrations with a higher version number will be ignored.
+ * Special values:
+ *
+ *
{@code current}: designates the current version of the schema
+ *
{@code latest}: the latest version of the schema, as defined by the migration with the highest version
+ *
+ * Defaults to {@code latest}.
+ */
+ public FluentConfiguration target(MigrationVersion target) {
+ config.setTarget(target);
+ return this;
+ }
+
+ /**
+ * Sets the target version up to which Flyway should consider migrations.
+ * Migrations with a higher version number will be ignored.
+ * Special values:
+ *
+ *
{@code current}: designates the current version of the schema
+ *
{@code latest}: the latest version of the schema, as defined by the migration with the highest version
+ *
+ * Defaults to {@code latest}.
+ */
+ public FluentConfiguration target(String target) {
+ config.setTargetAsString(target);
+ return this;
+ }
+
+ /**
+ * Sets whether placeholders should be replaced.
+ *
+ * @param placeholderReplacement Whether placeholders should be replaced. (default: true)
+ */
+ public FluentConfiguration placeholderReplacement(boolean placeholderReplacement) {
+ config.setPlaceholderReplacement(placeholderReplacement);
+ return this;
+ }
+
+ /**
+ * Sets the placeholders to replace in sql migration scripts.
+ *
+ * @param placeholders The map of <placeholder, replacementValue> to apply to sql migration scripts.
+ */
+ public FluentConfiguration placeholders(Map placeholders) {
+ config.setPlaceholders(placeholders);
+ return this;
+ }
+
+ /**
+ * Sets the prefix of every placeholder.
+ *
+ * @param placeholderPrefix The prefix of every placeholder. (default: ${ )
+ */
+ public FluentConfiguration placeholderPrefix(String placeholderPrefix) {
+ config.setPlaceholderPrefix(placeholderPrefix);
+ return this;
+ }
+
+ /**
+ * Sets the suffix of every placeholder.
+ *
+ * @param placeholderSuffix The suffix of every placeholder. (default: } )
+ */
+ public FluentConfiguration placeholderSuffix(String placeholderSuffix) {
+ config.setPlaceholderSuffix(placeholderSuffix);
+ return this;
+ }
+
+ /**
+ * Sets the file name prefix for sql migrations.
+ *
Sql migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to V1_1__My_description.sql
+ *
+ * @param sqlMigrationPrefix The file name prefix for sql migrations (default: V)
+ */
+ public FluentConfiguration sqlMigrationPrefix(String sqlMigrationPrefix) {
+ config.setSqlMigrationPrefix(sqlMigrationPrefix);
+ return this;
+ }
+
+ @Override
+ public String getUndoSqlMigrationPrefix() {
+ return config.getUndoSqlMigrationPrefix();
+ }
+
+ /**
+ * Sets the file name prefix for undo SQL migrations. (default: U)
+ *
Undo SQL migrations are responsible for undoing the effects of the versioned migration with the same version.
+ *
They have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to U1.1__My_description.sql
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param undoSqlMigrationPrefix The file name prefix for undo SQL migrations. (default: U)
+ */
+ public FluentConfiguration undoSqlMigrationPrefix(String undoSqlMigrationPrefix) {
+ config.setUndoSqlMigrationPrefix(undoSqlMigrationPrefix);
+ return this;
+ }
+
+ /**
+ * Sets the file name prefix for repeatable sql migrations.
+ *
Repeatable sql migrations have the following file name structure: prefixSeparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to R__My_description.sql
+ *
+ * @param repeatableSqlMigrationPrefix The file name prefix for repeatable sql migrations (default: R)
+ */
+ public FluentConfiguration repeatableSqlMigrationPrefix(String repeatableSqlMigrationPrefix) {
+ config.setRepeatableSqlMigrationPrefix(repeatableSqlMigrationPrefix);
+ return this;
+ }
+
+ /**
+ * Sets the file name separator for sql migrations.
+ *
Sql migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to V1_1__My_description.sql
+ *
+ * @param sqlMigrationSeparator The file name separator for sql migrations (default: __)
+ */
+ public FluentConfiguration sqlMigrationSeparator(String sqlMigrationSeparator) {
+ config.setSqlMigrationSeparator(sqlMigrationSeparator);
+ return this;
+ }
+
+ /**
+ * The file name suffixes for SQL migrations. (default: .sql)
+ *
SQL migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix ,
+ * which using the defaults translates to V1_1__My_description.sql
+ *
Multiple suffixes (like .sql,.pkg,.pkb) can be specified for easier compatibility with other tools such as
+ * editors with specific file associations.
+ *
+ * @param sqlMigrationSuffixes The file name suffixes for SQL migrations.
+ */
+ public FluentConfiguration sqlMigrationSuffixes(String... sqlMigrationSuffixes) {
+ config.setSqlMigrationSuffixes(sqlMigrationSuffixes);
+ return this;
+ }
+
+ /**
+ * The manually added Java-based migrations. These are not Java-based migrations discovered through classpath
+ * scanning and instantiated by Flyway. Instead these are manually added instances of JavaMigration.
+ * This is particularly useful when working with a dependency injection container, where you may want the DI
+ * container to instantiate the class and wire up its dependencies for you.
+ *
+ * @param javaMigrations The manually added Java-based migrations. An empty array if none. (default: none)
+ */
+ public FluentConfiguration javaMigrations(JavaMigration... javaMigrations) {
+ config.setJavaMigrations(javaMigrations);
+ return this;
+ }
+
+ /**
+ * Sets the datasource to use. Must have the necessary privileges to execute ddl.
+ *
+ * @param dataSource The datasource to use. Must have the necessary privileges to execute ddl.
+ */
+ public FluentConfiguration dataSource(DataSource dataSource) {
+ config.setDataSource(dataSource);
+ return this;
+ }
+
+ /**
+ * Sets the datasource to use. Must have the necessary privileges to execute ddl.
+ *
+ * @param url The JDBC URL of the database.
+ * @param user The user of the database.
+ * @param password The password of the database.
+ */
+ public FluentConfiguration dataSource(String url, String user, String password) {
+ config.setDataSource(url, user, password);
+ return this;
+ }
+
+ /**
+ * The maximum number of retries when attempting to connect to the database. After each failed attempt, Flyway will
+ * wait 1 second before attempting to connect again, up to the maximum number of times specified by connectRetries.
+ *
+ * @param connectRetries The maximum number of retries (default: 0).
+ */
+ public FluentConfiguration connectRetries(int connectRetries) {
+ config.setConnectRetries(connectRetries);
+ return this;
+ }
+
+ /**
+ * The SQL statements to run to initialize a new database connection immediately after opening it.
+ *
+ * @param initSql The SQL statements. (default: {@code null})
+ */
+ public FluentConfiguration initSql(String initSql) {
+ config.setInitSql(initSql);
+ return this;
+ }
+
+ /**
+ * Sets the version to tag an existing schema with when executing baseline.
+ *
+ * @param baselineVersion The version to tag an existing schema with when executing baseline. (default: 1)
+ */
+ public FluentConfiguration baselineVersion(MigrationVersion baselineVersion) {
+ config.setBaselineVersion(baselineVersion);
+ return this;
+ }
+
+ /**
+ * Sets the version to tag an existing schema with when executing baseline.
+ *
+ * @param baselineVersion The version to tag an existing schema with when executing baseline. (default: 1)
+ */
+ public FluentConfiguration baselineVersion(String baselineVersion) {
+ config.setBaselineVersion(MigrationVersion.fromVersion(baselineVersion));
+ return this;
+ }
+
+ /**
+ * Sets the description to tag an existing schema with when executing baseline.
+ *
+ * @param baselineDescription The description to tag an existing schema with when executing baseline. (default: << Flyway Baseline >>)
+ */
+ public FluentConfiguration baselineDescription(String baselineDescription) {
+ config.setBaselineDescription(baselineDescription);
+ return this;
+ }
+
+ /**
+ *
+ * Whether to automatically call baseline when migrate is executed against a non-empty schema with no schema history table.
+ * This schema will then be baselined with the {@code baselineVersion} before executing the migrations.
+ * Only migrations above {@code baselineVersion} will then be applied.
+ *
+ *
+ * This is useful for initial Flyway production deployments on projects with an existing DB.
+ *
+ *
+ * Be careful when enabling this as it removes the safety net that ensures
+ * Flyway does not migrate the wrong database in case of a configuration mistake!
+ *
+ *
+ * @param baselineOnMigrate {@code true} if baseline should be called on migrate for non-empty schemas, {@code false} if not. (default: {@code false})
+ */
+ public FluentConfiguration baselineOnMigrate(boolean baselineOnMigrate) {
+ config.setBaselineOnMigrate(baselineOnMigrate);
+ return this;
+ }
+
+ /**
+ * Allows migrations to be run "out of order".
+ *
If you already have versions 1 and 3 applied, and now a version 2 is found,
+ * it will be applied too instead of being ignored.
+ *
+ * @param outOfOrder {@code true} if outOfOrder migrations should be applied, {@code false} if not. (default: {@code false})
+ */
+ public FluentConfiguration outOfOrder(boolean outOfOrder) {
+ config.setOutOfOrder(outOfOrder);
+ return this;
+ }
+
+ /**
+ * Gets the callbacks for lifecycle notifications.
+ *
+ * @return The callbacks for lifecycle notifications. An empty array if none. (default: none)
+ */
+ @Override
+ public Callback[] getCallbacks() {
+ return config.getCallbacks();
+ }
+
+ @Override
+ public boolean isSkipDefaultCallbacks() {
+ return config.isSkipDefaultCallbacks();
+ }
+
+ /**
+ * Set the callbacks for lifecycle notifications.
+ *
+ * @param callbacks The callbacks for lifecycle notifications. (default: none)
+ */
+ public FluentConfiguration callbacks(Callback... callbacks) {
+ config.setCallbacks(callbacks);
+ return this;
+ }
+
+ /**
+ * Set the callbacks for lifecycle notifications.
+ *
+ * @param callbacks The fully qualified class names of the callbacks for lifecycle notifications. (default: none)
+ */
+ public FluentConfiguration callbacks(String... callbacks) {
+ config.setCallbacksAsClassNames(callbacks);
+ return this;
+ }
+
+ /**
+ * Whether Flyway should skip the default callbacks. If true, only custom callbacks are used.
+ *
+ * @param skipDefaultCallbacks Whether default built-in callbacks should be skipped.
(default: false)
+ */
+ public FluentConfiguration skipDefaultCallbacks(boolean skipDefaultCallbacks) {
+ config.setSkipDefaultCallbacks(skipDefaultCallbacks);
+ return this;
+ }
+
+ /**
+ * Sets custom MigrationResolvers to be used in addition to the built-in ones for resolving Migrations to apply.
+ *
+ * @param resolvers The custom MigrationResolvers to be used in addition to the built-in ones for resolving Migrations to apply. (default: empty list)
+ */
+ public FluentConfiguration resolvers(MigrationResolver... resolvers) {
+ config.setResolvers(resolvers);
+ return this;
+ }
+
+ /**
+ * Sets custom MigrationResolvers to be used in addition to the built-in ones for resolving Migrations to apply.
+ *
+ * @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)
+ */
+ public FluentConfiguration resolvers(String... resolvers) {
+ config.setResolversAsClassNames(resolvers);
+ return this;
+ }
+
+ /**
+ * Whether Flyway should skip the default resolvers. If true, only custom resolvers are used.
+ *
+ * @param skipDefaultResolvers Whether default built-in resolvers should be skipped.
(default: false)
+ */
+ public FluentConfiguration skipDefaultResolvers(boolean skipDefaultResolvers) {
+ config.setSkipDefaultResolvers(skipDefaultResolvers);
+ return this;
+ }
+
+ /**
+ * Whether to stream SQL migrations when executing them. Streaming doesn't load the entire migration in memory at
+ * once. Instead each statement is loaded individually. This is particularly useful for very large SQL migrations
+ * composed of multiple MB or even GB of reference data, as this dramatically reduces Flyway's memory consumption.
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param stream {@code true} to stream SQL migrations. {@code false} to fully loaded them in memory instead. (default: {@code false})
+ */
+ public FluentConfiguration stream(boolean stream) {
+ config.setStream(stream);
+ return this;
+ }
+
+ /**
+ * Whether to batch SQL statements when executing them. Batching can save up to 99 percent of network roundtrips by
+ * sending up to 100 statements at once over the network to the database, instead of sending each statement
+ * individually. This is particularly useful for very large SQL migrations composed of multiple MB or even GB of
+ * reference data, as this can dramatically reduce the network overhead. This is supported for INSERT, UPDATE,
+ * DELETE, MERGE and UPSERT statements. All other statements are automatically executed without batching.
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param batch {@code true} to batch SQL statements. {@code false} to execute them individually instead. (default: {@code false})
+ */
+ public FluentConfiguration batch(boolean batch) {
+ config.setBatch(batch);
+ return this;
+ }
+
+ /**
+ * Whether to Flyway's support for Oracle SQL*Plus commands should be activated.
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param oracleSqlplus {@code true} to active SQL*Plus support. {@code false} to fail fast instead. (default: {@code false})
+ */
+ public FluentConfiguration oracleSqlplus(boolean oracleSqlplus) {
+ config.setOracleSqlplus(oracleSqlplus);
+ return this;
+ }
+
+ /**
+ * Whether Flyway should issue a warning instead of an error whenever it encounters an Oracle SQL*Plus statement
+ * it doesn't yet support.
+ *
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param oracleSqlplusWarn {@code true} to issue a warning. {@code false} to fail fast instead. (default: {@code false})
+ */
+ public FluentConfiguration oracleSqlplusWarn(boolean oracleSqlplusWarn) {
+ config.setOracleSqlplusWarn(oracleSqlplusWarn);
+ return this;
+ }
+
+ /**
+ * Your Flyway license key (FL01...). Not yet a Flyway Pro or Enterprise Edition customer?
+ * Request your Flyway trial license key
+ * to try out Flyway Pro and Enterprise Edition features free for 30 days.
+ *
+ *
Flyway Pro and Flyway Enterprise only
+ *
+ * @param licenseKey Your Flyway license key.
+ */
+ public FluentConfiguration licenseKey(String licenseKey) {
+ config.setLicenseKey(licenseKey);
+ return this;
+ }
+
+ /**
+ * Custom ResourceProvider to be used to look up resources. If not set, the default strategy will be used.
+ *
+ * @param resourceProvider Custom ResourceProvider to be used to look up resources
+ */
+ public FluentConfiguration resourceProvider(ResourceProvider resourceProvider) {
+ config.setResourceProvider(resourceProvider);
+ return this;
+ }
+
+ /**
+ * Custom ClassProvider to be used to look up {@link JavaMigration} classes. If not set, the default strategy will be used.
+ *
+ * @param javaMigrationClassProvider Custom ClassProvider to be used to look up {@link JavaMigration} classes.
+ */
+ public FluentConfiguration javaMigrationClassProvider(ClassProvider javaMigrationClassProvider) {
+ config.setJavaMigrationClassProvider(javaMigrationClassProvider);
+ return this;
+ }
+
+ /**
+ * Configures Flyway with these properties. This overwrites any existing configuration. Property names are
+ * documented in the flyway maven plugin.
+ *
To use a custom ClassLoader, setClassLoader() must be called prior to calling this method.
+ *
+ * @param properties Properties used for configuration.
+ * @throws FlywayException when the configuration failed.
+ */
+ public FluentConfiguration configuration(Properties properties) {
+ config.configure(properties);
+ return this;
+ }
+
+ /**
+ * Configures Flyway with these properties. This overwrites any existing configuration. Property names are
+ * documented in the flyway maven plugin.
+ *
To use a custom ClassLoader, it must be passed to the Flyway constructor prior to calling this method.
+ *
+ * @param props Properties used for configuration.
+ * @throws FlywayException when the configuration failed.
+ */
+ public FluentConfiguration configuration(Map props) {
+ config.configure(props);
+ return this;
+ }
+
+ /**
+ * Load configuration files from the default locations:
+ * $installationDir$/conf/flyway.conf
+ * $user.home$/flyway.conf
+ * $workingDirectory$/flyway.conf
+ *
+ * The configuration files must be encoded with UTF-8.
+ *
+ * @throws FlywayException when the configuration failed.
+ */
+ public FluentConfiguration loadDefaultConfigurationFiles() {
+ return loadDefaultConfigurationFiles("UTF-8");
+ }
+
+ /**
+ * Load configuration files from the default locations:
+ * $installationDir$/conf/flyway.conf
+ * $user.home$/flyway.conf
+ * $workingDirectory$/flyway.conf
+ *
+ * @param encoding the conf file encoding.
+ * @throws FlywayException when the configuration failed.
+ */
+ public FluentConfiguration loadDefaultConfigurationFiles(String encoding) {
+ String installationPath = ClassUtils.getLocationOnDisk(FluentConfiguration.class);
+ File installationDir = new File(installationPath).getParentFile();
+
+ Map configMap = ConfigUtils.loadDefaultConfigurationFiles(installationDir, encoding);
+
+ config.configure(configMap);
+ return this;
+ }
+
+ /**
+ * Whether Flyway should attempt to create the schemas specified in the schemas property
+ *
+ * @param createSchemas @{code true} to attempt to create the schemas (default: {@code true})
+ */
+ public FluentConfiguration createSchemas(boolean createSchemas) {
+ config.setShouldCreateSchemas(createSchemas);
+ return this;
+ }
+
+ /**
+ * Configures Flyway using FLYWAY_* environment variables.
+ *
+ * @throws FlywayException when the configuration failed.
+ */
+ public FluentConfiguration envVars() {
+ config.configureUsingEnvVars();
+ return this;
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/configuration/package-info.java a/flyway-core/src/main/java/org/flywaydb/core/api/configuration/package-info.java
new file mode 100644
index 0000000..e360e7d
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/configuration/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Interfaces for Flyway configuration injection.
+ */
+package org.flywaydb.core.api.configuration;
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/executor/Context.java a/flyway-core/src/main/java/org/flywaydb/core/api/executor/Context.java
new file mode 100644
index 0000000..c682487
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/executor/Context.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.executor;
+
+import org.flywaydb.core.api.configuration.Configuration;
+
+import java.sql.Connection;
+
+/**
+ * The context relevant to a migration executor.
+ */
+public interface Context {
+ /**
+ * @return The configuration currently in use.
+ */
+ Configuration getConfiguration();
+
+ /**
+ * @return The JDBC connection being used. Transaction are managed by Flyway.
+ * When the context is passed to the migrate method, a transaction will already have
+ * been started if required and will be automatically committed or rolled back afterwards, unless the
+ * canExecuteInTransaction method has been implemented to return false.
+ */
+ Connection getConnection();
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/executor/MigrationExecutor.java a/flyway-core/src/main/java/org/flywaydb/core/api/executor/MigrationExecutor.java
new file mode 100644
index 0000000..a200c0e
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/executor/MigrationExecutor.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.executor;
+
+import java.sql.SQLException;
+
+/**
+ * Executes a migration.
+ */
+public interface MigrationExecutor {
+ /**
+ * Executes the migration this executor is associated with.
+ *
+ * @param context The context to use to execute the migration against the DB.
+ * @throws SQLException when the execution of a statement failed.
+ */
+ void execute(Context context) throws SQLException;
+
+ /**
+ * Whether the execution can take place inside a transaction. Almost all implementation should return {@code true}.
+ * This however makes it possible to execute certain migrations outside a transaction. This is useful for databases
+ * like PostgreSQL and SQL Server where certain statement can only execute outside a transaction.
+ *
+ * @return {@code true} if a transaction should be used (highly recommended), or {@code false} if not.
+ */
+ boolean canExecuteInTransaction();
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/executor/package-info.java a/flyway-core/src/main/java/org/flywaydb/core/api/executor/package-info.java
new file mode 100644
index 0000000..d25f38f
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/executor/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Interfaces for Migration executors.
+ */
+package org.flywaydb.core.api.executor;
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/logging/Log.java a/flyway-core/src/main/java/org/flywaydb/core/api/logging/Log.java
new file mode 100644
index 0000000..8332656
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/logging/Log.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.logging;
+
+/**
+ * A logger.
+ */
+public interface Log {
+ /**
+ * @return Whether debug logging is enabled.
+ */
+ boolean isDebugEnabled();
+
+ /**
+ * Logs a debug message.
+ *
+ * @param message The message to log.
+ */
+ void debug(String message);
+
+ /**
+ * Logs an info message.
+ *
+ * @param message The message to log.
+ */
+ void info(String message);
+
+ /**
+ * Logs a warning message.
+ *
+ * @param message The message to log.
+ */
+ void warn(String message);
+
+ /**
+ * Logs an error message.
+ *
+ * @param message The message to log.
+ */
+ void error(String message);
+
+ /**
+ * Logs an error message and the exception that caused it.
+ *
+ * @param message The message to log.
+ * @param e The exception that caused the error.
+ */
+ void error(String message, Exception e);
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/logging/LogCreator.java a/flyway-core/src/main/java/org/flywaydb/core/api/logging/LogCreator.java
new file mode 100644
index 0000000..8e04e2a
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/logging/LogCreator.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.logging;
+
+/**
+ * Factory for implementation-specific loggers.
+ */
+public interface LogCreator {
+ /**
+ * Creates an implementation-specific logger for this class.
+ *
+ * @param clazz The class to create the logger for.
+ * @return The logger.
+ */
+ Log createLogger(Class> clazz);
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/logging/LogFactory.java a/flyway-core/src/main/java/org/flywaydb/core/api/logging/LogFactory.java
new file mode 100644
index 0000000..357a6f5
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/logging/LogFactory.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.logging;
+
+import org.flywaydb.core.internal.logging.LogCreatorFactory;
+
+/**
+ * Factory for loggers. Custom MigrationResolver, MigrationExecutor, Callback and JavaMigration
+ * implementations should use this to obtain a logger that will work with any logging framework across all environments
+ * (API, Maven, Gradle, CLI, etc).
+ */
+public class LogFactory {
+ /**
+ * Factory for implementation-specific loggers.
+ */
+ private static volatile LogCreator logCreator;
+
+ /**
+ * The factory for implementation-specific loggers to be used as a fallback when no other suitable loggers were found.
+ */
+ private static LogCreator fallbackLogCreator;
+
+ /**
+ * Prevent instantiation.
+ */
+ private LogFactory() {
+ // Do nothing
+ }
+
+ /**
+ * Sets the LogCreator that will be used. This will effectively override Flyway's default LogCreator auto-detection
+ * logic and force Flyway to always use this LogCreator regardless of which log libraries are present on the
+ * classpath.
+ *
+ *
This is primarily meant for integrating Flyway into environments with their own logging system (like Ant,
+ * Gradle, Maven, ...). This ensures Flyway is a good citizen in those environments and sends its logs through the
+ * expected pipeline.
+ *
+ * @param logCreator The factory for implementation-specific loggers.
+ */
+ public static void setLogCreator(LogCreator logCreator) {
+ LogFactory.logCreator = logCreator;
+ }
+
+ /**
+ * Sets the fallback LogCreator. This LogCreator will be used as a fallback solution when the default LogCreator
+ * auto-detection logic fails to detect a suitable LogCreator based on the log libraries present on the classpath.
+ *
+ * @param fallbackLogCreator The factory for implementation-specific loggers to be used as a fallback when no other
+ * suitable loggers were found.
+ */
+ public static void setFallbackLogCreator(LogCreator fallbackLogCreator) {
+ LogFactory.fallbackLogCreator = fallbackLogCreator;
+ }
+
+ /**
+ * Retrieves the matching logger for this class.
+ *
+ * @param clazz The class to get the logger for.
+ * @return The logger.
+ */
+ public static Log getLog(Class> clazz) {
+ if (logCreator == null) {
+ logCreator = LogCreatorFactory.getLogCreator(LogFactory.class.getClassLoader(), fallbackLogCreator);
+ }
+
+ return logCreator.createLogger(clazz);
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/logging/package-info.java a/flyway-core/src/main/java/org/flywaydb/core/api/logging/package-info.java
new file mode 100644
index 0000000..1555fa8
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/logging/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Interfaces for Flyway's log abstraction. Custom MigrationResolver, MigrationExecutor, FlywayCallback, ErrorHandler and JdbcMigration
+ * implementations should use this to obtain a logger that will work with any logging framework across all environments
+ * (API, Maven, Gradle, CLI, etc).
+ */
+package org.flywaydb.core.api.logging;
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/migration/BaseJavaMigration.java a/flyway-core/src/main/java/org/flywaydb/core/api/migration/BaseJavaMigration.java
new file mode 100644
index 0000000..9eb31a1
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/migration/BaseJavaMigration.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.migration;
+
+import org.flywaydb.core.api.FlywayException;
+import org.flywaydb.core.api.MigrationVersion;
+import org.flywaydb.core.internal.resolver.MigrationInfoHelper;
+import org.flywaydb.core.internal.util.Pair;
+
+/**
+ *
This is the recommended class to extend for implementing Java-based Migrations.
+ *
Subclasses should follow the default Flyway naming convention of having a class name with the following structure:
+ *
+ *
Versioned Migrations: V2__Add_new_table
+ *
Undo Migrations: U2__Add_new_table
+ *
Repeatable Migrations: R__Add_new_table
+ *
+ *
+ *
The file name consists of the following parts:
+ *
+ *
Prefix: V for versioned migrations, U for undo migrations, R for repeatable migrations
+ *
Version: Underscores (automatically replaced by dots at runtime) separate as many parts as you like (Not for repeatable migrations)
+ *
Separator: __ (two underscores)
+ *
Description: Underscores (automatically replaced by spaces at runtime) separate the words
+ *
+ *
If you need more control over the class name, you can override the default convention by implementing the
+ * JavaMigration interface directly. This will allow you to name your class as you wish. Version, description and
+ * migration category are provided by implementing the respective methods.
+ */
+public abstract class BaseJavaMigration implements JavaMigration {
+ private final MigrationVersion version;
+ private final String description;
+
+
+
+
+ /**
+ * Creates a new instance of a Java-based migration following Flyway's default naming convention.
+ */
+ public BaseJavaMigration() {
+ String shortName = getClass().getSimpleName();
+ String prefix;
+
+
+
+ boolean repeatable = shortName.startsWith("R");
+ if (shortName.startsWith("V") || repeatable
+
+
+
+ ) {
+ prefix = shortName.substring(0, 1);
+ } else {
+ throw new FlywayException("Invalid Java-based migration class name: " + getClass().getName()
+ + " => ensure it starts with V" +
+
+
+
+ " or R," +
+ " or implement org.flywaydb.core.api.migration.JavaMigration directly for non-default naming");
+ }
+ Pair info =
+ MigrationInfoHelper.extractVersionAndDescription(shortName, prefix, "__", new String[]{""}, repeatable);
+ version = info.getLeft();
+ description = info.getRight();
+ }
+
+ @Override
+ public MigrationVersion getVersion() {
+ return version;
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public Integer getChecksum() {
+ return null;
+ }
+
+ @Override
+ public boolean isUndo() {
+
+
+
+
+ return false;
+
+ }
+
+ @Override
+ public boolean canExecuteInTransaction() {
+ return true;
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/migration/Context.java a/flyway-core/src/main/java/org/flywaydb/core/api/migration/Context.java
new file mode 100644
index 0000000..6dd9666
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/migration/Context.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.migration;
+
+import org.flywaydb.core.api.configuration.Configuration;
+
+import java.sql.Connection;
+
+/**
+ * The context relevant to a Java-based migration.
+ */
+public interface Context {
+ /**
+ * @return The configuration currently in use.
+ */
+ Configuration getConfiguration();
+
+ /**
+ * @return The JDBC connection being used. Transaction are managed by Flyway.
+ * When the context is passed to the migrate method, a transaction will already have
+ * been started if required and will be automatically committed or rolled back afterwards, unless the
+ * canExecuteInTransaction method has been implemented to return false.
+ */
+ Connection getConnection();
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/migration/JavaMigration.java a/flyway-core/src/main/java/org/flywaydb/core/api/migration/JavaMigration.java
new file mode 100644
index 0000000..d2c699c
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/migration/JavaMigration.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.migration;
+
+import org.flywaydb.core.api.MigrationVersion;
+
+/**
+ * Interface to be implemented by Java-based Migrations.
+ *
+ *
Java-based migrations are a great fit for all changes that can not easily be expressed using SQL.
+ *
+ *
These would typically be things like
+ *
+ *
BLOB & CLOB changes
+ *
Advanced bulk data changes (Recalculations, advanced format changes, …)
+ *
+ *
+ *
Migration classes implementing this interface will be
+ * automatically discovered when placed in a location on the classpath.
+ *
+ *
Most users will be better served by subclassing subclass {@link BaseJavaMigration} instead of implementing this
+ * interface directly, as {@link BaseJavaMigration} encourages the use of Flyway's default naming convention and
+ * comes with sensible default implementations of all methods (except migrate of course) while at the same time also
+ * providing better isolation against future additions to this interface.
+ */
+public interface JavaMigration {
+ /**
+ * @return The version of the schema after the migration is complete. {@code null} for repeatable migrations.
+ */
+ MigrationVersion getVersion();
+
+ /**
+ * @return The description of this migration for the migration history. Never {@code null}.
+ */
+ String getDescription();
+
+ /**
+ * Computes the checksum of the migration.
+ *
+ * @return The checksum of the migration.
+ */
+ Integer getChecksum();
+
+ /**
+ * Whether this is an undo migration for a previously applied versioned migration.
+ *
+ * @return {@code true} if it is, {@code false} if not. Always {@code false} for repeatable migrations.
+ */
+ boolean isUndo();
+
+ /**
+ * Whether the execution should take place inside a transaction. Almost all implementation should return {@code true}.
+ * This however makes it possible to execute certain migrations outside a transaction. This is useful for databases
+ * like PostgreSQL and SQL Server where certain statement can only execute outside a transaction.
+ *
+ * @return {@code true} if a transaction should be used (highly recommended), or {@code false} if not.
+ */
+ boolean canExecuteInTransaction();
+
+ /**
+ * Executes this migration. The execution will automatically take place within a transaction, when the underlying
+ * database supports it and the canExecuteInTransaction returns {@code true}.
+ *
+ * @param context The context relevant for this migration, containing things like the JDBC connection to use and the
+ * current Flyway configuration.
+ * @throws Exception when the migration failed.
+ */
+ void migrate(Context context) throws Exception;
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/migration/package-info.java a/flyway-core/src/main/java/org/flywaydb/core/api/migration/package-info.java
new file mode 100644
index 0000000..d6d590e
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/migration/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Interfaces for Migration implementors.
+ */
+package org.flywaydb.core.api.migration;
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/package-info.java a/flyway-core/src/main/java/org/flywaydb/core/api/package-info.java
new file mode 100644
index 0000000..f7ea4c0
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * FlywayException, MigrationInfo and related classes.
+ */
+package org.flywaydb.core.api;
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/resolver/ChecksumMatcher.java a/flyway-core/src/main/java/org/flywaydb/core/api/resolver/ChecksumMatcher.java
new file mode 100644
index 0000000..2986649
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/resolver/ChecksumMatcher.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.resolver;
+
+interface ChecksumMatcher {
+ boolean checksumMatches(Integer checksum);
+
+ boolean checksumMatchesWithoutBeingIdentical(Integer checksum);
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/resolver/Context.java a/flyway-core/src/main/java/org/flywaydb/core/api/resolver/Context.java
new file mode 100644
index 0000000..62b46df
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/resolver/Context.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.resolver;
+
+import org.flywaydb.core.api.configuration.Configuration;
+
+import java.sql.Connection;
+
+/**
+ * The context relevant to a migration resolver.
+ */
+public interface Context {
+ /**
+ * @return The configuration currently in use.
+ */
+ Configuration getConfiguration();
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/resolver/MigrationResolver.java a/flyway-core/src/main/java/org/flywaydb/core/api/resolver/MigrationResolver.java
new file mode 100644
index 0000000..1c6b9bf
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/resolver/MigrationResolver.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.resolver;
+
+import java.util.Collection;
+
+/**
+ * Resolves available migrations. This interface can be implemented to create custom resolvers. A custom resolver
+ * can be used to create additional types of migrations not covered by the standard resolvers (jdbc, sql, spring-jdbc).
+ * Using the skipDefaultResolvers configuration property, the built-in resolvers can also be completely replaced.
+ */
+public interface MigrationResolver {
+ /**
+ * Resolves the available migrations.
+ *
+ * @return The available migrations.
+ */
+ Collection resolveMigrations(Context context);
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/resolver/ResolvedMigration.java a/flyway-core/src/main/java/org/flywaydb/core/api/resolver/ResolvedMigration.java
new file mode 100644
index 0000000..b5bf08f
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/resolver/ResolvedMigration.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.api.resolver;
+
+import org.flywaydb.core.api.MigrationType;
+import org.flywaydb.core.api.MigrationVersion;
+import org.flywaydb.core.api.executor.MigrationExecutor;
+
+/**
+ * Migration resolved through a MigrationResolver. Can be applied against a database.
+ */
+public interface ResolvedMigration extends ChecksumMatcher {
+ /**
+ * @return The version of the database after applying this migration. {@code null} for repeatable migrations.
+ */
+ MigrationVersion getVersion();
+
+ /**
+ * @return The description of the migration.
+ */
+ String getDescription();
+
+ /**
+ * @return The name of the script to execute for this migration, relative to its base (classpath/filesystem) location.
+ */
+ String getScript();
+
+ /**
+ * @return The checksum of the migration. Optional. Can be {@code null} if not unique checksum is computable.
+ */
+ Integer getChecksum();
+
+ /**
+ * @return The type of migration (INIT, SQL, ...)
+ */
+ MigrationType getType();
+
+ /**
+ * @return The physical location of the migration on disk. Used for more precise error reporting in case of conflict.
+ */
+ String getPhysicalLocation();
+
+ /**
+ * @return The executor to run this migration.
+ */
+ MigrationExecutor getExecutor();
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/api/resolver/package-info.java a/flyway-core/src/main/java/org/flywaydb/core/api/resolver/package-info.java
new file mode 100644
index 0000000..13fd55a
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/api/resolver/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Interfaces for Migration resolvers.
+ */
+package org.flywaydb.core.api.resolver;
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/internal/callback/CallbackExecutor.java a/flyway-core/src/main/java/org/flywaydb/core/internal/callback/CallbackExecutor.java
new file mode 100644
index 0000000..1bf6b07
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/internal/callback/CallbackExecutor.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.internal.callback;
+
+import org.flywaydb.core.api.MigrationInfo;
+import org.flywaydb.core.api.callback.Event;
+import org.flywaydb.core.api.callback.Warning;
+import org.flywaydb.core.api.callback.Error;
+
+import java.util.List;
+
+/**
+ * Executes the callbacks for a specific event.
+ */
+public interface CallbackExecutor {
+ /**
+ * Executes the callbacks for this event on the main connection, within a separate transaction per callback if possible.
+ *
+ * @param event The vent to handle.
+ */
+ void onEvent(Event event);
+
+ /**
+ * Executes the callbacks for this event on the migration connection, within a separate transaction per callback if possible.
+ *
+ * @param event The vent to handle.
+ */
+ void onMigrateOrUndoEvent(Event event);
+
+ /**
+ * Sets the current migration info.
+ *
+ * @param migrationInfo The current migration.
+ */
+ void setMigrationInfo(MigrationInfo migrationInfo);
+
+ /**
+ * Executes the callbacks for an "each" event within the same transaction (if any) as the main operation.
+ *
+ * @param event The event to handle.
+ */
+ void onEachMigrateOrUndoEvent(Event event);
+
+
+
+
+
+
+
+
+
+
+
+
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/internal/callback/DefaultCallbackExecutor.java a/flyway-core/src/main/java/org/flywaydb/core/internal/callback/DefaultCallbackExecutor.java
new file mode 100644
index 0000000..00849fb
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/internal/callback/DefaultCallbackExecutor.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.internal.callback;
+
+import org.flywaydb.core.api.FlywayException;
+import org.flywaydb.core.api.MigrationInfo;
+import org.flywaydb.core.api.callback.Callback;
+import org.flywaydb.core.api.callback.Context;
+import org.flywaydb.core.api.callback.Error;
+import org.flywaydb.core.api.callback.Event;
+import org.flywaydb.core.api.callback.Warning;
+import org.flywaydb.core.api.configuration.Configuration;
+import org.flywaydb.core.internal.database.base.Connection;
+import org.flywaydb.core.internal.database.base.Database;
+import org.flywaydb.core.internal.database.base.Schema;
+import org.flywaydb.core.internal.jdbc.ExecutionTemplateFactory;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+/**
+ * Executes the callbacks for a specific event.
+ */
+public class DefaultCallbackExecutor implements CallbackExecutor {
+ private final Configuration configuration;
+ private final Database database;
+ private final Schema schema;
+ private final Collection callbacks;
+ private MigrationInfo migrationInfo;
+
+ /**
+ * Creates a new callback executor.
+ *
+ * @param configuration The configuration.
+ * @param database The database.
+ * @param schema The current schema to use for the connection.
+ * @param callbacks The callbacks to execute.
+ */
+ public DefaultCallbackExecutor(Configuration configuration, Database database, Schema schema, Collection callbacks) {
+ this.configuration = configuration;
+ this.database = database;
+ this.schema = schema;
+ this.callbacks = callbacks;
+ }
+
+ @Override
+ public void onEvent(final Event event) {
+ execute(event, database.getMainConnection());
+ }
+
+ @Override
+ public void onMigrateOrUndoEvent(final Event event) {
+ execute(event, database.getMigrationConnection());
+ }
+
+ @Override
+ public void setMigrationInfo(MigrationInfo migrationInfo) {
+ this.migrationInfo = migrationInfo;
+ }
+
+ @Override
+ public void onEachMigrateOrUndoEvent(Event event) {
+ final Context context = new SimpleContext(configuration, database.getMigrationConnection(), migrationInfo);
+ for (Callback callback : callbacks) {
+ if (callback.supports(event, context)) {
+ callback.handle(event, context);
+ }
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ private void execute(final Event event, final Connection connection) {
+ final Context context = new SimpleContext(configuration, connection, null);
+
+ for (final Callback callback : callbacks) {
+ if (callback.supports(event, context)) {
+ if (callback.canHandleInTransaction(event, context)) {
+ ExecutionTemplateFactory.createExecutionTemplate(connection.getJdbcConnection(),
+ database).execute(new Callable() {
+ @Override
+ public Void call() {
+ DefaultCallbackExecutor.this.execute(connection, callback, event, context);
+ return null;
+ }
+ });
+ } else {
+ execute(connection, callback, event, context);
+ }
+ }
+ }
+ }
+
+ private void execute(Connection connection, Callback callback, Event event, Context context) {
+ connection.restoreOriginalState();
+ connection.changeCurrentSchemaTo(schema);
+ handleEvent(callback, event, context);
+ }
+
+ private void handleEvent(Callback callback, Event event, Context context) {
+ try {
+ callback.handle(event, context);
+ } catch (RuntimeException e) {
+ throw new FlywayException("Error while executing " + event.getId() + " callback: " + e.getMessage(), e);
+ }
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/internal/callback/NoopCallback.java a/flyway-core/src/main/java/org/flywaydb/core/internal/callback/NoopCallback.java
new file mode 100644
index 0000000..99ac6a4
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/internal/callback/NoopCallback.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.internal.callback;
+
+import org.flywaydb.core.api.callback.Callback;
+import org.flywaydb.core.api.callback.Context;
+import org.flywaydb.core.api.callback.Event;
+
+/**
+ * Callback that does nothing.
+ */
+public enum NoopCallback implements Callback {
+ INSTANCE;
+
+ @Override
+ public boolean supports(Event event, Context context) {
+ return false;
+ }
+
+ @Override
+ public boolean canHandleInTransaction(Event event, Context context) {
+ return true;
+ }
+
+ @Override
+ public void handle(Event event, Context context) {
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/internal/callback/NoopCallbackExecutor.java a/flyway-core/src/main/java/org/flywaydb/core/internal/callback/NoopCallbackExecutor.java
new file mode 100644
index 0000000..90b2f2d
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/internal/callback/NoopCallbackExecutor.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.internal.callback;
+
+import org.flywaydb.core.api.MigrationInfo;
+import org.flywaydb.core.api.callback.Error;
+import org.flywaydb.core.api.callback.Event;
+import org.flywaydb.core.api.callback.Warning;
+
+import java.util.List;
+
+/**
+ * A callback executor that does nothing.
+ */
+public enum NoopCallbackExecutor implements CallbackExecutor {
+ INSTANCE;
+
+ @Override
+ public void onEvent(Event event) {
+ }
+
+ @Override
+ public void onMigrateOrUndoEvent(Event event) {
+ }
+
+ @Override
+ public void setMigrationInfo(MigrationInfo migrationInfo) {
+ }
+
+ @Override
+ public void onEachMigrateOrUndoEvent(Event event) {
+ }
+
+
+
+
+
+
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/internal/callback/SimpleContext.java a/flyway-core/src/main/java/org/flywaydb/core/internal/callback/SimpleContext.java
new file mode 100644
index 0000000..004e4bd
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/internal/callback/SimpleContext.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.internal.callback;
+
+import org.flywaydb.core.api.MigrationInfo;
+import org.flywaydb.core.api.callback.Context;
+import org.flywaydb.core.api.callback.Error;
+import org.flywaydb.core.api.callback.Statement;
+import org.flywaydb.core.api.callback.Warning;
+import org.flywaydb.core.api.configuration.Configuration;
+import org.flywaydb.core.internal.database.base.Connection;
+
+import java.util.List;
+
+public class SimpleContext implements Context {
+ private final Configuration configuration;
+ private final Connection connection;
+ private final MigrationInfo migrationInfo;
+ private final Statement statement;
+
+ SimpleContext(Configuration configuration, Connection connection, MigrationInfo migrationInfo) {
+ this.configuration = configuration;
+ this.connection = connection;
+ this.migrationInfo = migrationInfo;
+ this.statement = null;
+ }
+
+ public SimpleContext(Configuration configuration, Connection connection, MigrationInfo migrationInfo,
+ String sql, List warnings, List errors) {
+ this.configuration = configuration;
+ this.connection = connection;
+ this.migrationInfo = migrationInfo;
+ this.statement = new SimpleStatement(sql, warnings, errors);
+ }
+
+ @Override
+ public Configuration getConfiguration() {
+ return configuration;
+ }
+
+ @Override
+ public java.sql.Connection getConnection() {
+ return connection.getJdbcConnection();
+ }
+
+ @Override
+ public MigrationInfo getMigrationInfo() {
+ return migrationInfo;
+ }
+
+ @Override
+ public Statement getStatement() {
+ return statement;
+ }
+
+
+ private static class SimpleStatement implements Statement {
+ private final String sql;
+ private final List warnings;
+ private final List errors;
+
+ private SimpleStatement(String sql, List warnings, List errors) {
+ this.sql = sql;
+ this.warnings = warnings;
+ this.errors = errors;
+ }
+
+ @Override
+ public String getSql() {
+ return sql;
+ }
+
+ @Override
+ public List getWarnings() {
+ return warnings;
+ }
+
+ @Override
+ public List getErrors() {
+ return errors;
+ }
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/internal/callback/SqlScriptCallbackFactory.java a/flyway-core/src/main/java/org/flywaydb/core/internal/callback/SqlScriptCallbackFactory.java
new file mode 100644
index 0000000..f71f516
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/internal/callback/SqlScriptCallbackFactory.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.internal.callback;
+
+import org.flywaydb.core.api.FlywayException;
+import org.flywaydb.core.api.callback.Callback;
+import org.flywaydb.core.api.callback.Context;
+import org.flywaydb.core.api.callback.Event;
+import org.flywaydb.core.api.configuration.Configuration;
+import org.flywaydb.core.api.logging.Log;
+import org.flywaydb.core.api.logging.LogFactory;
+import org.flywaydb.core.internal.resource.LoadableResource;
+import org.flywaydb.core.internal.resource.ResourceName;
+import org.flywaydb.core.internal.resource.ResourceNameParser;
+import org.flywaydb.core.api.ResourceProvider;
+import org.flywaydb.core.internal.sqlscript.SqlScript;
+import org.flywaydb.core.internal.sqlscript.SqlScriptExecutorFactory;
+import org.flywaydb.core.internal.sqlscript.SqlScriptFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Callback factory, looking for SQL scripts (named like on the callback methods) inside the configured locations.
+ */
+public class SqlScriptCallbackFactory {
+ private static final Log LOG = LogFactory.getLog(SqlScriptCallbackFactory.class);
+
+ private final List callbacks = new ArrayList<>();
+
+ /**
+ * Creates a new instance.
+ *
+ * @param resourceProvider The resource provider.
+ * @param sqlScriptFactory The SQL statement factory.
+ * @param configuration The Flyway configuration.
+ */
+ public SqlScriptCallbackFactory(ResourceProvider resourceProvider,
+ SqlScriptExecutorFactory sqlScriptExecutorFactory,
+ SqlScriptFactory sqlScriptFactory,
+ Configuration configuration) {
+ Map callbacksFound = new HashMap<>();
+
+ LOG.debug("Scanning for SQL callbacks ...");
+ Collection resources = resourceProvider.getResources("", configuration.getSqlMigrationSuffixes());
+ ResourceNameParser resourceNameParser = new ResourceNameParser(configuration);
+
+ for (LoadableResource resource : resources) {
+ ResourceName parsedName = resourceNameParser.parse(resource.getFilename());
+ if (!parsedName.isValid()) {
+ continue;
+ }
+
+ String name = parsedName.getFilenameWithoutSuffix();
+ Event event = Event.fromId(parsedName.getPrefix());
+ if (event != null) {
+ SqlScript existing = callbacksFound.get(name);
+ if (existing != null) {
+ throw new FlywayException("Found more than 1 SQL callback script called " + name + "!\n" +
+ "Offenders:\n" +
+ "-> " + existing.getResource().getAbsolutePathOnDisk() + "\n" +
+ "-> " + resource.getAbsolutePathOnDisk());
+ }
+ SqlScript sqlScript = sqlScriptFactory.createSqlScript(resource, configuration.isMixed(), resourceProvider);
+ callbacksFound.put(name, sqlScript);
+ callbacks.add(new SqlScriptCallback(event, parsedName.getDescription(), sqlScriptExecutorFactory, sqlScript
+
+
+
+ ));
+ }
+ }
+ Collections.sort(callbacks);
+ }
+
+ public List getCallbacks() {
+ return new ArrayList<>(callbacks);
+ }
+
+ private static class SqlScriptCallback implements Callback, Comparable {
+ private final Event event;
+ private final String description;
+ private final SqlScriptExecutorFactory sqlScriptExecutorFactory;
+ private final SqlScript sqlScript;
+
+
+
+
+ private SqlScriptCallback(Event event, String description, SqlScriptExecutorFactory sqlScriptExecutorFactory, SqlScript sqlScript
+
+
+
+ ) {
+ this.event = event;
+ this.description = description;
+ this.sqlScriptExecutorFactory = sqlScriptExecutorFactory;
+ this.sqlScript = sqlScript;
+
+
+
+ }
+
+ @Override
+ public boolean supports(Event event, Context context) {
+ return this.event == event;
+ }
+
+ @Override
+ public boolean canHandleInTransaction(Event event, Context context) {
+ return sqlScript.executeInTransaction();
+ }
+
+ @Override
+ public void handle(Event event, Context context) {
+ LOG.info("Executing SQL callback: " + event.getId()
+ + (description == null ? "" : " - " + description)
+ + (sqlScript.executeInTransaction() ? "" : " [non-transactional]"));
+ sqlScriptExecutorFactory.createSqlScriptExecutor(context.getConnection()
+
+
+
+ ).execute(sqlScript);
+ }
+
+ @Override
+ public int compareTo(SqlScriptCallback o) {
+ int result = event.compareTo(o.event);
+ if (result == 0) {
+ if (description == null) {
+ return -1;
+ }
+ if (o.description == null) {
+ return 1;
+ }
+ result = description.compareTo(o.description);
+ }
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/internal/callback/package-info.java a/flyway-core/src/main/java/org/flywaydb/core/internal/callback/package-info.java
new file mode 100644
index 0000000..b189d1e
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/internal/callback/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * FlywayException, MigrationInfo and related classes.
+ */
+package org.flywaydb.core.internal.callback;
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/internal/clazz/NoopClassProvider.java a/flyway-core/src/main/java/org/flywaydb/core/internal/clazz/NoopClassProvider.java
new file mode 100644
index 0000000..0c5bc49
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/internal/clazz/NoopClassProvider.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.internal.clazz;
+
+import org.flywaydb.core.api.ClassProvider;
+
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * ClassProvider that does nothing.
+ */
+public enum NoopClassProvider implements ClassProvider {
+ INSTANCE;
+
+ @Override
+ public Collection> getClasses() {
+ return Collections.emptyList();
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/internal/clazz/package-info.java a/flyway-core/src/main/java/org/flywaydb/core/internal/clazz/package-info.java
new file mode 100644
index 0000000..85d2497
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/internal/clazz/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Private API. No compatibility guarantees provided.
+ */
+package org.flywaydb.core.internal.clazz;
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/internal/command/DbBaseline.java a/flyway-core/src/main/java/org/flywaydb/core/internal/command/DbBaseline.java
new file mode 100644
index 0000000..8993977
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/internal/command/DbBaseline.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.internal.command;
+
+import org.flywaydb.core.api.FlywayException;
+import org.flywaydb.core.api.MigrationVersion;
+import org.flywaydb.core.api.callback.Event;
+import org.flywaydb.core.api.logging.Log;
+import org.flywaydb.core.api.logging.LogFactory;
+import org.flywaydb.core.internal.callback.CallbackExecutor;
+import org.flywaydb.core.internal.schemahistory.AppliedMigration;
+import org.flywaydb.core.internal.schemahistory.SchemaHistory;
+
+/**
+ * Handles Flyway's baseline command.
+ */
+public class DbBaseline {
+ private static final Log LOG = LogFactory.getLog(DbBaseline.class);
+
+ /**
+ * The schema history table.
+ */
+ private final SchemaHistory schemaHistory;
+
+ /**
+ * The version to tag an existing schema with when executing baseline.
+ */
+ private final MigrationVersion baselineVersion;
+
+ /**
+ * The description to tag an existing schema with when executing baseline.
+ */
+ private final String baselineDescription;
+
+ /**
+ * The callback executor.
+ */
+ private final CallbackExecutor callbackExecutor;
+
+ /**
+ * Creates a new DbBaseline.
+ *
+ * @param schemaHistory The database schema history table.
+ * @param baselineVersion The version to tag an existing schema with when executing baseline.
+ * @param baselineDescription The description to tag an existing schema with when executing baseline.
+ * @param callbackExecutor The callback executor.
+ */
+ public DbBaseline(SchemaHistory schemaHistory, MigrationVersion baselineVersion,
+ String baselineDescription, CallbackExecutor callbackExecutor) {
+ this.schemaHistory = schemaHistory;
+ this.baselineVersion = baselineVersion;
+ this.baselineDescription = baselineDescription;
+ this.callbackExecutor = callbackExecutor;
+ }
+
+ /**
+ * Baselines the database.
+ */
+ public void baseline() {
+ callbackExecutor.onEvent(Event.BEFORE_BASELINE);
+
+ try {
+ if (!schemaHistory.exists()) {
+ schemaHistory.create(true);
+ LOG.info("Successfully baselined schema with version: " + baselineVersion);
+ } else {
+ AppliedMigration baselineMarker = schemaHistory.getBaselineMarker();
+ if (baselineMarker != null) {
+ if (baselineVersion.equals(baselineMarker.getVersion())
+ && baselineDescription.equals(baselineMarker.getDescription())) {
+ LOG.info("Schema history table " + schemaHistory + " already initialized with ("
+ + baselineVersion + "," + baselineDescription + "). Skipping.");
+ } else {
+ throw new FlywayException("Unable to baseline schema history table " + schemaHistory + " with ("
+ + baselineVersion + "," + baselineDescription
+ + ") as it has already been baselined with ("
+ + baselineMarker.getVersion() + "," + baselineMarker.getDescription() + ")");
+ }
+ } else {
+ if (schemaHistory.hasSchemasMarker() && baselineVersion.equals(MigrationVersion.fromVersion("0"))) {
+ throw new FlywayException("Unable to baseline schema history table " + schemaHistory + " with version 0 as this version was used for schema creation");
+ }
+
+ if (schemaHistory.hasNonSyntheticAppliedMigrations()) {
+ throw new FlywayException("Unable to baseline schema history table " + schemaHistory + " as it already contains migrations");
+ }
+
+ if (schemaHistory.allAppliedMigrations().isEmpty()) {
+ throw new FlywayException("Unable to baseline schema history table " + schemaHistory + " as it already exists, and is empty.\n" +
+ "Delete the schema history table with the clean command, and run baseline again.");
+ }
+
+ throw new FlywayException("Unable to baseline schema history table " + schemaHistory + " as it already contains migrations.\n" +
+ "Delete the schema history table with the clean command, and run baseline again.");
+ }
+ }
+ } catch (FlywayException e) {
+ callbackExecutor.onEvent(Event.AFTER_BASELINE_ERROR);
+ throw e;
+ }
+
+ callbackExecutor.onEvent(Event.AFTER_BASELINE);
+ }
+}
\ No newline at end of file
diff --git b/flyway-core/src/main/java/org/flywaydb/core/internal/command/DbClean.java a/flyway-core/src/main/java/org/flywaydb/core/internal/command/DbClean.java
new file mode 100644
index 0000000..4e39fb7
--- /dev/null
+++ a/flyway-core/src/main/java/org/flywaydb/core/internal/command/DbClean.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2010-2020 Redgate Software Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flywaydb.core.internal.command;
+
+import org.flywaydb.core.api.FlywayException;
+import org.flywaydb.core.api.callback.Event;
+import org.flywaydb.core.api.logging.Log;
+import org.flywaydb.core.api.logging.LogFactory;
+import org.flywaydb.core.internal.callback.CallbackExecutor;
+import org.flywaydb.core.internal.database.base.Connection;
+import org.flywaydb.core.internal.database.base.Database;
+import org.flywaydb.core.internal.database.base.Schema;
+import org.flywaydb.core.internal.exception.FlywaySqlException;
+import org.flywaydb.core.internal.jdbc.ExecutionTemplateFactory;
+import org.flywaydb.core.internal.schemahistory.SchemaHistory;
+import org.flywaydb.core.internal.util.StopWatch;
+import org.flywaydb.core.internal.util.TimeFormat;
+
+import java.util.concurrent.Callable;
+
+/**
+ * Main workflow for cleaning the database.
+ */
+public class DbClean {
+ private static final Log LOG = LogFactory.getLog(DbClean.class);
+
+ /**
+ * The connection to use.
+ */
+ private final Connection connection;
+
+ /**
+ * The schema history table.
+ */
+ private final SchemaHistory schemaHistory;
+
+ /**
+ * The schemas to clean.
+ */
+ private final Schema[] schemas;
+
+ /**
+ * The callback executor.
+ */
+ private final CallbackExecutor callbackExecutor;
+
+ /**
+ * Whether to disable clean.
+ *
This is especially useful for production environments where running clean can be quite a career limiting move.
+ */
+ private boolean cleanDisabled;
+
+ /**
+ * The database
+ */
+ private Database database;
+
+ /**
+ * Creates a new database cleaner.
+ *
+ * @param database The DB support for the connection.
+ * @param schemaHistory The schema history table.
+ * @param schemas The schemas to clean.
+ * @param callbackExecutor The callback executor.
+ * @param cleanDisabled Whether to disable clean.
+ */
+ public DbClean(Database database, SchemaHistory schemaHistory, Schema[] schemas,
+ CallbackExecutor callbackExecutor, boolean cleanDisabled) {
+ this.database = database;
+ this.connection = database.getMainConnection();
+ this.schemaHistory = schemaHistory;
+ this.schemas = schemas;
+ this.callbackExecutor = callbackExecutor;
+ this.cleanDisabled = cleanDisabled;
+ }
+
+ /**
+ * Cleans the schemas of all objects.
+ *
+ * @throws FlywayException when clean failed.
+ */
+ public void clean() throws FlywayException {
+ if (cleanDisabled) {
+ throw new FlywayException("Unable to execute clean as it has been disabled with the \"flyway.cleanDisabled\" property.");
+ }
+ callbackExecutor.onEvent(Event.BEFORE_CLEAN);
+
+ try {
+ connection.changeCurrentSchemaTo(schemas[0]);
+ boolean dropSchemas = false;
+ try {
+ dropSchemas = schemaHistory.hasSchemasMarker();
+ } catch (Exception e) {
+ LOG.error("Error while checking whether the schemas should be dropped", e);
+ }
+
+ dropDatabaseObjectsPreSchemas();
+
+ for (Schema schema : schemas) {
+ if (!schema.exists()) {
+ LOG.warn("Unable to clean unknown schema: " + schema);
+ continue;
+ }
+
+ if (dropSchemas) {
+ dropSchema(schema);
+ } else {
+ cleanSchema(schema);
+ }
+ }
+
+ dropDatabaseObjectsPostSchemas();
+
+ } catch (FlywayException e) {
+ callbackExecutor.onEvent(Event.AFTER_CLEAN_ERROR);
+ throw e;
+ }
+
+ callbackExecutor.onEvent(Event.AFTER_CLEAN);
+ schemaHistory.clearCache();
+ }
+
+ /**
+ * Drops database-level objects that need to be cleaned prior to schema-level objects
+ *
+ * @throws FlywayException when the drop failed.
+ */
+ private void dropDatabaseObjectsPreSchemas() {
+ LOG.debug("Dropping pre-schema database level objects...");
+ StopWatch stopWatch = new StopWatch();
+ stopWatch.start();
+ try {
+ ExecutionTemplateFactory.createExecutionTemplate(connection.getJdbcConnection(),
+ database).execute(new Callable