Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions flyway-database-cubrid/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,36 @@
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.cubrid</groupId>
<artifactId>cubrid-jdbc</artifactId>
<version>11.3.2.0053</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.11.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.21.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>1.21.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.26.3</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand All @@ -55,6 +85,10 @@
<plugin>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.3.1</version>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
package org.flywaydb.community.database.cubrid;

import static org.assertj.core.api.Assertions.assertThat;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.flywaydb.core.Flyway;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;

@Testcontainers(disabledWithoutDocker = true)
class CubridSupportTest {
private static final int BROKER_PORT = 33000;
private static final String DATABASE_NAME = "cubrid";
private static final String USER_SCHEMA = "public";
private static final String INITIAL_MIGRATION_LOCATION = "cubrid_initial_migration";
private static final String NEXT_MIGRATION_LOCATION = "cubrid_next_migration";

@Container
static final GenericContainer<?> cubrid = new GenericContainer<>(DockerImageName.parse("cubrid/cubrid:11.4"))
.withEnv("CUBRID_DB", DATABASE_NAME)
.withExposedPorts(BROKER_PORT)
.waitingFor(Wait.forListeningPort().withStartupTimeout(Duration.ofMinutes(3)));

@BeforeAll
static void waitUntilJdbcIsReady() throws Exception {
long deadline = System.nanoTime() + Duration.ofMinutes(2).toNanos();
Exception lastFailure = null;

while (System.nanoTime() < deadline) {
try (Connection connection = connection();
Statement statement = connection.createStatement()) {
statement.execute("SELECT 1");
return;
} catch (Exception e) {
lastFailure = e;
Thread.sleep(1_000);
}
}

if (lastFailure != null) {
throw lastFailure;
}
throw new IllegalStateException("CUBRID JDBC endpoint was not ready");
}

@BeforeEach
void resetDatabase() throws SQLException {
try (Connection connection = connection();
Statement statement = connection.createStatement()) {
statement.execute("DROP TABLE IF EXISTS app_user");
statement.execute("DROP TABLE IF EXISTS flyway_schema_history");
}
}

@Test
void migrates() throws SQLException {
Flyway flyway = flyway(INITIAL_MIGRATION_LOCATION);

assertThat(tableNames()).doesNotContain("app_user", "flyway_schema_history");

flyway.migrate();

assertThat(tableNames()).contains("app_user", "flyway_schema_history");
assertThat(countAppUserRows()).isEqualTo(2);
assertThat(historyDescriptions()).containsExactly("create app user", "insert app users");
}

@Test
void doesNotApplyMigrationSeveralTimes() throws SQLException {
Flyway flyway = flyway(INITIAL_MIGRATION_LOCATION);

flyway.migrate();
flyway.migrate();
flyway.migrate();

assertThat(countAppUserRows()).isEqualTo(2);
assertThat(historyDescriptions()).containsExactly("create app user", "insert app users");
}

@Test
void appliesOnlyNewMigrationsWhenSomeWereAlreadyApplied() throws SQLException {
flyway(INITIAL_MIGRATION_LOCATION).migrate();

assertThat(countAppUserRows()).isEqualTo(2);
assertThat(historyDescriptions()).containsExactly("create app user", "insert app users");

flyway(INITIAL_MIGRATION_LOCATION, NEXT_MIGRATION_LOCATION).migrate();

assertThat(countAppUserRows()).isEqualTo(3);
assertThat(historyDescriptions()).containsExactly("create app user", "insert app users", "insert more app users");
}

@Test
void validatesAppliedMigrations() {
Flyway flyway = flyway(INITIAL_MIGRATION_LOCATION);

flyway.migrate();

flyway.validate();
}

@Test
void setsBaseline() throws SQLException {
Flyway flyway = Flyway.configure()
.communityDBSupportEnabled(true)
.dataSource(jdbcUrl(), USER_SCHEMA, "")
.defaultSchema(USER_SCHEMA)
.locations(INITIAL_MIGRATION_LOCATION)
.baselineVersion("123")
.load();

flyway.baseline();

assertThat(tableNames()).contains("flyway_schema_history");
assertThat(historyDescriptions()).containsExactly("<< Flyway Baseline >>");
}

@Test
void cleansUserTables() throws SQLException {
Flyway flyway = Flyway.configure()
.communityDBSupportEnabled(true)
.dataSource(jdbcUrl(), USER_SCHEMA, "")
.defaultSchema(USER_SCHEMA)
.locations(INITIAL_MIGRATION_LOCATION)
.cleanDisabled(false)
.load();

flyway.migrate();
assertThat(tableNames()).contains("app_user", "flyway_schema_history");

flyway.clean();

assertThat(tableNames()).doesNotContain("app_user", "flyway_schema_history");
}

private static Flyway flyway(String... locations) {
return Flyway.configure()
.communityDBSupportEnabled(true)
.dataSource(jdbcUrl(), USER_SCHEMA, "")
.defaultSchema(USER_SCHEMA)
.locations(locations)
.load();
}

private static Connection connection() throws SQLException {
return DriverManager.getConnection(jdbcUrl(), USER_SCHEMA, "");
}

private static String jdbcUrl() {
return "jdbc:cubrid:" + cubrid.getHost() + ":" + cubrid.getMappedPort(BROKER_PORT) + ":" + DATABASE_NAME + ":::";
}

private static Set<String> tableNames() throws SQLException {
return Set.copyOf(queryForStrings(
"SELECT class_name FROM db_class WHERE class_type = 'CLASS' AND is_system_class = 'NO'"
));
}

private static List<String> historyDescriptions() throws SQLException {
return queryForStrings(
"SELECT description FROM flyway_schema_history ORDER BY installed_rank"
);
}

private static int countAppUserRows() throws SQLException {
try (Connection connection = connection();
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT COUNT(*) FROM app_user")) {
resultSet.next();
return resultSet.getInt(1);
}
}

private static List<String> queryForStrings(String sql) throws SQLException {
try (Connection connection = connection();
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql)) {
List<String> results = new ArrayList<>();
while (resultSet.next()) {
results.add(resultSet.getString(1));
}
return results;
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CREATE TABLE app_user (
id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
INSERT INTO app_user(id, name) VALUES (1, 'alice');
INSERT INTO app_user(id, name) VALUES (2, 'bob');
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
INSERT INTO app_user(id, name) VALUES (3, 'carol');
Loading