Files

80 lines
2.2 KiB
Go

package db
import (
"database/sql"
"time"
)
// LabelChecker wraps a database connection to check takedown labels.
// Implements middleware.LabelChecker interface.
type LabelChecker struct {
db *sql.DB
}
// NewLabelChecker creates a new LabelChecker.
func NewLabelChecker(database *sql.DB) *LabelChecker {
return &LabelChecker{db: database}
}
// IsTakenDown checks if a (DID, repository) pair has an active takedown.
func (lc *LabelChecker) IsTakenDown(did, repository string) (bool, error) {
return IsTakenDown(lc.db, did, repository)
}
// IsTakenDown reports whether the given (did, repo) pair is currently taken
// down, either by an exact-repo row or by a user-level row (repo=”).
func IsTakenDown(db DBTX, did, repository string) (bool, error) {
var exists bool
err := db.QueryRow(
`SELECT EXISTS(
SELECT 1 FROM taken_down_subjects
WHERE did = ? AND (repo = ? OR repo = '')
)`,
did, repository,
).Scan(&exists)
return exists, err
}
// SetTakedown records a positive takedown for (src, did, repo). Idempotent:
// re-applying updates the timestamp.
func SetTakedown(db DBTX, src, did, repo string, cts time.Time) error {
_, err := db.Exec(
`INSERT INTO taken_down_subjects (src, did, repo, cts) VALUES (?, ?, ?, ?)
ON CONFLICT(src, did, repo) DO UPDATE SET cts = excluded.cts`,
src, did, repo, cts.UTC().Format(time.RFC3339),
)
return err
}
// RemoveTakedown drops the takedown row for (src, did, repo). Idempotent.
func RemoveTakedown(db DBTX, src, did, repo string) error {
_, err := db.Exec(
`DELETE FROM taken_down_subjects WHERE src = ? AND did = ? AND repo = ?`,
src, did, repo,
)
return err
}
// GetCursor returns the last persisted cursor for a labeler src (0 if none).
func GetCursor(db DBTX, src string) (int64, error) {
var cursor int64
err := db.QueryRow(
`SELECT cursor FROM labeler_cursor WHERE src = ?`,
src,
).Scan(&cursor)
if err == sql.ErrNoRows {
return 0, nil
}
return cursor, err
}
// SetCursor persists the cursor for a labeler src.
func SetCursor(db DBTX, src string, cursor int64) error {
_, err := db.Exec(
`INSERT INTO labeler_cursor (src, cursor) VALUES (?, ?)
ON CONFLICT(src) DO UPDATE SET cursor = excluded.cursor`,
src, cursor,
)
return err
}