diff --git a/pom.xml b/pom.xml index df1c4ac..4326d63 100644 --- a/pom.xml +++ b/pom.xml @@ -99,6 +99,14 @@ true + + io.ebean + ebean + 17.0.0-RC2 + provided + true + + io.avaje junit diff --git a/src/main/java/io/ebean/test/containers/BaseDbBuilder.java b/src/main/java/io/ebean/test/containers/BaseDbBuilder.java index d982da9..b0b92ea 100644 --- a/src/main/java/io/ebean/test/containers/BaseDbBuilder.java +++ b/src/main/java/io/ebean/test/containers/BaseDbBuilder.java @@ -478,11 +478,21 @@ public String getExtraDbUser() { return extraDbUser; } + @Override + public String getExtraDbUserWithDefault() { + return extraDbUser != null ? extraDbUser : extraDb; + } + @Override public String getExtraDbPassword() { return extraDbPassword; } + @Override + public String getExtraDbPasswordWithDefault() { + return extraDbPassword != null ? extraDbPassword : password; + } + @Override public String getExtraDbExtensions() { return extraDbExtensions; diff --git a/src/main/java/io/ebean/test/containers/BasePostgresContainer.java b/src/main/java/io/ebean/test/containers/BasePostgresContainer.java index 6e7bbac..bcd79c9 100644 --- a/src/main/java/io/ebean/test/containers/BasePostgresContainer.java +++ b/src/main/java/io/ebean/test/containers/BasePostgresContainer.java @@ -58,7 +58,7 @@ private void createExtraDb(Connection connection, boolean withDrop) { dropDatabaseIfExists(connection, extraDb); dropRoleIfExists(connection, extraUser); } - createRole(connection, extraUser, getWithDefault(dbConfig.getExtraDbPassword(), dbConfig.getPassword())); + createRole(connection, extraUser, dbConfig.getExtraDbPasswordWithDefault()); if (databaseNotExists(connection, extraDb)) { createExtraDatabase(connection, extraDb, extraUser); } @@ -127,7 +127,7 @@ private void addExtensions(String dbExtensions, String jdbcUrl) { * Additionally we don't create an extra user IF it is the same as the main db user. */ private String getExtraDbUser() { - String extraUser = getWithDefault(dbConfig.getExtraDbUser(), dbConfig.getExtraDb()); + String extraUser = dbConfig.getExtraDbUserWithDefault(); return extraUser != null && !extraUser.equals(dbConfig.getUsername()) ? extraUser : null; } @@ -147,10 +147,6 @@ private ProcessBuilder sqlFileProcess(String dbUser, String dbName, String conta return createProcessBuilder(args); } - private String getWithDefault(String value, String defaultValue) { - return value == null ? defaultValue : value; - } - private List parseExtensions(String dbExtn) { return TrimSplit.split(dbExtn); } diff --git a/src/main/java/io/ebean/test/containers/DbContainer.java b/src/main/java/io/ebean/test/containers/DbContainer.java index 497c77d..23b8eac 100644 --- a/src/main/java/io/ebean/test/containers/DbContainer.java +++ b/src/main/java/io/ebean/test/containers/DbContainer.java @@ -107,6 +107,14 @@ public boolean startContainerOnly() { return true; } + /** + * Return the Ebean SDK to obtain Ebean Database and Ebean DataSource builders + * for the underlying container. + */ + public EbeanSDK ebean() { + return new EbeanAdapter(dbConfig); + } + /** * If we are using FastStartMode just check is the DB exists and if so assume it is all created correctly. *

diff --git a/src/main/java/io/ebean/test/containers/EbeanAdapter.java b/src/main/java/io/ebean/test/containers/EbeanAdapter.java new file mode 100644 index 0000000..b8496f0 --- /dev/null +++ b/src/main/java/io/ebean/test/containers/EbeanAdapter.java @@ -0,0 +1,48 @@ +package io.ebean.test.containers; + +final class EbeanAdapter implements EbeanSDK { + + private final InternalConfigDb dbConfig; + + EbeanAdapter(InternalConfigDb dbConfig) { + this.dbConfig = dbConfig; + } + + @Override + public io.ebean.DatabaseBuilder builder() { + return io.ebean.Database.builder() + .dataSourceBuilder(dataSourceBuilder()) + .name(dbConfig.getDbName()) + .register(false) + .ddlGenerate(true) + .ddlRun(true); + } + + + @Override + public io.ebean.datasource.DataSourceBuilder dataSourceBuilder() { + return io.ebean.datasource.DataSourceBuilder.create() + .url(dbConfig.jdbcUrl()) + .username(dbConfig.getUsername()) + .password(dbConfig.getPassword()); + } + + + @Override + public io.ebean.datasource.DataSourceBuilder extraDataSourceBuilder() { + return io.ebean.datasource.DataSourceBuilder.create() + .url(dbConfig.jdbcExtraUrl()) + .username(dbConfig.getExtraDbUserWithDefault()) + .password(dbConfig.getExtraDbPasswordWithDefault()); + } + + @Override + public io.ebean.DatabaseBuilder extraDatabaseBuilder() { + return io.ebean.Database.builder() + .dataSourceBuilder(extraDataSourceBuilder()) + .name(dbConfig.getExtraDb()) + .defaultDatabase(false) + .register(false); + } + +} diff --git a/src/main/java/io/ebean/test/containers/EbeanSDK.java b/src/main/java/io/ebean/test/containers/EbeanSDK.java new file mode 100644 index 0000000..5b68a91 --- /dev/null +++ b/src/main/java/io/ebean/test/containers/EbeanSDK.java @@ -0,0 +1,43 @@ +package io.ebean.test.containers; + +/** + * Ebean SDK extension to create builders for Ebean Database and DataSource. + *

{@code
+ *
+ *  PostgresContainer container = PostgresContainer.builder("15")
+ *    .dbName("my_test")
+ *    .build()
+ *    .start();
+ *
+ *  io.ebean.Database ebean = container.ebean().builder().build();
+ *  // create ebean database and use it
+ *
+ * }
+ */ +public interface EbeanSDK { + + /** + * Return an ebean Database builder for the underlying database (url, username, password). + *

+ * The name of the ebean database will be dbName set for the container. + *

+ * This builder will have ddlGenerate set to true and ddlRun set to true. Alternatively, + * set runMigrations(true) to run database migrations on startup. + */ + io.ebean.DatabaseBuilder builder(); + + /** + * Return a java.sql.DataSource builder for the underlying database (url, username, password). + */ + io.ebean.datasource.DataSourceBuilder dataSourceBuilder(); + + /** + * Return a java.sql.DataSource builder for the underlying database (url, username, password). + */ + io.ebean.datasource.DataSourceBuilder extraDataSourceBuilder(); + + /** + * Return an ebean Database builder for the EXTRA database (extraUrl, extraDbUser, extraDbPassword). + */ + io.ebean.DatabaseBuilder extraDatabaseBuilder(); +} diff --git a/src/main/java/io/ebean/test/containers/InternalConfigDb.java b/src/main/java/io/ebean/test/containers/InternalConfigDb.java index 2dbedac..7045166 100644 --- a/src/main/java/io/ebean/test/containers/InternalConfigDb.java +++ b/src/main/java/io/ebean/test/containers/InternalConfigDb.java @@ -30,8 +30,12 @@ interface InternalConfigDb extends InternalConfig { String getExtraDbUser(); + String getExtraDbUserWithDefault(); + String getExtraDbPassword(); + String getExtraDbPasswordWithDefault(); + String getExtraDbExtensions(); String getExtraDbInitSqlFile(); diff --git a/src/main/java/io/ebean/test/containers/PostgresContainer.java b/src/main/java/io/ebean/test/containers/PostgresContainer.java index 7521432..4418131 100644 --- a/src/main/java/io/ebean/test/containers/PostgresContainer.java +++ b/src/main/java/io/ebean/test/containers/PostgresContainer.java @@ -1,7 +1,15 @@ package io.ebean.test.containers; /** - * Commands for controlling a postgres docker container. + * Run a postgres docker container for testing purposes. + *

{@code
+ *
+ *     PostgresContainer container = PostgresContainer.builder("15")
+ *       .dbName("my_test")
+ *       .build()
+ *       .start();
+ *
+ * }
*/ public class PostgresContainer extends BasePostgresContainer { @@ -13,6 +21,15 @@ public PostgresContainer start() { /** * Create a builder for PostgresContainer. + * + *
{@code
+   *
+   *     PostgresContainer container = PostgresContainer.builder("15")
+   *       .dbName("my_test")
+   *       .build()
+   *       .start();
+   *
+   * }
*/ public static Builder builder(String version) { return new Builder(version); diff --git a/src/test/java/io/ebean/test/containers/PostgisContainerTest.java b/src/test/java/io/ebean/test/containers/PostgisContainerTest.java index 4342e46..550cc7b 100644 --- a/src/test/java/io/ebean/test/containers/PostgisContainerTest.java +++ b/src/test/java/io/ebean/test/containers/PostgisContainerTest.java @@ -1,5 +1,7 @@ package io.ebean.test.containers; +import io.ebean.Database; +import io.ebean.datasource.DataSourcePool; import org.junit.jupiter.api.Test; import java.sql.Connection; @@ -11,7 +13,7 @@ class PostgisContainerTest { @Test - void extraDb() { + void extraDb() throws java.sql.SQLException { PostgisContainer container = PostgisContainer.builder("15") .port(0) .extraDb("myextra") @@ -26,6 +28,19 @@ void extraDb() { String jdbcUrl = container.config().jdbcUrl(); assertThat(jdbcUrl).contains(":" + containerConfig.port()); runSomeSql(container); + + DataSourcePool dataSource = container.ebean().dataSourceBuilder().build(); + try (Connection connection = dataSource.getConnection()) { + exeSql(connection, "insert into test_junk2 (acol) values (44)"); + } + dataSource.shutdown(); + + Database ebean = container.ebean().builder().build(); + ebean.sqlUpdate("insert into test_junk2 (acol) values (?)") + .setParameter(45) + .execute(); + + ebean.shutdown(); } private void runSomeSql(PostgisContainer container) { @@ -39,9 +54,9 @@ private void runSomeSql(PostgisContainer container) { } } - private void exeSql(Connection connection, String sql) throws SQLException { - PreparedStatement st = connection.prepareStatement(sql); - st.execute(); - st.close(); + private static void exeSql(Connection connection, String sql) throws SQLException { + try (PreparedStatement st = connection.prepareStatement(sql)) { + st.execute(); + } } } diff --git a/src/test/java/io/ebean/test/containers/PostgresContainerTest.java b/src/test/java/io/ebean/test/containers/PostgresContainerTest.java index 0cb3656..bfb49db 100644 --- a/src/test/java/io/ebean/test/containers/PostgresContainerTest.java +++ b/src/test/java/io/ebean/test/containers/PostgresContainerTest.java @@ -1,6 +1,8 @@ package io.ebean.test.containers; import io.avaje.applog.AppLog; +import io.ebean.Database; +import io.ebean.datasource.DataSourcePool; import org.junit.jupiter.api.Test; import java.sql.Connection; @@ -60,8 +62,10 @@ void randomPort() { @Test void defaultPort() { PostgresContainer container = PostgresContainer.builder("15") + .dbName("my_test") .extensions("hstore") - .build(); + .build() + .start(); container.startMaybe(); runSomeSql(container); @@ -141,8 +145,30 @@ void start() throws SQLException, InterruptedException { exeSql(connection, "drop table if exists test_doesnotexist"); } - final String url = container.jdbcUrl(); - assertEquals(url, "jdbc:postgresql://localhost:9828/main_db"); + assertEquals("jdbc:postgresql://localhost:9828/main_db", container.jdbcUrl()); + + Database ebean = container.ebean().builder().build(); + ebean.sqlUpdate("insert into foo_main (mcol) values (?)") + .setParameter(2) + .execute(); + + Database extraEbean = container.ebean().extraDatabaseBuilder().build(); + extraEbean.sqlUpdate("insert into foo_extra (acol) values (?)") + .setParameter(2) + .execute(); + + DataSourcePool dataSource = container.ebean().dataSourceBuilder().build(); + try (Connection connection = dataSource.getConnection()) { + exeSql(connection, "insert into foo_main (mcol) values (1)"); + } + dataSource.shutdown(); + + DataSourcePool extraDataSource = container.ebean().extraDataSourceBuilder().build(); + try (Connection connection = extraDataSource.getConnection()) { + exeSql(connection, "insert into foo_extra (acol) values (1)"); + } + extraDataSource.shutdown(); + container.stopRemove(); log.log(INFO, "start() finished"); }