diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml
index d80a583..147c58e 100644
--- a/.github/workflows/verify.yml
+++ b/.github/workflows/verify.yml
@@ -1,4 +1,4 @@
-name: verify
+name: 'build test'
on: [pull_request, push]
@@ -8,22 +8,14 @@ jobs:
steps:
- name: Checkout...
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Set up JDK...
- uses: actions/setup-java@v1
+ uses: actions/setup-java@v4
with:
- java-version: 17
+ java-version: 11
+ distribution: 'temurin'
+ cache: 'maven'
- - name: Retrieve mvn repo cache...
- uses: actions/cache@v2
- with:
- path: ~/.m2/repository
- key: maven-${{ runner.os }}-${{ hashFiles('**/pom.xml') }}
- restore-keys: maven-${{ runner.os }}
-
- - name: App - Build and test...
- run: cd jdbc-app-demo/ && mvn verify
-
- - name: Tests - Build and test...
- run: cd jdbc-test-demo-inmemory-db/ && mvn verify
\ No newline at end of file
+ - name: Build and test...
+ run: mvn -ntp clean verify
\ No newline at end of file
diff --git a/README.md b/README.md
index 89544c6..0552365 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,90 @@
[](https://github.com/bootique-examples/bootique-jdbc-demo/actions/workflows/verify.yml)
-# bootique-jdbc-demo
-Contains two examples of [bootique-jdbc](https://github.com/bootique/bootique-jdbc) use:
+# Bootique 3.x REST Demo
-* [jdbc-app-demo](https://github.com/bootique-examples/bootique-jdbc-demo/tree/master/jdbc-app-demo) - core JDBC API
-* [jdbc-test-demo-inmemory-db](https://github.com/bootique-examples/bootique-jdbc-demo/tree/master/jdbc-test-demo-inmemory-db) - JUnit 5 tests using Derby in-memory DB
-* TODO: testcontainers demo
+This is an example [Bootique](http://bootique.io) JDBC app. It shows how to define and use a named DataSource,
+and how to write DB-aware unit tests with Bootique and Testcontainers.
-For the examples working with the older versions of Bootique check the code on the branches:
+Different Git branches contain demo code for different versions of Bootique:
-* [1.x](https://github.com/bootique-examples/bootique-jdbc-demo/tree/1.x)
+* [3.x](https://github.com/bootique-examples/bootique-jdbc-demo/tree/3.x)
* [2.x](https://github.com/bootique-examples/bootique-jdbc-demo/tree/2.x)
+* [1.x](https://github.com/bootique-examples/bootique-jdbc-demo/tree/1.x)
+
+## Prerequisites
+
+To build and run the demo, ensure you have the following installed on your machine:
+
+* Docker
+* Java 11 or newer
+* Maven
+
+and then follow these steps:
+
+## Checkout
+```
+git clone git@github.com:bootique-examples/bootique-jdbc-demo.git
+cd bootique-jdbc-demo
+```
+
+## Start Postgres DB Locally
+
+This starts a Postgres instance listening on port 15432, with login credentials of `postgres` / `test`, and
+creates a simple test schema:
+
+```bash
+docker-compose -f docker-compose.yml up -d
+```
+
+## Build, test and package
+
+Run the following command to build the code, run the tests and package the app:
+```
+mvn clean package
+```
+This project uses a [runnable jar with lib folder](https://bootique.io/docs/3.x/bootique-docs/#runnable-jar-with-lib)
+packaging recipe, so now the app is packaged for distribution as `target/bootique-jdbc-demo-3.0.tar.gz` archive. But
+there is also the "unpacked" version in the `target` folder that can be used to run the app.
+
+## Run
+
+The following command prints a help message with supported options:
+```bash
+java -jar target/bootique-jdbc-demo-3.0.jar
+```
+
+```
+NAME
+ bootique-jdbc-demo-3.0.jar
+
+OPTIONS
+ -c yaml_location, --config=yaml_location
+ Specifies YAML config location, which can be a file path or a URL.
+
+ -h, --help
+ Prints this message.
+
+ -H, --help-config
+ Prints information about application modules and their configuration options.
+
+ -i, --insert
+ Inserts sample data to a DB
+
+ -s, --select
+ Selects data from a DB
+```
+
+Run the `--insert` command to create some test data in the DB. DB location and login credential are specified in the
+provided `config.yml`.
+```bash
+java -jar target/bootique-jdbc-demo-3.0.jar -c config.yml -i
+```
+
+Check the data in the database using the `--select` command:
+```bash
+java -jar target/jdbc-app-demo-X.XX.jar -c config.yml -s
+```
+
+Note that per `config.yml` the test database is located under `target/derby/DerbyDatabase`, so running `mvn clean` will
+delete it with all the inserted data.
diff --git a/assembly.xml b/assembly.xml
new file mode 100644
index 0000000..f9f2811
--- /dev/null
+++ b/assembly.xml
@@ -0,0 +1,18 @@
+
+ tar.gz
+
+ tar.gz
+
+
+
+ ${project.build.directory}
+ true
+ ./
+
+ ${project.artifactId}-${project.version}.jar
+ lib/
+
+
+
+
\ No newline at end of file
diff --git a/config.yml b/config.yml
new file mode 100644
index 0000000..a5df18b
--- /dev/null
+++ b/config.yml
@@ -0,0 +1,5 @@
+jdbc:
+ postgres:
+ jdbcUrl: jdbc:postgresql://localhost:15432/postgres
+ username: postgres
+ password: test
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..ec80409
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,12 @@
+version: '3.3'
+
+services:
+ postgres:
+ image: postgres:16.2
+ ports:
+ - "15432:5432"
+ restart: always
+ environment:
+ POSTGRES_PASSWORD: test
+ volumes:
+ - ./sql/postgres-schema.sql:/docker-entrypoint-initdb.d/postgres-schema.sql
\ No newline at end of file
diff --git a/jdbc-app-demo/README.md b/jdbc-app-demo/README.md
deleted file mode 100644
index e72a11f..0000000
--- a/jdbc-app-demo/README.md
+++ /dev/null
@@ -1,55 +0,0 @@
-# jdbc-app-demo
-
-Provides a runnable app that demonstrates how to work with Bootique JDBC APIs.
-
-## Prerequisites
-
-* Java 11 or newer
-* Apache Maven
-
-## Build the Demo App
-
-```bash
-git clone git@github.com:bootique-examples/bootique-jdbc-demo.git
-cd bootique-jdbc-demo/jdbc-app-demo
-mvn clean package
-```
-
-## Run the Demo App
-
-Now you can check the options available in your app:
-```bash
-java -jar target/jdbc-app-demo-X.XX.jar
-```
-
-```
-OPTIONS
- -c yaml_location, --config=yaml_location
- Specifies YAML config location, which can be a file path or a URL.
-
- -h, --help
- Prints this message.
-
- -H, --help-config
- Prints information about application modules and their configuration options.
-
- -i, --insert
- Demo command to insert data.
-
- -s, --select
- Demo command to select data.
-
-```
-
-Run the `--insert` command to create some test data in the test Derby DB:
-```bash
-java -jar target/jdbc-app-demo-X.XX.jar -c config.yml -i
-```
-
-Check the data in the database using the `--select` command:
-```bash
-java -jar target/jdbc-app-demo-X.XX.jar -c config.yml -s
-```
-
-Note that per `config.yml` the test database is located under `target/derby/DerbyDatabase`, so running `mvn clean` will
-delete it with all the inserted data.
\ No newline at end of file
diff --git a/jdbc-app-demo/config.yml b/jdbc-app-demo/config.yml
deleted file mode 100644
index a38ad10..0000000
--- a/jdbc-app-demo/config.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-jdbc:
- DerbyDatabase:
- jdbcUrl: jdbc:derby:target/derby/DerbyDatabase;create=true
\ No newline at end of file
diff --git a/jdbc-app-demo/pom.xml b/jdbc-app-demo/pom.xml
deleted file mode 100644
index 58c60b7..0000000
--- a/jdbc-app-demo/pom.xml
+++ /dev/null
@@ -1,109 +0,0 @@
-
-
-
- 4.0.0
-
- io.bootique.jdbc.demo
- jdbc-app-demo
- jar
- 2.0.RC1
-
-
- 17
- UTF-8
- UTF-8
-
- io.bootique.jdbc.demo.Application
-
-
-
-
-
- io.bootique.bom
- bootique-bom
- 2.0.RC1
- import
- pom
-
-
- org.apache.derby
- derby
- 10.14.2.0
-
-
-
-
-
-
- org.apache.derby
- derby
-
-
- io.bootique.logback
- bootique-logback
-
-
- io.bootique
- bootique
-
-
- io.bootique.jdbc
- bootique-jdbc-hikaricp
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.9.0
-
-
- org.apache.maven.plugins
- maven-shade-plugin
- 3.2.4
-
-
- true
-
-
- *:*
-
- META-INF/*.SF
- META-INF/*.DSA
- META-INF/*.RSA
-
-
-
-
-
-
- package
-
- shade
-
-
-
-
-
- ${main.class}
-
-
-
-
-
-
-
-
-
-
- maven-shade-plugin
-
-
-
-
-
\ No newline at end of file
diff --git a/jdbc-app-demo/src/main/java/io/bootique/jdbc/demo/Application.java b/jdbc-app-demo/src/main/java/io/bootique/jdbc/demo/Application.java
deleted file mode 100644
index 9e093c1..0000000
--- a/jdbc-app-demo/src/main/java/io/bootique/jdbc/demo/Application.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package io.bootique.jdbc.demo;
-
-import io.bootique.BQCoreModule;
-import io.bootique.BaseModule;
-import io.bootique.Bootique;
-import io.bootique.di.BQModule;
-import io.bootique.di.Binder;
-
-public class Application extends BaseModule {
-
- public static void main(String[] args) {
- Bootique.app(args)
- .autoLoadModules()
- .module(Application.class)
- .exec()
- .exit();
- }
-
- @Override
- public void configure(Binder binder) {
- BQCoreModule.extend(binder)
- .addCommand(InsertCommand.class)
- .addCommand(SelectCommand.class);
- }
-}
diff --git a/jdbc-app-demo/src/main/java/io/bootique/jdbc/demo/SchemaHelper.java b/jdbc-app-demo/src/main/java/io/bootique/jdbc/demo/SchemaHelper.java
deleted file mode 100644
index 8e1a44a..0000000
--- a/jdbc-app-demo/src/main/java/io/bootique/jdbc/demo/SchemaHelper.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package io.bootique.jdbc.demo;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.sql.DataSource;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-public class SchemaHelper {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(SchemaHelper.class);
-
- static void createSchemaIfMissing(DataSource dataSource) throws SQLException {
- try (Connection connection = dataSource.getConnection()) {
- if (!schemaPresent(connection)) {
- createSchema(connection);
- }
- }
- }
-
- private static boolean schemaPresent(Connection connection) throws SQLException {
- DatabaseMetaData metaData = connection.getMetaData();
- try (ResultSet rs = metaData.getTables(null, null, "TEST", null)) {
- return rs.next();
- }
- }
-
- private static void createSchema(Connection connection) throws SQLException {
-
- LOGGER.info("Creating test schema...");
-
- try (Statement statement = connection.createStatement()) {
- statement.execute("CREATE TABLE TEST (ID INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, NAME VARCHAR(100))");
- }
- }
-}
diff --git a/jdbc-test-demo-inmemory-db/README.md b/jdbc-test-demo-inmemory-db/README.md
deleted file mode 100644
index 9e55927..0000000
--- a/jdbc-test-demo-inmemory-db/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# jdbc-test-demo-inmemory-db
-
-Provides example JUnit5 tests using Bootique JDBC test API.
-
-## Prerequisites
-
-* Java 17 or newer
-* Apache Maven
-
-## Run the demo tests
-
-You can run tests in bootique-jdbc-test demo module using standard Derby DB:
-```bash
-git clone git@github.com:bootique-examples/bootique-jdbc-demo.git
-cd jdbc-test-demo-inmemory-db
-mvn clean test
-```
\ No newline at end of file
diff --git a/jdbc-test-demo-inmemory-db/pom.xml b/jdbc-test-demo-inmemory-db/pom.xml
deleted file mode 100644
index 14c5ea4..0000000
--- a/jdbc-test-demo-inmemory-db/pom.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
-
- 4.0.0
- io.bootique.jdbc.demo
- jdbc-test-demo-inmemory-db
- 2.0.RC1
-
-
- 17
- UTF-8
- UTF-8
-
-
-
-
-
- io.bootique.bom
- bootique-bom
- 2.0.RC1
- import
- pom
-
-
- org.slf4j
- slf4j-simple
- 1.7.25
-
-
-
-
-
-
- io.bootique.jdbc
- bootique-jdbc-junit5-derby
- test
-
-
- org.slf4j
- slf4j-simple
- test
-
-
-
-
-
-
-
- maven-compiler-plugin
- 3.8.1
-
-
- maven-surefire-plugin
- 3.0.0-M5
-
-
-
-
-
\ No newline at end of file
diff --git a/jdbc-test-demo-inmemory-db/src/test/java/io/bootique/jdbc/test/BasicTest.java b/jdbc-test-demo-inmemory-db/src/test/java/io/bootique/jdbc/test/BasicTest.java
deleted file mode 100644
index b7c5674..0000000
--- a/jdbc-test-demo-inmemory-db/src/test/java/io/bootique/jdbc/test/BasicTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package io.bootique.jdbc.test;
-
-import io.bootique.BQRuntime;
-import io.bootique.Bootique;
-import io.bootique.jdbc.junit5.DbTester;
-import io.bootique.jdbc.junit5.Table;
-import io.bootique.jdbc.junit5.derby.DerbyTester;
-import io.bootique.junit5.BQApp;
-import io.bootique.junit5.BQTest;
-import io.bootique.junit5.BQTestScope;
-import io.bootique.junit5.BQTestTool;
-
-@BQTest
-public abstract class BasicTest {
-
- // create a test DB
- @BQTestTool(BQTestScope.GLOBAL)
- static final DbTester db = DerbyTester.db()
-
- // make sure schema is created
- .initDB("classpath:test-schema.sql")
-
- // make sure test data is deleted before each test
- .deleteBeforeEachTest("t1");
-
- // create a global test app object, but do not run any commands
- @BQApp(value = BQTestScope.GLOBAL, skipRun = true)
- static final BQRuntime app = Bootique.app()
- .autoLoadModules()
-
- // make sure the test app is connected to our test DB
- .module(db.moduleWithTestDataSource("db"))
- .createRuntime();
-
- protected Table t1() {
- return db.getTable("t1");
- }
-}
diff --git a/jdbc-test-demo-inmemory-db/src/test/java/io/bootique/jdbc/test/InsertSelectUpdateTest.java b/jdbc-test-demo-inmemory-db/src/test/java/io/bootique/jdbc/test/InsertSelectUpdateTest.java
deleted file mode 100644
index 376ad09..0000000
--- a/jdbc-test-demo-inmemory-db/src/test/java/io/bootique/jdbc/test/InsertSelectUpdateTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package io.bootique.jdbc.test;
-
-import org.junit.jupiter.api.Test;
-
-import java.sql.Types;
-import java.util.List;
-
-import static org.junit.jupiter.api.Assertions.assertArrayEquals;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-public class InsertSelectUpdateTest extends BasicTest {
-
- @Test
- public void testUpdate() {
-
- // implicit column names and positions
- t1().insert(1, "x", "y");
-
- // explicit column names
- t1().insertColumns("c1", "c2", "c3")
- .values(2, "a", "b")
- .exec();
-
- t1().update()
- .set("c3", "c", Types.VARCHAR)
- .where("c1", 2)
- .exec();
-
- // Note that "matcher" API is preferred for assertions, but sometimes you do need to select the data in a test
- List