Skip to content
Merged
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
83 changes: 83 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,89 @@ Use the `jdbc:sqlite:` prefix so Liquibase's SQLite implementation claims the UR
`jdbc:libsql:` also reaches the driver, but Liquibase cannot resolve a driver from it
and still needs the explicit driver class.

### Flyway

Flyway selects its database plugin from the URL before it opens a connection. Its
SQLite plugin claims `jdbc:sqlite:`, `jdbc:sqldroid:`, and the p6spy prefixes, so a
`jdbc:libsql:` URL is rejected with:

```text
No Flyway database plugin found to handle jdbc:libsql:********
```

The `jdbc:sqlite:` alias is claimed, but its plugin resolves the driver to
`org.sqlite.JDBC`. Programmatic `Flyway.configure().dataSource(url, ...)` builds a
`DriverDataSource` eagerly with a null driver class, so a later `driver(...)` call is
ignored.

Use one of these configurations:

**DataSource with either URL form (recommended)**

`jdbc:libsql:` works when Flyway receives a `DataSource`, because the plugin lookup
has already happened by the time the connection is opened:

```java
Flyway flyway = Flyway.configure()
.dataSource(dataSource) // any pool or DriverManager-backed DataSource
.locations("classpath:db/migration")
.load();
flyway.migrate();
```

Spring Boot configuration, using the application `DataSource` that Flyway receives
automatically:

```properties
spring.datasource.url=jdbc:libsql:http://localhost:8080
spring.datasource.driver-class-name=io.github.magnusp.libsql.jdbc.LibsqlDriver
```

**URL configuration with an explicit driver**

URL-based configuration must use the `jdbc:sqlite:` alias and name the driver
explicitly. This mirrors the Flyway Maven plugin and `flyway.properties` path:

```java
ClassicConfiguration configuration = new ClassicConfiguration();
configuration.setUrl("jdbc:sqlite:http://localhost:8080");
configuration.setDriver("io.github.magnusp.libsql.jdbc.LibsqlDriver");
Flyway flyway = new Flyway(configuration);
```

```properties
# flyway.properties
url=jdbc:sqlite:http://localhost:8080
driver=io.github.magnusp.libsql.jdbc.LibsqlDriver
```

`jdbc:libsql:` cannot be used with URL-based configuration at all, even with an
explicit driver, because the plugin lookup fails first.

Auto-commit statements on one JDBC connection share a Hrana stream, so `initSql` and
`afterConnect` statements that set session state such as `PRAGMA foreign_keys` apply
to the migrations that follow on that connection.

Flyway wraps `clean()` in a transaction, and SQLite ignores `PRAGMA foreign_keys`
inside a transaction. Set the pragma when the connection is initialized, before
Flyway begins that transaction:

```properties
# flyway.properties
initSql=PRAGMA foreign_keys = OFF
```

```properties
# Spring Boot
spring.flyway.init-sqls=PRAGMA foreign_keys = OFF
```

The driver splits Flyway's `PRAGMA foreign_keys = OFF; DROP TABLE ...; PRAGMA
foreign_keys = ON` scripts and runs every statement on the connection's stream (see
[#258](https://github.com/magnusp/libsql-java/issues/258)). sqld expires an idle
stream after about ten seconds and session state resets with it, so configure state
that must outlive an idle period in the pool's connection initialization.

## Contributing

We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines and development workflow, and [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) for community standards.
Expand Down
Loading