ikurotime / gitgud

public

Añadir soporte para PostgreSQL #1

Open rafaelzr opened this on 2026-08-27 12:01
Rrafaelzr commented on 2026-08-27 12:01

SQLite sobre archivo local hace gitgud de un solo nodo: no puede haber una segunda réplica, y un reinicio sin volumen persistente se lleva los datos.

¿Ya se usa un ORM? No

  • No hay ninguno en go.mod (ni GORM, ent, bun, xorm, sqlx, sqlc).
  • Es database/sql con 22 sentencias SQL a mano entre user_repo.go, repo_repo.go, issue_repo.go y pr_repo.go.
  • Pero la arquitectura ya es la correcta: los repositorios de domain son interfaces y persistence/sqlite es un adaptador. Nada por encima de infra sabe que existe SQLite.

No es un rewrite, es un segundo adaptador al lado.

Qué está atado a SQLite

  1. res.LastInsertId() — no existe en Postgres. Cada INSERT necesita RETURNING id. Es lo que más líneas toca.
  2. Placeholders ? -> $1..$n (22 sentencias).
  3. isUniqueViolation (user_repo.go:60) compara sqlite3.ErrConstraintUnique. Es el único sitio donde un error de driver se vuelve domain.ErrConflict. En Postgres es el SQLSTATE 23505.
  4. DDL: INTEGER PRIMARY KEY AUTOINCREMENT -> BIGSERIAL; DATETIME -> TIMESTAMPTZ.
  5. Sesiones: scs/sqlite3store -> scs/postgresstore. Cambio directo.
  6. Config.DBPath() devuelve una ruta de archivo; tiene que ser un DSN.
  7. Las migraciones no tienen versionado: se ejecutan en orden de nombre en cada arranque y dependen de IF NOT EXISTS. Eso no sobrevive al primer ALTER TABLE. Es prerequisito, no extra.

Sobre el ORM: no

  • GORM/ent pelean con el diseño: quieren tags o structs base embebidos, lo que mete detalle de persistencia dentro de domain. Y no resuelven ni RETURNING id ni el numerado por repo.
  • sqlx solo ayuda con el scanning, que no es el problema.
  • sqlc sí encaja: genera Go tipado desde el SQL que ya está escrito, soporta ambos dialectos, cero dependencia en runtime.

Propuesta: sqlc, o dos adaptadores a mano. Decidirlo antes de empezar.

Bloqueante previo

Hoy las foreign keys no se aplican (el DSN usa la sintaxis de pragma del dialecto equivocado; PRAGMA foreign_keys da 0 y se aceptan filas huérfanas). Postgres las aplica por defecto y no se le puede convencer de lo contrario, así que todas esas filas huérfanas se vuelven errores duros a mitad de la migración. Arreglar eso primero.

Pregunta abierta

¿SQLite se mantiene o Postgres lo reemplaza? Si se va, esto se achica bastante y la decisión de sqlc deja de importar.

Sign in to comment.