refactor: usar sqlite_apply_migrations_go_infra del registry

Sustituye applyMigrations + splitSQLStatements + isIdempotentError locales
por infra.ApplyMigrations del registry. ~55 LOC eliminadas.

- store.go: import fn-registry/functions/infra, llama infra.ApplyMigrations
- go.mod: declara dep fn-registry con replace local
- app.md: declara sqlite_apply_migrations_go_infra en uses_functions

Sin cambio funcional (mismo parser naive de `;`, mismas reglas idempotentes).
Bug fixes futuros se aplicaran automaticamente al consumir registry.
This commit is contained in:
2026-05-09 12:40:10 +02:00
parent ff5c17f7ff
commit d231f04a26
4 changed files with 224 additions and 62 deletions
+3 -58
View File
@@ -5,11 +5,10 @@ import (
"embed"
"encoding/json"
"fmt"
"io/fs"
"sort"
"strings"
"time"
"fn-registry/functions/infra"
_ "github.com/mattn/go-sqlite3"
)
@@ -69,61 +68,7 @@ func (s *Store) Close() error {
}
func (s *Store) migrate() error {
files, err := fs.Glob(migrationsFS, "migrations/*.sql")
if err != nil {
return err
}
sort.Strings(files)
for _, f := range files {
b, err := migrationsFS.ReadFile(f)
if err != nil {
return err
}
// Split por sentencia para que cada ALTER pueda fallar idempotentemente
// sin abortar el resto. SQLite acepta multiples sentencias en Exec(),
// pero no ignora duplicados — ejecutamos una a una.
stmts := splitSQLStatements(string(b))
for _, stmt := range stmts {
s2 := strings.TrimSpace(stmt)
if s2 == "" {
continue
}
if _, err := s.db.Exec(s2); err != nil {
if isIdempotentError(err) {
continue
}
return fmt.Errorf("migrate %s: %w", f, err)
}
}
}
return nil
}
func splitSQLStatements(s string) []string {
out := []string{}
cur := strings.Builder{}
for _, line := range strings.Split(s, "\n") {
trim := strings.TrimSpace(line)
if strings.HasPrefix(trim, "--") || trim == "" {
continue
}
cur.WriteString(line)
cur.WriteString("\n")
if strings.HasSuffix(trim, ";") {
out = append(out, cur.String())
cur.Reset()
}
}
if cur.Len() > 0 {
out = append(out, cur.String())
}
return out
}
func isIdempotentError(err error) bool {
msg := err.Error()
return strings.Contains(msg, "duplicate column") ||
strings.Contains(msg, "already exists")
return infra.ApplyMigrations(s.db, migrationsFS, "migrations/*.sql")
}
func (s *Store) AddTarget(t DeployTarget) error {