package oltp
import "database/sql"
// Tickets closed by a default-branch check-in's comment ("closes #12").
// The sweep that does it runs after every fold, and a fold is not once
// per check-in: a restart, a reindex or a re-fold replays the same
// history. checkin_close is the per-check-in memory that makes the
// close happen once — a ticket somebody reopened stays reopened — and
// checkin_close_watch is how far the sweep has looked, so the history
// a repository arrived with is never read as a list of new closes.
const checkinCloseSchema = `
CREATE TABLE IF NOT EXISTS checkin_close (
repo TEXT NOT NULL,
checkin TEXT NOT NULL, -- a check-in whose closing words were acted on
PRIMARY KEY (repo, checkin)
);
CREATE TABLE IF NOT EXISTS checkin_close_watch (
repo TEXT PRIMARY KEY,
checkin TEXT NOT NULL -- the last check-in the sweep looked at
);`
// CloseWatch reads how far the sweep has looked; false before it ever has.
func (d *DB) CloseWatch(repo string) (string, bool) {
var at string
err := d.db.QueryRow(`SELECT checkin FROM checkin_close_watch WHERE repo = ?`,
repo).Scan(&at)
return at, err == nil
}
// SetCloseWatch records how far the sweep has looked.
func (d *DB) SetCloseWatch(repo, checkin string) error {
_, err := d.w.Exec(`INSERT OR REPLACE INTO checkin_close_watch (repo, checkin) VALUES (?, ?)`,
repo, checkin)
return err
}
// CheckinClosed reports whether a check-in's closing words were acted on.
func (d *DB) CheckinClosed(repo, checkin string) (bool, error) {
var one int
err := d.db.QueryRow(`SELECT 1 FROM checkin_close WHERE repo = ? AND checkin = ?`,
repo, checkin).Scan(&one)
if err == sql.ErrNoRows {
return false, nil
}
return err == nil, err
}
// MarkCheckinClosed records that a check-in's closing words were acted
// on; marking one twice is one mark.
func (d *DB) MarkCheckinClosed(repo, checkin string) error {
_, err := d.w.Exec(`INSERT OR IGNORE INTO checkin_close (repo, checkin) VALUES (?, ?)`,
repo, checkin)
return err
}