Repository navigation
Align SQLite CLI URL forms across languages #1588
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # SQLite CLI URLs | ||
|
|
||
| The Go, Java, JavaScript, Ruby, and Rust migration CLIs accept the same SQLite | ||
| prefixes. The `//` after `sqlite:` is optional: | ||
|
|
||
| | Database | Long form | Short form | | ||
| | --- | --- | --- | | ||
| | Relative file | `sqlite://river.db` | `sqlite:river.db` | | ||
| | Absolute file | `sqlite:///var/lib/app/river.db` | `sqlite:/var/lib/app/river.db` | | ||
| | In memory | `sqlite://:memory:` | `sqlite::memory:` | | ||
|
|
||
| Relative paths are resolved from the command's working directory. An in-memory | ||
| database lasts only for that invocation; use a file to share a database between | ||
| migration commands and application processes. | ||
|
|
||
| Commands that connect to a database reject an empty SQLite path. Use an explicit | ||
| `:memory:` path if you want a temporary database. | ||
|
|
||
| For `migrate-get`, `--database-url` only selects the SQL dialect. Both `sqlite:` | ||
| and `sqlite://` work without a path, and export never opens or creates a database. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 Bare forms are documented only for For Go, the bare case "sqlite":
+ if _, isMigrateGet := any(command).(*migrateGet); urlWithoutProtocol == "" && !isMigrateGet {
+ return false, fmt.Errorf("SQLite database URL (`%s`) needs a path or `:memory:`", *databaseURL)
+ }
+
dbPool, err := openSQLitePool(protocol, urlWithoutProtocol)Suggested regression test, as a subtest between t.Run("EmptyPathRejected", func(t *testing.T) {
t.Parallel()
for _, databaseURL := range []string{"sqlite:", "sqlite://"} {
t.Run(databaseURL, func(t *testing.T) {
t.Parallel()
cli := NewCLI(&Config{Name: "River"})
cli.SetOut(&bytes.Buffer{})
cmd := cli.BaseCommandSet()
cmd.SetArgs([]string{"migrate-up", "--database-url", databaseURL})
require.ErrorContains(t, cmd.Execute(), "needs a path")
})
}
})
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 Fixed in 9c435d99. Go, Java, Ruby, and Rust now reject empty SQLite paths before connecting; JavaScript already rejected them and now has matching regression coverage. Tests cover each supported migration command, Go's benchmark, Ruby's |
||
|
|
||
| Ruby also accepts `sqlite3:` and `sqlite3://` with either Active Record or Sequel. | ||
| Java also accepts native `jdbc:sqlite:` URLs, passed unchanged to the JDBC driver. | ||
| These aliases are specific to those languages. Query parameters and | ||
| percent-encoding are handled differently by each language and can select a | ||
| different file, or turn an in-memory database into an on-disk file. For portable | ||
| URLs, avoid `?` and `%` in paths, and don't add parameters to `:memory:`. | ||
| Driver-specific URI options are not portable; for example, Rust's `?mode=rwc` | ||
| creates a missing database file. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |
|
|
||
| ## [Unreleased] | ||
|
|
||
| ### Fixed | ||
|
|
||
| - Normalize `sqlite://` URLs before opening JDBC connections so relative paths remain relative and `sqlite://:memory:` opens an in-memory database. Preserve `sqlite:` and native `jdbc:sqlite:` URLs. [PR #1588](https://github.com/riverqueue/river/pull/1588). | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 Non-blocking, and probably low impact given how few Java users there are yet:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 Added an upgrade note to the Java changelog in 9c435d99: |
||
| - **Upgrade note:** `sqlite://var/lib/x.db` now opens `./var/lib/x.db` instead of `/var/lib/x.db`. Use `sqlite:///var/lib/x.db` to keep targeting the absolute path. | ||
| - Reject empty SQLite paths in commands that connect to a database; bare prefixes remain valid for offline migration SQL export. [PR #1588](https://github.com/riverqueue/river/pull/1588). | ||
|
|
||
| ## [0.4.0] - 2026-11-06 | ||
|
|
||
| ### Added | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 Accepting the short form here exposes a gap in
bench. Its in-memory migration check atriver_cli.go:415only looks atparsedDatabaseURL.Host, buturl.Parse("sqlite::memory:")leavesHostempty and puts:memory:inOpaque. Soriver bench --database-url sqlite::memory:skips the migration and fails withSQL logic error: no such table: river_job (1), whilesqlite://:memory:works.One-line fix in
cmd/river/rivercli/river_cli.go:Suggested regression test, as the first subtest in
TestBaseCommandSetSQLiteURLsinriver_cli_test.go. Thesqlite::memory:case fails on this branch and passes with the fix:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 Fixed in 9c435d99 by checking
Opaqueas well asHost. Added the benchmark regression test for both memory URL forms; the short form reproduced the missing-table error before the fix, and both now pass. Full Gomake testandmake lintalso passed.