Artifact fe9917d1f27216dd32f00ce3c670cca0fc68f7f74d5548012b05a341f279da7d:
- File
internal/oltp/savedview.go
— part of check-in
[96181d8fcb]
at
2026-08-23 01:43:17
on branch trunk
— saved views: name a report, keep it in the rail
A saved view is a name for a URL the tracker could already produce, so it stores the name and the query and nothing else. Per account, per listing; forgetting one loses the shortcut and not the listing. (user: dmestas, size: 2408) [annotate] [blame] [check-ins using]
// savedview.go stores named tracker reports. A saved view is a NAME for // a URL this forge could already produce — it invents no query the // address bar cannot say, which is why it needs no schema of its own // beyond the name and the parameters, and why deleting one loses // nothing but the shortcut. package oltp const savedViewSchema = ` CREATE TABLE IF NOT EXISTS saved_view ( account TEXT NOT NULL, -- The listing this view belongs to: a repository's tracker name, or -- the empty string for the cross-repository listing. A report saved -- against one tracker means nothing on another, so the two never -- appear in each other's rail. repo TEXT NOT NULL, name TEXT NOT NULL, query TEXT NOT NULL, -- the report, as a URL query string at TEXT NOT NULL, PRIMARY KEY (account, repo, name) );` // SavedView is one named report. type SavedView struct { Name string `json:"name"` Query string `json:"query"` } // SaveView records a report under a name, replacing a view of the same // name: saving twice with one name is how a reader corrects it, not an // error and not a second entry that shadows the first. func (d *DB) SaveView(account, repo, name, query string) error { _, err := d.db.Exec(`INSERT INTO saved_view (account, repo, name, query, at) VALUES (?, ?, ?, ?, ?) ON CONFLICT (account, repo, name) DO UPDATE SET query = excluded.query, at = excluded.at`, account, repo, name, query, now()) return err } // DeleteView drops one. A view nobody has is not an error to remove: // the caller asked for it to be gone and afterwards it is. func (d *DB) DeleteView(account, repo, name string) error { _, err := d.db.Exec(`DELETE FROM saved_view WHERE account = ? AND repo = ? AND name = ?`, account, repo, name) return err } // SavedViews lists one account's views for one listing, by name — the // order a reader put them in their own head, not by when they saved. func (d *DB) SavedViews(account, repo string) ([]SavedView, error) { if account == "" { return nil, nil } rows, err := d.db.Query(`SELECT name, query FROM saved_view WHERE account = ? AND repo = ? ORDER BY lower(name)`, account, repo) if err != nil { return nil, err } defer rows.Close() var out []SavedView for rows.Next() { var v SavedView if err := rows.Scan(&v.Name, &v.Query); err != nil { return nil, err } out = append(out, v) } return out, rows.Err() }