Artifact 0b7374374e7891d1e38f6c9c9e9d9980c225f4b8a42c254b2e354889cd2667ac:
- File
internal/oltp/oltp.go
— part of check-in
[87a492fe4f]
at
2026-08-18 01:59:53
on branch trunk
— repo: a create flow a person can actually use
Nobody picks a filesystem path when they make a repository on a forge, and requiring one made repo.add usable only by the machine's operator. --repos-root gives the server somewhere to put them; path is now optional and the response says where it landed.
Repositories gain a description — every forge has one and quarry had nowhere to put it, so the listing could only show names and counts.
Three surfaces on one op: quarry repo new|clone|list|remove drives the HTTP API rather than the database, so the CLI has no privileged path and anything it can do a client can; /new is the same three questions a forge always asks; and an empty repository shows how to push to it instead of a bare file table, because it is waiting, not broken.
A rejected form comes back as a form with the reason on it — an error page throws the reader's input away. (user: dmestas, size: 2928) [annotate] [blame] [check-ins using]
// Package oltp is quarry's forge OLTP database (0001 §8): the only // authoritative non-DAG state. v1 holds sync users — per-repo login // credentials for push gating. Small by construction; the litestream // replica is the recovery story when deployment warrants it. package oltp import ( "database/sql" "fmt" "strings" "github.com/ncruces/go-sqlite3/driver" ) const schema = ` CREATE TABLE IF NOT EXISTS sync_user ( repo TEXT NOT NULL, user TEXT NOT NULL, secret TEXT NOT NULL, -- RFC §6.3 shared secret (40 hex); plaintext never stored PRIMARY KEY (repo, user) );` type DB struct { db *sql.DB } func Open(path string) (*DB, error) { db, err := driver.Open("file:" + path) if err != nil { return nil, err } if _, err := db.Exec(`PRAGMA journal_mode=WAL; PRAGMA busy_timeout=5000;`); err != nil { db.Close() return nil, fmt.Errorf("oltp: pragmas: %w", err) } if _, err := db.Exec(schema); err != nil { db.Close() return nil, fmt.Errorf("oltp: schema: %w", err) } if _, err := db.Exec(accountSchema); err != nil { db.Close() return nil, fmt.Errorf("oltp: account schema: %w", err) } if _, err := db.Exec(webhookSchema); err != nil { db.Close() return nil, fmt.Errorf("oltp: webhook schema: %w", err) } if _, err := db.Exec(sessionSchema); err != nil { db.Close() return nil, fmt.Errorf("oltp: session schema: %w", err) } if _, err := db.Exec(ciSchema); err != nil { db.Close() return nil, fmt.Errorf("oltp: ci schema: %w", err) } if _, err := db.Exec(mirrorSchema); err != nil { db.Close() return nil, fmt.Errorf("oltp: mirror schema: %w", err) } if _, err := db.Exec(repoSchema); err != nil { db.Close() return nil, fmt.Errorf("oltp: repo schema: %w", err) } for _, alter := range repoMigrations { if _, err := db.Exec(alter); err != nil && !strings.Contains(err.Error(), "duplicate column") { db.Close() return nil, fmt.Errorf("oltp: repo migrate: %w", err) } } return &DB{db: db}, nil } func (d *DB) Close() error { return d.db.Close() } // SetSyncUser stores (replacing) one repo user's shared secret. func (d *DB) SetSyncUser(repo, user, secret string) error { _, err := d.db.Exec(`INSERT OR REPLACE INTO sync_user (repo, user, secret) VALUES (?, ?, ?)`, repo, user, secret) return err } // Secret returns the stored shared secret for one repo user. func (d *DB) Secret(repo, user string) (string, bool) { var s string err := d.db.QueryRow(`SELECT secret FROM sync_user WHERE repo = ? AND user = ?`, repo, user).Scan(&s) return s, err == nil } // Gated reports whether a repo has any sync users — the v1 policy // switch: no users means anonymous push stays allowed (local use), // one or more users means pushes must authenticate. func (d *DB) Gated(repo string) bool { var n int if err := d.db.QueryRow(`SELECT count(*) FROM sync_user WHERE repo = ?`, repo).Scan(&n); err != nil { return false } return n > 0 }