Skip to content

Commit d330ba8

Browse files
committed
#44 make flyway config snapshot completely mutable
1 parent c571a35 commit d330ba8

File tree

1 file changed

+88
-79
lines changed

1 file changed

+88
-79
lines changed

embedded-database-spring-test/src/main/java/io/zonky/test/db/flyway/FlywayConfigSnapshot.java

Lines changed: 88 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
package io.zonky.test.db.flyway;
22

3+
import com.google.common.collect.ImmutableList;
4+
import com.google.common.collect.ImmutableMap;
35
import org.flywaydb.core.Flyway;
46
import org.flywaydb.core.api.MigrationVersion;
57
import org.flywaydb.core.api.resolver.MigrationResolver;
8+
import org.springframework.test.util.ReflectionTestUtils;
69

710
import javax.sql.DataSource;
8-
import java.util.Arrays;
11+
import java.util.List;
912
import java.util.Map;
1013
import java.util.Objects;
1114

1215
import static org.springframework.test.util.ReflectionTestUtils.getField;
13-
import static org.springframework.test.util.ReflectionTestUtils.invokeMethod;
1416

1517
/**
16-
* Represents a snapshot of configuration parameters of a flyway instance.
17-
* It is necessary because of mutability of flyway instances.
18+
* Represents an <b>immutable</b> snapshot of Flyway's configuration.
19+
* It is required because the mutability of flyway instances.
1820
*/
1921
public class FlywayConfigSnapshot {
2022

@@ -29,21 +31,17 @@ public class FlywayConfigSnapshot {
2931
// included in equals and hashCode methods
3032
// but it will work only for empty arrays (that is common use-case)
3133
// because of missing equals and hashCode methods
32-
// on classes implementing these interfaces,
33-
// note the properties require special treatment suitable for arrays
34-
private final MigrationResolver[] resolvers;
35-
private final Object[] errorHandlers;
36-
37-
// included in equals and hashCode methods
38-
// but these properties require special treatment suitable for arrays
39-
private final Object[] locations;
40-
private final String[] schemas;
41-
private final String[] sqlMigrationSuffixes;
42-
private final String[] errorOverrides;
34+
// on classes implementing these interfaces
35+
private final List<MigrationResolver> resolvers;
36+
private final List<Object> errorHandlers;
4337

4438
// included in equals and hashCode methods
4539
private final MigrationVersion baselineVersion;
4640
private final MigrationVersion target;
41+
private final List<Object> locations;
42+
private final List<String> schemas;
43+
private final List<String> sqlMigrationSuffixes;
44+
private final List<String> errorOverrides;
4745
private final Map<String, String> placeholders;
4846
private final String table;
4947
private final String baselineDescription;
@@ -86,46 +84,46 @@ public FlywayConfigSnapshot(Flyway flyway) {
8684
config = flyway;
8785
}
8886

89-
this.classLoader = invokeMethod(config, "getClassLoader");
90-
this.dataSource = invokeMethod(config, "getDataSource");
91-
this.resolvers = invokeMethod(config, "getResolvers");
92-
this.callbacks = invokeMethod(config, "getCallbacks");
93-
this.sqlMigrationSeparator = invokeMethod(config, "getSqlMigrationSeparator");
94-
this.sqlMigrationPrefix = invokeMethod(config, "getSqlMigrationPrefix");
95-
this.placeholderSuffix = invokeMethod(config, "getPlaceholderSuffix");
96-
this.placeholderPrefix = invokeMethod(config, "getPlaceholderPrefix");
97-
this.placeholders = invokeMethod(config, "getPlaceholders");
98-
this.target = invokeMethod(config, "getTarget");
99-
this.table = invokeMethod(config, "getTable");
100-
this.schemas = invokeMethod(config, "getSchemas");
101-
this.encoding = invokeMethod(config, "getEncoding");
102-
this.locations = invokeMethod(config, "getLocations");
103-
this.outOfOrder = invokeMethod(config, "isOutOfOrder");
104-
this.validateOnMigrate = invokeMethod(config, "isValidateOnMigrate");
105-
this.cleanOnValidationError = invokeMethod(config, "isCleanOnValidationError");
87+
this.classLoader = getValue(config, "getClassLoader");
88+
this.dataSource = getValue(config, "getDataSource");
89+
this.resolvers = ImmutableList.copyOf(getArray(config, "getResolvers"));
90+
this.callbacks = getValue(config, "getCallbacks");
91+
this.sqlMigrationSeparator = getValue(config, "getSqlMigrationSeparator");
92+
this.sqlMigrationPrefix = getValue(config, "getSqlMigrationPrefix");
93+
this.placeholderSuffix = getValue(config, "getPlaceholderSuffix");
94+
this.placeholderPrefix = getValue(config, "getPlaceholderPrefix");
95+
this.placeholders = ImmutableMap.copyOf(getMap(config, "getPlaceholders"));
96+
this.target = getValue(config, "getTarget");
97+
this.table = getValue(config, "getTable");
98+
this.schemas = ImmutableList.copyOf(getArray(config, "getSchemas"));
99+
this.encoding = getValue(config, "getEncoding");
100+
this.locations = ImmutableList.copyOf(getArray(config, "getLocations"));
101+
this.outOfOrder = getValue(config, "isOutOfOrder");
102+
this.validateOnMigrate = getValue(config, "isValidateOnMigrate");
103+
this.cleanOnValidationError = getValue(config, "isCleanOnValidationError");
106104

107105
if (flywayVersion >= 31) {
108-
this.baselineVersion = invokeMethod(config, "getBaselineVersion");
109-
this.baselineDescription = invokeMethod(config, "getBaselineDescription");
110-
this.baselineOnMigrate = invokeMethod(config, "isBaselineOnMigrate");
106+
this.baselineVersion = getValue(config, "getBaselineVersion");
107+
this.baselineDescription = getValue(config, "getBaselineDescription");
108+
this.baselineOnMigrate = getValue(config, "isBaselineOnMigrate");
111109
} else {
112110
this.baselineVersion = null;
113111
this.baselineDescription = null;
114112
this.baselineOnMigrate = false;
115113
}
116114

117115
if (flywayVersion >= 32) {
118-
this.placeholderReplacement = invokeMethod(config, "isPlaceholderReplacement");
116+
this.placeholderReplacement = getValue(config, "isPlaceholderReplacement");
119117
} else {
120118
this.placeholderReplacement = true;
121119
}
122120

123121
if (flywayVersion >= 40) {
124-
this.skipDefaultResolvers = invokeMethod(config, "isSkipDefaultResolvers");
125-
this.skipDefaultCallbacks = invokeMethod(config, "isSkipDefaultCallbacks");
126-
this.repeatableSqlMigrationPrefix = invokeMethod(config, "getRepeatableSqlMigrationPrefix");
127-
this.ignoreFutureMigrations = invokeMethod(config, "isIgnoreFutureMigrations");
128-
this.cleanDisabled = invokeMethod(config, "isCleanDisabled");
122+
this.skipDefaultResolvers = getValue(config, "isSkipDefaultResolvers");
123+
this.skipDefaultCallbacks = getValue(config, "isSkipDefaultCallbacks");
124+
this.repeatableSqlMigrationPrefix = getValue(config, "getRepeatableSqlMigrationPrefix");
125+
this.ignoreFutureMigrations = getValue(config, "isIgnoreFutureMigrations");
126+
this.cleanDisabled = getValue(config, "isCleanDisabled");
129127
} else {
130128
this.skipDefaultResolvers = false;
131129
this.skipDefaultCallbacks = false;
@@ -135,79 +133,91 @@ public FlywayConfigSnapshot(Flyway flyway) {
135133
}
136134

137135
if (flywayVersion >= 41) {
138-
this.ignoreMissingMigrations = invokeMethod(config, "isIgnoreMissingMigrations");
139-
this.installedBy = invokeMethod(config, "getInstalledBy");
136+
this.ignoreMissingMigrations = getValue(config, "isIgnoreMissingMigrations");
137+
this.installedBy = getValue(config, "getInstalledBy");
140138
} else {
141139
this.ignoreMissingMigrations = false;
142140
this.installedBy = null;
143141
}
144142

145143
if (flywayVersion >= 41 && flywayVersion < 50) {
146-
this.allowMixedMigrations = invokeMethod(config, "isAllowMixedMigrations");
144+
this.allowMixedMigrations = getValue(config, "isAllowMixedMigrations");
147145
} else {
148146
this.allowMixedMigrations = false;
149147
}
150148

151149
if (flywayVersion >= 42) {
152-
this.mixed = invokeMethod(config, "isMixed");
153-
this.group = invokeMethod(config, "isGroup");
150+
this.mixed = getValue(config, "isMixed");
151+
this.group = getValue(config, "isGroup");
154152
} else {
155153
this.mixed = false;
156154
this.group = false;
157155
}
158156

159157
if (flywayVersion >= 50) {
160-
this.sqlMigrationSuffixes = invokeMethod(config, "getSqlMigrationSuffixes");
158+
this.sqlMigrationSuffixes = ImmutableList.copyOf(getArray(config, "getSqlMigrationSuffixes"));
161159
} else {
162-
String sqlMigrationSuffix = invokeMethod(config, "getSqlMigrationSuffix");
163-
this.sqlMigrationSuffixes = new String[] {sqlMigrationSuffix};
160+
String sqlMigrationSuffix = getValue(config, "getSqlMigrationSuffix");
161+
this.sqlMigrationSuffixes = ImmutableList.of(sqlMigrationSuffix);
164162
}
165163

166164
if (flywayVersion >= 50 && isFlywayPro) {
167-
this.undoSqlMigrationPrefix = invokeMethod(config, "getUndoSqlMigrationPrefix");
168-
this.errorHandlers = invokeMethod(config, "getErrorHandlers");
169-
this.dryRun = invokeMethod(config, "getDryRunOutput") != null;
165+
this.undoSqlMigrationPrefix = getValue(config, "getUndoSqlMigrationPrefix");
166+
this.errorHandlers = ImmutableList.copyOf(getArray(config, "getErrorHandlers"));
167+
this.dryRun = getValue(config, "getDryRunOutput") != null;
170168
} else {
171169
this.undoSqlMigrationPrefix = null;
172-
this.errorHandlers = null;
170+
this.errorHandlers = ImmutableList.of();
173171
this.dryRun = false;
174172
}
175173

176174
if (flywayVersion >= 51) {
177-
this.ignoreIgnoredMigrations = invokeMethod(config, "isIgnoreIgnoredMigrations");
175+
this.ignoreIgnoredMigrations = getValue(config, "isIgnoreIgnoredMigrations");
178176
} else {
179177
this.ignoreIgnoredMigrations = false;
180178
}
181179

182180
if (flywayVersion >= 51 && isFlywayPro) {
183-
this.errorOverrides = invokeMethod(config, "getErrorOverrides");
184-
this.stream = invokeMethod(config, "isStream");
185-
this.batch = invokeMethod(config, "isBatch");
186-
this.oracleSqlPlus = invokeMethod(config, "isOracleSqlplus");
181+
this.errorOverrides = ImmutableList.copyOf(getArray(config, "getErrorOverrides"));
182+
this.stream = getValue(config, "isStream");
183+
this.batch = getValue(config, "isBatch");
184+
this.oracleSqlPlus = getValue(config, "isOracleSqlplus");
187185
} else {
188-
this.errorOverrides = null;
186+
this.errorOverrides = ImmutableList.of();
189187
this.stream = false;
190188
this.batch = false;
191189
this.oracleSqlPlus = false;
192190
}
193191

194192
if (flywayVersion >= 52) {
195-
this.ignorePendingMigrations = invokeMethod(config, "isIgnorePendingMigrations");
196-
this.connectRetries = invokeMethod(config, "getConnectRetries");
197-
this.initSql = invokeMethod(config, "getInitSql");
193+
this.ignorePendingMigrations = getValue(config, "isIgnorePendingMigrations");
194+
this.connectRetries = getValue(config, "getConnectRetries");
195+
this.initSql = getValue(config, "getInitSql");
198196
} else {
199197
this.ignorePendingMigrations = false;
200198
this.connectRetries = 0;
201199
this.initSql = null;
202200
}
203201

204202
if (flywayVersion >= 52 && isFlywayPro) {
205-
this.licenseKey = invokeMethod(config, "getLicenseKey");
203+
this.licenseKey = getValue(config, "getLicenseKey");
206204
} else {
207205
this.licenseKey = null;
208206
}
209207
}
210208

209+
private static <T> T getValue(Object target, String method) {
210+
return ReflectionTestUtils.invokeMethod(target, method);
211+
}
212+
213+
private static <E> E[] getArray(Object target, String method) {
214+
return ReflectionTestUtils.invokeMethod(target, method);
215+
}
216+
217+
private static <K, V> Map<K, V> getMap(Object target, String method) {
218+
return ReflectionTestUtils.invokeMethod(target, method);
219+
}
220+
211221
public ClassLoader getClassLoader() {
212222
return classLoader;
213223
}
@@ -224,7 +234,7 @@ public String getBaselineDescription() {
224234
return baselineDescription;
225235
}
226236

227-
public MigrationResolver[] getResolvers() {
237+
public List<MigrationResolver> getResolvers() {
228238
return resolvers;
229239
}
230240

@@ -240,7 +250,7 @@ public boolean isSkipDefaultCallbacks() {
240250
return skipDefaultCallbacks;
241251
}
242252

243-
public String[] getSqlMigrationSuffixes() {
253+
public List<String> getSqlMigrationSuffixes() {
244254
return sqlMigrationSuffixes;
245255
}
246256

@@ -284,7 +294,7 @@ public String getTable() {
284294
return table;
285295
}
286296

287-
public String[] getSchemas() {
297+
public List<String> getSchemas() {
288298
return schemas;
289299
}
290300

@@ -300,7 +310,7 @@ public String getLicenseKey() {
300310
return licenseKey;
301311
}
302312

303-
public Object[] getLocations() {
313+
public List<Object> getLocations() {
304314
return locations;
305315
}
306316

@@ -356,11 +366,11 @@ public String getInstalledBy() {
356366
return installedBy;
357367
}
358368

359-
public Object[] getErrorHandlers() {
369+
public List<Object> getErrorHandlers() {
360370
return errorHandlers;
361371
}
362372

363-
public String[] getErrorOverrides() {
373+
public List<String> getErrorOverrides() {
364374
return errorOverrides;
365375
}
366376

@@ -409,14 +419,14 @@ public boolean equals(Object o) {
409419
batch == that.batch &&
410420
oracleSqlPlus == that.oracleSqlPlus &&
411421
connectRetries == that.connectRetries &&
412-
Arrays.equals(resolvers, that.resolvers) &&
413-
Arrays.equals(errorHandlers, that.errorHandlers) &&
414-
Arrays.equals(locations, that.locations) &&
415-
Arrays.equals(schemas, that.schemas) &&
416-
Arrays.equals(sqlMigrationSuffixes, that.sqlMigrationSuffixes) &&
417-
Arrays.equals(errorOverrides, that.errorOverrides) &&
422+
Objects.equals(resolvers, that.resolvers) &&
423+
Objects.equals(errorHandlers, that.errorHandlers) &&
418424
Objects.equals(baselineVersion, that.baselineVersion) &&
419425
Objects.equals(target, that.target) &&
426+
Objects.equals(locations, that.locations) &&
427+
Objects.equals(schemas, that.schemas) &&
428+
Objects.equals(sqlMigrationSuffixes, that.sqlMigrationSuffixes) &&
429+
Objects.equals(errorOverrides, that.errorOverrides) &&
420430
Objects.equals(placeholders, that.placeholders) &&
421431
Objects.equals(table, that.table) &&
422432
Objects.equals(baselineDescription, that.baselineDescription) &&
@@ -435,10 +445,9 @@ public boolean equals(Object o) {
435445
@Override
436446
public int hashCode() {
437447
return Objects.hash(
438-
Arrays.hashCode(resolvers), Arrays.hashCode(errorHandlers),
439-
Arrays.hashCode(locations), Arrays.hashCode(schemas),
440-
Arrays.hashCode(sqlMigrationSuffixes), Arrays.hashCode(errorOverrides),
441-
baselineVersion, target, placeholders, table, baselineDescription,
448+
resolvers, errorHandlers,
449+
baselineVersion, target, locations, schemas, sqlMigrationSuffixes,
450+
errorOverrides, placeholders, table, baselineDescription,
442451
undoSqlMigrationPrefix, repeatableSqlMigrationPrefix,
443452
sqlMigrationSeparator, sqlMigrationPrefix, placeholderPrefix,
444453
placeholderSuffix, encoding, initSql, licenseKey,

0 commit comments

Comments
 (0)