Skip to content

feat(db): Postgres + pgvector backend (Windows-friendly, zero CGO)#22

Merged
shahid-io merged 3 commits into
mainfrom
feature/postgres-pgvector-backend
May 13, 2026
Merged

feat(db): Postgres + pgvector backend (Windows-friendly, zero CGO)#22
shahid-io merged 3 commits into
mainfrom
feature/postgres-pgvector-backend

Conversation

@shahid-io

Copy link
Copy Markdown
Owner

Summary

  • Adds PostgresAdapter alongside the existing SQLiteAdapter — pick via db.backend config (sqlite default, postgres opt-in).
  • Pure-Go driver (pgx) means go install works without a C toolchain on this path, unblocking Windows users who were stuck on the sqlite-vec / MSYS2 dance.
  • Same L2 distance metric (<-> operator) as sqlite-vec, so the existing relevance threshold needs no tuning when switching backends.

Why

A Windows user couldn't get sqlite-vec building. We considered three options (drop CGO via modernc.org/sqlite, replace SQLite with Postgres, or add Postgres alongside) and picked the third — SQLite stays the friction-free default for everyone who already has it working, and Postgres becomes the escape hatch for anyone who doesn't. It's also the groundwork for the Phase 2 multi-user backend that was always going to be Postgres.

What's in

  • internal/adapters/db/postgres.go — single notes table, vector(N) column inline, prefix-match id (TEXT) for parity with SQLite.
  • internal/adapters/db/postgres_test.go — full test parity with sqlite_test.go, skipped unless INODE_TEST_PG_DSN is set so CI stays green without docker.
  • internal/config/settings.godb.backend + db.dsn keys (bound to INODE_DB_BACKEND / INODE_DB_DSN).
  • internal/core/container.go — switch on cfg.DB.Backend.
  • README.md — opt-in section with the docker recipe.

Test plan

  • go test ./... — all SQLite tests still pass, Postgres tests skip cleanly without DSN
  • go build ./... — clean (existing sqlite-vec macOS deprecation warnings unchanged)
  • INODE_TEST_PG_DSN=postgres://postgres:password@localhost:5432/postgres?sslmode=disable go test ./internal/adapters/db/... against docker run pgvector/pgvector:pg16 — run locally when next at a machine with Docker
  • End-to-end smoke: inode config set db.backend postgres && inode config set db.dsn ... then inode add + inode get on a real DB

🤖 Generated with Claude Code

shahid-io and others added 3 commits May 13, 2026 21:14
SQLite + sqlite-vec stays the default. Postgres is opt-in via
`db.backend=postgres` for users who can't (or don't want to) build
sqlite-vec — chiefly Windows, where the MSYS2 toolchain dance is rough.

The Postgres driver (pgx) is pure Go, so `go install` works on every
platform without a C toolchain when this backend is selected. pgvector
gives us the same L2 distance metric the SQLite path uses, so the
existing relevance threshold ports over unchanged.

Integration tests skip unless INODE_TEST_PG_DSN is set, so CI stays
green without docker. Local opt-in is one docker run + one env var.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
One-command spin-up for local dev and contributors testing the new
backend — `docker compose up -d` beats remembering the `docker run`
incantation.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Found by running the integration tests against a real pgvector
container: pgxvec.RegisterTypes (called from AfterConnect) looks the
`vector` type up in pg_type and fails if the extension hasn't been
installed yet — but our previous migrate() ran CREATE EXTENSION
*after* the pool was already open, so every first-time connect blew up
with "vector type not found in the database".

Move CREATE EXTENSION IF NOT EXISTS vector into AfterConnect itself so
every new pool connection ensures the extension before registering
types. Schema migration is left as just the table create.

Also consolidate compose into the existing docker-compose.yml (which
already had Ollama) instead of shipping a duplicate compose.yaml.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@shahid-io
shahid-io enabled auto-merge May 13, 2026 15:55
@shahid-io
shahid-io merged commit eb6a208 into main May 13, 2026
4 checks passed
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.

1 participant