null
otherwise.
68 | */
69 | public Change getChange() {
70 | return change;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/org/apache/ibatis/migration/hook/HookScript.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2022 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.apache.ibatis.migration.hook;
17 |
18 | import java.util.Map;
19 |
20 | public interface HookScript {
21 |
22 | void execute(Mapbefore_new
and after_new
hooks.
20 | */
21 | public class NewHookContext {
22 | private String description;
23 | private String filename;
24 |
25 | public NewHookContext(String description, String filename) {
26 | this.description = description;
27 | this.filename = filename;
28 | }
29 |
30 | /**
31 | * @return The specified description.
32 | */
33 | public String getDescription() {
34 | return description;
35 | }
36 |
37 | /**
38 | * @return The name of the file that is created by new command.before_new
hook, the file is not created yet.
40 | */
41 | public String getFilename() {
42 | return filename;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/org/apache/ibatis/migration/hook/ScriptHookContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2023 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.apache.ibatis.migration.hook;
17 |
18 | import org.apache.ibatis.migration.Change;
19 |
20 | /**
21 | * Hook context object that is available to before_new
and after_new
hooks.
22 | */
23 | public class ScriptHookContext {
24 | private final Change change;
25 | private final boolean undo;
26 |
27 | public ScriptHookContext(Change change, boolean undo) {
28 | this.change = change;
29 | this.undo = undo;
30 | }
31 |
32 | public Change getChange() {
33 | return change;
34 | }
35 |
36 | public boolean isUndo() {
37 | return undo;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/org/apache/ibatis/migration/hook/SqlHookScript.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2025 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.apache.ibatis.migration.hook;
17 |
18 | import java.io.ByteArrayOutputStream;
19 | import java.io.File;
20 | import java.io.IOException;
21 | import java.io.InputStream;
22 | import java.io.PrintStream;
23 | import java.io.StringReader;
24 | import java.nio.charset.Charset;
25 | import java.nio.file.Files;
26 | import java.util.Map;
27 | import java.util.Properties;
28 |
29 | import org.apache.ibatis.migration.MigrationException;
30 | import org.apache.ibatis.migration.VariableReplacer;
31 | import org.apache.ibatis.migration.utils.Util;
32 |
33 | public class SqlHookScript implements HookScript {
34 |
35 | protected final File scriptFile;
36 | protected final String charset;
37 | protected final Properties variables;
38 | protected final PrintStream printStream;
39 | protected final VariableReplacer replacer;
40 |
41 | public SqlHookScript(File scriptFile, String charset, String[] options, Properties variables,
42 | PrintStream printStream) {
43 | this.scriptFile = scriptFile;
44 | this.charset = charset;
45 | this.variables = variables;
46 | this.printStream = printStream;
47 | // options can be local variables in key=value format.
48 | for (String option : options) {
49 | int sep = option.indexOf('=');
50 | if (sep > -1) {
51 | this.variables.put(option.substring(0, sep), option.substring(sep + 1));
52 | }
53 | }
54 | replacer = new VariableReplacer(this.variables);
55 | }
56 |
57 | @Override
58 | public void execute(Mapnull
if the property file does not exist or the key
does not exist.
57 | */
58 | public static String getPropertyOption(String key) {
59 | String migrationsHome = migrationsHome();
60 | if (migrationsHome == null || migrationsHome.isEmpty()) {
61 | return null;
62 | }
63 | Properties properties = new Properties();
64 | String path = migrationsHome + File.separator + MIGRATIONS_PROPERTIES;
65 | try (InputStream stream = Files.newInputStream(Path.of(path))) {
66 | properties.load(stream);
67 | return properties.getProperty(key);
68 | } catch (Exception e) {
69 | return null;
70 | }
71 | }
72 |
73 | public static boolean isOption(String arg) {
74 | return arg.startsWith("--") && !arg.trim().endsWith("=");
75 | }
76 |
77 | public static File file(File path, String fileName) {
78 | return Path.of(path.getAbsolutePath() + File.separator + fileName).toFile();
79 | }
80 |
81 | public static String horizontalLine(String caption, int length) {
82 | StringBuilder builder = new StringBuilder();
83 | builder.append("==========");
84 | if (caption.length() > 0) {
85 | caption = " " + caption + " ";
86 | builder.append(caption);
87 | }
88 | for (int i = 0; i < length - caption.length() - 10; i++) {
89 | builder.append("=");
90 | }
91 | return builder.toString();
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/org/apache/ibatis/migration/utils/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2023 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.apache.ibatis.migration.utils;
17 |
--------------------------------------------------------------------------------
/src/main/resources/mybatis-migrations.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2010-2022 the original author or authors.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # https://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | groupId=@project.groupId@
18 | name=@project.name@
19 | version=@project.version@
20 | build=@java.version@
21 |
--------------------------------------------------------------------------------
/src/main/resources/org/apache/ibatis/migration/template_README:
--------------------------------------------------------------------------------
1 | Welcome!
2 |
3 | This is an MyBatis Migration repository. You can specify the repository
4 | directory when running migrations using the --path=Evolving databases has been one of the major challenges for software development. Often times, regardless of 30 | our software development methodology, the database follows a different change management process. Despite our best 31 | efforts, few tools and practices have been able to change that. The tools of the past have been GUI centric, 32 | proprietary for a particular database and/or carried a steep license cost. Yet, at the end of the day they suffered 33 | from the same challenges.
34 |Recently, a few tools arrived and changed all of that. They did so by embracing simplicity and a few simple 35 | rules for database evolution to follow. A couple of good examples are Rails Migrations and dbdeploy. Both tools are 36 | similar in purpose, but quite different in implementation. The MyBatis Schema Migration System draws from both and 37 | seeks to be the best migration tool of its kind.
38 | 39 |To achieve a good database change management practice, we need to identify a few key goals.
41 |Thus, the MyBatis Schema Migration System (or MyBatis Migrations for short) seeks to:
42 |To put it in short. Have a look at the video:
57 | 58 |The redo command is a shortcut which internally executes a down command and up command. As it executes the same number of steps for both down and up operation, the final migration status does not change.
30 | The redo command is useful for testing undo part of scripts or re-applying recent migration scripts after edit.
The redo command takes an integer parameter which indicates the number of migrations to redo. No parameter means 1.
33 | 34 |The redo command was added in version 3.3.10.
35 |Any of the commands can be executed with only the first few (unambiguous) characters of their name.
30 | 31 |For example, the status
command can be shortened to:
Or even just:
36 | 37 |If you script migrations using unix shell scripts or Windows batch files, be sure to always use the full name 40 | for safety. That way, if the shortcut becomes ambiguous in the future, your script will still function.
41 |The status command will report the current state of the database.
30 | The status command takes no parameters and operates on the current working directory or that specified by the
31 | --path
option (as with all other commands).
Since we’ve never run a migration, the status of all of the existing migration scripts is pending, 40 | including the changelog table itself, which is where more detailed status logs are kept. Once we run the up 41 | command (discussed next), the status will report something like the following:
42 | 43 |Thanks to our identifier format, things are in order, and we can see when a migration script was created, as 50 | well as when it was applied. The comment helps us read a high level overview of the evolution of this database. 51 | As we add migrations this status log will grow. For example:
52 | 53 |You can also get this information from the changelog table by querying it directly in the database. 62 | Of course, you won’t see any "pending" items, as those are only known to the migration repository until they're 63 | applied to the database.
64 |The up
and down
commands are pretty prescriptive in how they work.
30 | The up command evolves all the way up, and down only devolves one step down. Sometimes that might be
31 | limiting, so the version command exists to allow you to migrate the schema to any specific version of the database
32 | you like. You simply call it, specifying the version you’d like to end up at, and the migrations system figures out whether
33 | it has to go up or down, and which migrations it needs to run. Here’s an example.
The version command is a powerful utility for moving to a specific revision of the database.
74 |