Skip to content

Commit 2a1e5eb

Browse files
authored
Merge pull request #138 from ebean-orm/feature/read-idx-files
Read idx migrations (index) files and support GraalVM native image,
2 parents e998a87 + f0ed71c commit 2a1e5eb

File tree

17 files changed

+286
-12
lines changed

17 files changed

+286
-12
lines changed

ebean-migration/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ mvn install:install-file -Dfile=/some/path/to/ojdbc7.jar -DgroupId=oracle \
135135

136136
<dependency>
137137
<groupId>io.ebean</groupId>
138-
<artifactId>ebean-test-docker</artifactId>
139-
<version>5.4</version>
138+
<artifactId>ebean-test-containers</artifactId>
139+
<version>7.1</version>
140140
<scope>test</scope>
141141
</dependency>
142142

ebean-migration/src/main/java/io/ebean/migration/MigrationConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ public void setName(String name) {
549549
* Return the base platform that was set.
550550
*/
551551
public String getBasePlatform() {
552-
return basePlatform;
552+
return basePlatform != null ? basePlatform : platform;
553553
}
554554

555555
/**

ebean-migration/src/main/java/io/ebean/migration/MigrationVersion.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ public static String trim(String raw) {
190190
* Parse the raw version string into a MigrationVersion.
191191
*/
192192
public static MigrationVersion parse(String raw) {
193+
if (raw.endsWith(".sql")) {
194+
raw = raw.substring(0, raw.length() - 4);
195+
}
193196
if (raw.startsWith("V") || raw.startsWith("v")) {
194197
raw = raw.substring(1);
195198
}

ebean-migration/src/main/java/io/ebean/migration/runner/LocalMigrationResources.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import io.ebean.migration.MigrationConfig;
77
import io.ebean.migration.MigrationVersion;
88

9+
import java.io.*;
10+
import java.net.URL;
911
import java.util.ArrayList;
1012
import java.util.Collections;
1113
import java.util.List;
@@ -45,9 +47,60 @@ boolean readInitResources() {
4547
* Read all the migration resources (SQL scripts) returning true if there are versions.
4648
*/
4749
boolean readResources() {
50+
if (readFromIndex()) {
51+
return true;
52+
}
4853
return readResourcesForPath(migrationConfig.getMigrationPath());
4954
}
5055

56+
private boolean readFromIndex() {
57+
final var base = "/" + migrationConfig.getMigrationPath() + "/";
58+
final var basePlatform = migrationConfig.getBasePlatform();
59+
final var indexName = "idx_" + basePlatform + ".migrations";
60+
URL idx = resource(base + indexName);
61+
if (idx != null) {
62+
return loadFromIndexFile(idx, base);
63+
}
64+
idx = resource(base + basePlatform + '/' + indexName);
65+
if (idx != null) {
66+
return loadFromIndexFile(idx, base + basePlatform + '/');
67+
}
68+
final var platform = migrationConfig.getPlatform();
69+
idx = resource(base + platform + indexName);
70+
if (idx != null) {
71+
return loadFromIndexFile(idx, base + platform + '/');
72+
}
73+
return false;
74+
}
75+
76+
private URL resource(String base) {
77+
return LocalMigrationResources.class.getResource(base);
78+
}
79+
80+
private boolean loadFromIndexFile(URL idx, String base) {
81+
try (var reader = new LineNumberReader(new InputStreamReader(idx.openStream()))) {
82+
String line;
83+
while ((line = reader.readLine()) != null) {
84+
if (!line.isEmpty()) {
85+
final String[] pair = line.split(",");
86+
if (pair.length == 2) {
87+
final var checksum = Integer.parseInt(pair[0]);
88+
final var location = pair[1].trim();
89+
final String substring = location.substring(0, location.length() - 4);
90+
final var version = MigrationVersion.parse(substring);
91+
final var url = resource(base + location);
92+
versions.add(new LocalUriMigrationResource(version, location, url, checksum));
93+
}
94+
}
95+
}
96+
97+
return !versions.isEmpty();
98+
99+
} catch (IOException e) {
100+
throw new UncheckedIOException("Error reading idx file", e);
101+
}
102+
}
103+
51104
private boolean readResourcesForPath(String path) {
52105
// try to load from base platform first
53106
final String basePlatform = migrationConfig.getBasePlatform();
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package io.ebean.migration.runner;
2+
3+
import io.ebean.migration.MigrationVersion;
4+
5+
import java.io.IOException;
6+
import java.io.InputStreamReader;
7+
import java.io.StringWriter;
8+
import java.net.URL;
9+
10+
/**
11+
* A local URL based DB migration resource.
12+
*/
13+
final class LocalUriMigrationResource extends LocalMigrationResource {
14+
15+
private final URL resource;
16+
private final int checksum;
17+
18+
LocalUriMigrationResource(MigrationVersion version, String location, URL resource, int checksum) {
19+
super(version, location);
20+
this.resource = resource;
21+
this.checksum = checksum;
22+
}
23+
24+
public int checksum() {
25+
return checksum;
26+
}
27+
28+
@Override
29+
public String content() {
30+
try (var reader = new InputStreamReader(resource.openStream())) {
31+
var writer = new StringWriter(1024);
32+
reader.transferTo(writer);
33+
return writer.toString();
34+
} catch (IOException e) {
35+
throw new IllegalStateException(missingOpensMessage(), e);
36+
}
37+
}
38+
39+
private String missingOpensMessage() {
40+
return "NPE reading DB migration content at [" + location + "] Probably missing an 'opens dbmigration;' in module-info.java";
41+
}
42+
}

ebean-migration/src/main/java/io/ebean/migration/runner/MigrationTable.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,10 @@ private boolean shouldRun(LocalMigrationResource localVersion, LocalMigrationRes
296296
private boolean runMigration(LocalMigrationResource local, MigrationMetaRow existing) throws SQLException {
297297
String script = null;
298298
int checksum;
299-
if (local instanceof LocalDdlMigrationResource) {
299+
if (local instanceof LocalUriMigrationResource) {
300+
script = convertScript(local.content());
301+
checksum = ((LocalUriMigrationResource)local).checksum();
302+
} else if (local instanceof LocalDdlMigrationResource) {
300303
script = convertScript(local.content());
301304
checksum = Checksum.calculate(script);
302305
} else {
@@ -402,13 +405,13 @@ private void executeMigration(LocalMigrationResource local, String script, int c
402405

403406
private long executeMigration(LocalMigrationResource local, String script) throws SQLException {
404407
long start = System.currentTimeMillis();
405-
if (local instanceof LocalDdlMigrationResource) {
406-
log.log(DEBUG, "run migration {0}", local.location());
407-
scriptRunner.runScript(script, "run migration version: " + local.version());
408-
} else {
408+
if (local instanceof LocalJdbcMigrationResource) {
409409
JdbcMigration migration = ((LocalJdbcMigrationResource) local).migration();
410410
log.log(INFO, "Executing jdbc migration version: {0} - {1}", local.version(), migration);
411411
migration.migrate(connection);
412+
} else {
413+
log.log(DEBUG, "run migration {0}", local.location());
414+
scriptRunner.runScript(script, "run migration version: " + local.version());
412415
}
413416
executionCount++;
414417
return System.currentTimeMillis() - start;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"resources": [
3+
{
4+
"pattern": ".*\\.sql"
5+
},
6+
{
7+
"pattern": ".*\\.migrations"
8+
}
9+
]
10+
}

ebean-migration/src/test/java/io/ebean/migration/MigrationRunner_platform_Test.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
package io.ebean.migration;
22

33
import io.ebean.ddlrunner.DdlRunner;
4-
import io.ebean.docker.commands.*;
5-
import io.ebean.docker.container.ContainerBuilderDb;
4+
import io.ebean.test.containers.*;
65
import org.junit.jupiter.api.Disabled;
76
import org.junit.jupiter.api.Test;
87

ebean-migration/src/test/java/io/ebean/migration/MigrationVersionTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,18 @@ void test_parse_when_v_prefix() {
108108
assertThat(version.type()).isEqualTo("V");
109109
}
110110

111+
@Test
112+
void test_parse_when_sql_suffix() {
113+
114+
MigrationVersion version = MigrationVersion.parse("v1_0__Foo.sql");
115+
assertThat(version.isRepeatable()).isFalse();
116+
assertThat(version.comment()).isEqualTo("Foo");
117+
assertThat(version.normalised()).isEqualTo("1.0");
118+
assertThat(version.asString()).isEqualTo("1_0");
119+
assertThat(version.raw()).isEqualTo("1_0__Foo");
120+
assertThat(version.type()).isEqualTo("V");
121+
}
122+
111123
@Test
112124
void repeatable_compareTo() {
113125

ebean-migration/src/test/java/io/ebean/migration/runner/MigrationTableAsyncTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import io.ebean.datasource.DataSourceConfig;
44
import io.ebean.datasource.DataSourceFactory;
55
import io.ebean.datasource.DataSourcePool;
6-
import io.ebean.docker.commands.*;
76
import io.ebean.migration.MigrationConfig;
87
import io.ebean.migration.MigrationRunner;
8+
import io.ebean.test.containers.*;
99
import org.junit.jupiter.api.AfterEach;
1010
import org.junit.jupiter.api.BeforeEach;
1111
import org.junit.jupiter.api.Disabled;

0 commit comments

Comments
 (0)