pjfanning opened a new pull request, #517: URL: https://github.com/apache/pekko-persistence-r2dbc/pull/517
### Motivation Port of the akka-persistence-r2dbc H2 support: - [akka/akka-persistence-r2dbc#402](https://github.com/akka/akka-persistence-r2dbc/pull/402) Support H2 database - [akka/akka-persistence-r2dbc#408](https://github.com/akka/akka-persistence-r2dbc/pull/408) Allow arbitrary H2 options passed through from config - [akka/akka-persistence-r2dbc#456](https://github.com/akka/akka-persistence-r2dbc/pull/456) Disable optimize reuse results to avoid race condition The code is copied from the akka-persistence-r2dbc 1.2.0 release, which is available under the Apache License, Version 2.0 as of 2026-10-24 (its LICENSE change date). Files derived from Akka keep the Lightbend copyright line, with the ASF header added by `sbt headerCreate`. An in-process database is useful for tests and small single-node applications without running a database server. ### Modification Upstream #402 was mostly a dialect refactor that Pekko doesn't have; Pekko already selects dialect-specific DAO subclasses in each `fromConfig`. So this follows Pekko's MySQL support instead of transcribing the diff: - **Dialect:** `Dialect.H2` (`dialect = "h2"`). Like MySQL, it requires `use-app-timestamp` and `db-timestamp-monotonic-increasing`, because the database runs in the same process. - **DAOs:** `H2JournalDao`, `H2QueryDao`, `H2SnapshotDao` (`MERGE ... KEY`) and `H2DurableStateDao` override the same hooks as the MySQL classes. That covers `CURRENT_TIMESTAMP`, interval and bucket SQL, no `RETURNING`, and reading tags as `Object` (r2dbc/r2dbc-h2#208). They run on `connection-factory.h2.use-dispatcher` (default `pekko.actor.default-blocking-io-dispatcher`) because the H2 driver blocks. - **Connection:** `ConnectionFactoryProvider` builds an `H2ConnectionFactory` when `driver = "h2"`, from the new `connection-factory.h2` settings, still behind the connection pool: - The tables and slice indexes are created on first connect, honouring `schema` and the table names. A non-default schema is now created too. - `additional-init` and `additional-options` (#408) are supported. Option values use `unwrapped()` instead of upstream's `render()`, which would wrap strings in quotes. - `OPTIMIZE_REUSE_RESULTS=FALSE` (#456) is set. - The H2 code lives in `internal.h2.H2Connections`, so users of other drivers never load it. - A configured `connection-factory-options-customizer` is rejected, since the H2 factory isn't built from `ConnectionFactoryOptions`. - **Dependencies:** `io.r2dbc:r2dbc-h2:1.1.0.RELEASE` (Apache 2.0) and `com.h2database:h2:2.4.240` (EPL 1.0 or MPL 2.0, ASF Category B; the version r2dbc-h2 is built against), both `provided,test` like the other drivers. - **CI:** new "Run tests with H2" job (no database container needed). - **Docs:** an H2 section in getting started, the H2 connection example on the config page, and the overview. - **Tests:** - New `H2ConnectionsSpec` and `H2AdditionalInitForSchemaSpec` (ported). - The `changes_test` column is renamed to `the_value`, because `value` is reserved in H2 (same as upstream). - H2 handling added to `PersistTagsSpec`, `R2dbcExecutorSpec` (`pg_sleep`), `ConnectionFactoryOptionsCustomizerSpec` and `RuntimePluginConfigSpec` (one in-memory database per plugin config). ### Result The plugins can be used with an in-memory or file-based H2 database. ### Tests - `sbt -Dpekko.persistence.r2dbc.dialect=h2 test`: 283 succeeded, 0 failed, 85 pending (the same dialect-specific pending tests as MySQL). - `sbt core/test` (PostgreSQL in docker): 362 succeeded, 0 failed. - `H2ConnectionsSpec`: the `OPTIMIZE_REUSE_RESULTS` and `additional-options` tests fail if the option is removed or `render()` is used. It also covers custom schema and table creation, rejecting an unknown protocol, and requiring `use-app-timestamp`. - Yugabyte and MySQL not run locally for this change; relying on CI. - `sbt core/mimaReportBinaryIssues migration/mimaReportBinaryIssues`: no issues. - scalafmt, `javafmtCheckAll`, `headerCheckAll`; `docs/paradox` (`paradoxValidateInternalLinks` reports only the existing `[[R2dbcReadJournal.loadEnvelope]]` error that is also on `main`). ### Notes - `OPTIMIZE_REUSE_RESULTS` is no longer a setting in H2 2.4.240's `DbSettings`. It is still passed for users on older H2 versions, since H2 is a provided dependency. - **Interaction with #515 (snapshots as starting points):** the H2 snapshot table matches `main` and has no `db_timestamp`/`tags` columns. Whichever of the two PRs merges second needs to add those columns to the H2 schema and the snapshot by-slice SQL hooks to `H2SnapshotDao`. ### References Refs akka/akka-persistence-r2dbc#402, akka/akka-persistence-r2dbc#408, akka/akka-persistence-r2dbc#456 -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
