Skip to content

feat(database): add PostgreSQL support alongside SQLite - #380

Merged
javi11 merged 2 commits into
mainfrom
feat/postgres-support
Mar 4, 2026
Merged

feat(database): add PostgreSQL support alongside SQLite#380
javi11 merged 2 commits into
mainfrom
feat/postgres-support

Conversation

@javi11

@javi11 javi11 commented Mar 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Introduces a Dialect abstraction (sqlite | postgres) with a dialectAwareDB/dialectAwareTx wrapper layer that auto-rewrites queries (placeholder ?$N, datetime('now')NOW(), etc.) on every call — zero per-query boilerplate
  • All repositories updated to accept Dialect at construction; LastInsertId() replaced with RETURNING id for PostgreSQL; date/time cutoffs computed in Go rather than SQL
  • 17 PostgreSQL migration files added; existing SQLite migrations moved to migrations/sqlite/ subdirectory
  • DatabaseConfig extended with optional type and dsn fields — SQLite remains the default and is fully backwards-compatible

Closes #82

Configuration

# SQLite (default — no changes required)
database:
  path: ./altmount.db

# PostgreSQL
database:
  type: postgres
  dsn: "postgres://user:password@localhost:5432/altmount?sslmode=disable"

Test plan

  • go build ./... — clean build
  • go test ./internal/database/... — all existing SQLite tests pass
  • Start server with default config — SQLite path identical to previous behaviour
  • Start server with type: postgres — migrations run, all operations work
  • Test AddToQueue with both new inserts and conflicts on both backends
  • Test FilterExistingNzbdavIds — JSONB extraction returns correct results on PostgreSQL

🤖 Generated with Claude Code

javi11 and others added 2 commits March 4, 2026 10:57
Introduces a dialect abstraction layer that allows AltMount to run against
either SQLite (default, unchanged behaviour) or PostgreSQL, selected via the
new `database.type` / `database.dsn` config keys.

Key changes:
- `internal/database/dialect.go` – new `Dialect` type + `dialectHelper` with
  helpers for placeholder rewriting (?→$N), datetime expressions, JSON
  extraction, and avg-time-diff calculations
- `dialectAwareDB` / `dialectAwareTx` wrappers auto-apply query rewriting on
  every ExecContext / QueryContext / QueryRowContext call
- All repository constructors now accept a `Dialect` parameter; `datetime('now')`
  in SET clauses replaced with bound `time.Now()` params; `LastInsertId()`
  replaced with `RETURNING id` for PostgreSQL branches
- `internal/database/db.go` – `newPostgresDB` path using `pgx/v5/stdlib`;
  goose migrations split into `migrations/sqlite/` and `migrations/postgres/`
- `internal/config/manager.go` – `DatabaseConfig` extended with `Type` and `DSN`
  fields (SQLite path remains default)
- `cmd/altmount/cmd/setup.go` – wires `Type`, `DSN`, and `db.Dialect()` through
  to all repository constructors
- 17 PostgreSQL migration files created (BIGSERIAL, TIMESTAMPTZ, JSONB, triggers)
- Test files updated to pass `DialectSQLite` to updated constructors

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…d importer tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@javi11
javi11 merged commit 7de3b73 into main Mar 4, 2026
1 check passed
@javi11
javi11 deleted the feat/postgres-support branch March 4, 2026 10:16
yoshitaka420 pushed a commit to yoshitaka420/altmount that referenced this pull request Jun 1, 2026
* feat(database): add PostgreSQL support alongside SQLite

Introduces a dialect abstraction layer that allows AltMount to run against
either SQLite (default, unchanged behaviour) or PostgreSQL, selected via the
new `database.type` / `database.dsn` config keys.

Key changes:
- `internal/database/dialect.go` – new `Dialect` type + `dialectHelper` with
  helpers for placeholder rewriting (?→$N), datetime expressions, JSON
  extraction, and avg-time-diff calculations
- `dialectAwareDB` / `dialectAwareTx` wrappers auto-apply query rewriting on
  every ExecContext / QueryContext / QueryRowContext call
- All repository constructors now accept a `Dialect` parameter; `datetime('now')`
  in SET clauses replaced with bound `time.Now()` params; `LastInsertId()`
  replaced with `RETURNING id` for PostgreSQL branches
- `internal/database/db.go` – `newPostgresDB` path using `pgx/v5/stdlib`;
  goose migrations split into `migrations/sqlite/` and `migrations/postgres/`
- `internal/config/manager.go` – `DatabaseConfig` extended with `Type` and `DSN`
  fields (SQLite path remains default)
- `cmd/altmount/cmd/setup.go` – wires `Type`, `DSN`, and `db.Dialect()` through
  to all repository constructors
- 17 PostgreSQL migration files created (BIGSERIAL, TIMESTAMPTZ, JSONB, triggers)
- Test files updated to pass `DialectSQLite` to updated constructors
javi11 added a commit to dclipca/altmount that referenced this pull request Sep 6, 2026
PostgreSQL requires an expression index column to be wrapped in its own
parentheses; the single-paren form has failed with a syntax error on
every fresh PostgreSQL install since kipsilabs#380, so no database can have
applied the old text.
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.

[Feature Request] Enable support for PostgreSQL 14+ / MySQL

1 participant