Database utilities for latte-java. Currently: a zero-dependency SQL migration runner.
Migrator applies *.sql scripts in SemVer order and records each applied version — with the script's SHA-256 checksum and the time it ran — in a version table (default versions).
try (Connection connection = dataSource.getConnection()) {
// From a directory
List<Version> applied = new Migrator(connection, Path.of("db/migrations")).migrate();
// Or from the classpath, with a custom version table name
new Migrator(connection, "db/migrations", "schema_versions").migrate();
}Migration files are named <semver>.sql (for example 1.36.3.sql or 2.0.0-beta.1.sql). Build metadata (1.0.0+build) is not allowed. Files are read as UTF-8 and checksummed over their raw bytes — editing an already-applied migration (even reformatting it) fails the next run with ChecksumException. New migrations must be higher than the highest applied version; out-of-order versions fail with MigrationException.
You can store the files in a directory or on the classpath (even in a JAR file). This allows you to execute the migrations when the application starts or via the project file.
Scripts are split into statements with a dialect-aware parser: comments (--, /* */, # on MySQL), quoted strings/identifiers, PostgreSQL dollar-quoting ($tag$ ... $tag$) and E'' strings, MySQL backticks and client-style DELIMITER directives for stored procedures.
Concurrent JVMs are safe: the runner holds a session advisory lock (pg_advisory_lock on PostgreSQL, GET_LOCK on MySQL/MariaDB) for the whole run. On other databases (H2, HSQLDB, …) protection is best-effort via SELECT ... FOR UPDATE plus the version table's primary key.
Each migration runs in its own transaction and the version row commits with it. On PostgreSQL a failed migration rolls back completely (transactional DDL). On MySQL/MariaDB, DDL commits implicitly, so a failed migration can leave partial schema changes — the version row is not recorded, so the fixed script re-runs from that migration.
latte build # compile + jar
latte test # unit + integration testsIntegration tests run against H2 in memory, plus PostgreSQL and MySQL when reachable on localhost (skipped otherwise). You can run MySQL and PostgreSQL in Docker, but the tests assume that the username and password are dev/dev. However, you can run the command:
latte test-databaseThis configures the databases (local or in Docker) to have the correct users/roles for the tests.