Skip to content

fix(storage-postgres): build socket-aware connection URLs (#52)#89

Open
flightlesstux wants to merge 1 commit into
ExtendDB:mainfrom
flightlesstux:fix/52-unix-socket-conn-string
Open

fix(storage-postgres): build socket-aware connection URLs (#52)#89
flightlesstux wants to merge 1 commit into
ExtendDB:mainfrom
flightlesstux:fix/52-unix-socket-conn-string

Conversation

@flightlesstux
Copy link
Copy Markdown

What

Fix extenddb init --pg-host <socket-path> producing a connection URL that the daemon's PostgreSQL driver rejects at startup with error with configuration: empty host.

Why

Closes #52

init was writing URLs of the form postgresql://user:pw@/var/run/postgresql:5432/db into both extenddb.toml and the catalog data_database_connection_string row. The unencoded forward slashes in the host segment break standard URL parsing, so sqlx::PgPool::connect rejected the URL at daemon startup. Init succeeded, serve failed, and users had to hand-edit both the TOML and the catalog row to recover.

Changes

  • crates/storage-postgres/src/config.rs: new build_connection_url() helper. When host starts with / it emits the documented PostgreSQL socket form postgresql://user:pw@localhost:5432/db?host=/var/run/postgresql. TCP hosts keep the classic form. parse_connection_string() now honors a ?host=<path> query parameter with last-value-wins libpq semantics; an empty value falls back to the URL host so existing parse callers stay backwards compatible.
  • crates/storage-postgres/src/bootstrapper.rs: app_connection_url() delegates to the new builder. No other behavior change.

Testing done

Added 10 unit tests in crates/storage-postgres/src/config.rs:

  • TCP and socket URL build shapes.
  • TCP URL parse path unchanged.
  • Socket URL parse extracts the ?host= value.
  • Empty ?host= falls back to the URL host.
  • Unknown query parameters are ignored.
  • Round-trip through the custom parser for both TCP and socket URLs.
  • Round-trip through sqlx::postgres::PgConnectOptions::from_str for both URL shapes. This is the same parser the daemon uses, so it directly verifies the fix at the failure layer.

Results:

```
cargo test --workspace --lib 382/382 passed
cargo clippy -p extenddb-storage-postgres --all-targets -- -D warnings clean
cargo fmt -p extenddb-storage-postgres -- --check (on the two changed files) clean
```

Full `cargo test --workspace` (including pytest/external integration suites) was not exercised in this branch because it requires a running PostgreSQL instance and provisioned test credentials.

Checklist

  • I have read CONTRIBUTING.md
  • All workspace lib tests pass (`cargo test --workspace --lib`)
  • Changed files are formatted (`cargo fmt`)
  • Clippy is clean on the modified crate (`-D warnings`)
  • Added unit tests for new functionality
  • No documentation changes needed (URL form change is internal; observable behavior is identical for TCP setups and now actually works for socket setups)
  • No breaking changes

`extenddb init --pg-host /var/run/postgresql` previously wrote a URL of
the form `postgresql://user:pw@/var/run/postgresql:5432/db` into both
`extenddb.toml` and the catalog `data_database_connection_string` row.
The unencoded forward slashes in the host segment break standard URL
parsing, so `sqlx::PgPool::connect` rejected the URL at daemon startup
with `error with configuration: empty host`, leaving init-time success
followed by serve-time failure.

Switch the URL builder in `bootstrapper.rs` to a new
`config::build_connection_url` helper that emits the documented
PostgreSQL socket form when the host is a path:

  postgresql://user:pw@localhost:5432/db?host=/var/run/postgresql

TCP hosts still use the classic form. Update the custom
`parse_connection_string` to honor a `?host=<path>` query parameter,
preserving the existing split logic for the URL host segment.

Tests round-trip both URL shapes through the custom parser and through
`sqlx::postgres::PgConnectOptions::from_str` so the regression is
caught at the same parser layer the daemon uses.
@jcshepherd
Copy link
Copy Markdown
Collaborator

Hi Ercan! Thanks for the PR. I'll let the reviewers weigh in on this approach vs #92 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Init-generated connection string fails at daemon startup with "empty host" when --pg-host is a Unix socket path

2 participants