Files
oikos/internal/db/splitsql_test.go
dtoro 1b04683639 phase 1 review fixes: dedup edges, real export, validation, tests
Review of aa2ca0a found and fixed:
- re-ingest duplicated ALL edges (upsert conflicted on valid_from=now(),
  never fired) — migration 007 dedupes + partial unique index on current
  edges; upsert now targets it. Regression-tested.
- export was a stub that overwrote seeds/*.yaml with 11-byte "version: 1"
  files — implemented real deterministic export (ontology/inventory/policy,
  cognition-layer excluded); round-trip is byte-stable (tested)
- DB password leaked in startup logs (slog JSON bypasses String()) —
  Config now implements slog.LogValuer; regression-tested
- docker-compose had literal '***' as DB password — env-interpolated
- uuid.New() (v4) → uuid.NewV7() per ADR-0005
- no ontology validation on ingest — internal/ontology TypeTree: abstract
  instantiation rejected, relationship endpoints hierarchy-validated,
  cardinality enforced in-transaction, lifecycle states checked, default
  state applied (Phase 1 gate items, R3-1)
- getOrCreateEntityID swallowed non-ErrNoRows errors
- migration runner now holds a session advisory lock on one connection
- Makefile: hardcoded /opt/homebrew/bin/go → go; test-db target

Tests: 4 unit suites + 7 integration tests (env-guarded, throwaway DB per
run): migrate idempotent, seed idempotent + no dup edges, abstract/edge/
cardinality rejection, blast_radius cycle termination, export round-trip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 08:11:01 +02:00

54 lines
1.3 KiB
Go

package db
import (
"strings"
"testing"
)
func nonEmpty(stmts []string) []string {
var out []string
for _, s := range stmts {
if strings.TrimSpace(s) != "" {
out = append(out, s)
}
}
return out
}
func TestSplitSQLBasic(t *testing.T) {
stmts := nonEmpty(splitSQL("CREATE TABLE a (id int); CREATE TABLE b (id int);"))
if len(stmts) != 2 {
t.Fatalf("got %d statements, want 2: %#v", len(stmts), stmts)
}
}
func TestSplitSQLDollarQuotedFunction(t *testing.T) {
sql := `CREATE FUNCTION f() RETURNS int AS $$
SELECT 1; SELECT 2;
$$ LANGUAGE sql;
CREATE TABLE t (id int);`
stmts := nonEmpty(splitSQL(sql))
if len(stmts) != 2 {
t.Fatalf("got %d statements, want 2: %#v", len(stmts), stmts)
}
if !strings.Contains(stmts[0], "SELECT 1; SELECT 2;") {
t.Errorf("dollar-quoted body was split: %q", stmts[0])
}
}
func TestSplitSQLTaggedDollarQuote(t *testing.T) {
sql := `DO $body$ BEGIN PERFORM 1; END $body$;SELECT 1;`
stmts := nonEmpty(splitSQL(sql))
if len(stmts) != 2 {
t.Fatalf("got %d statements, want 2: %#v", len(stmts), stmts)
}
}
func TestSplitSQLSemicolonInComment(t *testing.T) {
sql := "-- comment with ; semicolon\nCREATE TABLE t (id int); -- trailing; note\nSELECT 1;"
stmts := nonEmpty(splitSQL(sql))
if len(stmts) != 2 {
t.Fatalf("got %d statements, want 2: %#v", len(stmts), stmts)
}
}