Files
2dph/internal/websearch/cache.go
T
eSliderandGitHub 368a757612
Tests / Test (push) Failing after 4s
Tests / Release (semver) (push) Skipped
feat: Go SearXNG client; throttled is not absence (#16)
2026-08-13 19:53:31 +01:00

98 lines
1.9 KiB
Go

package websearch
import (
"database/sql"
"encoding/json"
"os"
"path/filepath"
_ "modernc.org/sqlite"
)
const cacheSchema = `
CREATE TABLE IF NOT EXISTS responses (
key TEXT PRIMARY KEY,
fetched REAL NOT NULL,
payload TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS meta (
key TEXT PRIMARY KEY,
value REAL NOT NULL
);
`
type Cache struct {
db *sql.DB
}
func OpenCache(path string) (*Cache, error) {
if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
return nil, err
}
db, err := sql.Open("sqlite", path)
if err != nil {
return nil, err
}
if _, err := db.Exec(cacheSchema); err != nil {
db.Close()
return nil, err
}
return &Cache{db: db}, nil
}
func (c *Cache) Close() error {
if c == nil || c.db == nil {
return nil
}
return c.db.Close()
}
func (c *Cache) Get(key string, ttl, now float64) (*Payload, error) {
var fetched float64
var raw string
err := c.db.QueryRow("SELECT fetched, payload FROM responses WHERE key = ?", key).Scan(&fetched, &raw)
if err == sql.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, err
}
if now-fetched > ttl {
return nil, nil
}
var p Payload
if err := json.Unmarshal([]byte(raw), &p); err != nil {
return nil, err
}
return &p, nil
}
func (c *Cache) Put(key string, p Payload, now float64) error {
raw, err := json.Marshal(p)
if err != nil {
return err
}
_, err = c.db.Exec(
"INSERT OR REPLACE INTO responses (key, fetched, payload) VALUES (?, ?, ?)",
key, now, string(raw),
)
return err
}
func (c *Cache) LastCall() (*float64, error) {
var v float64
err := c.db.QueryRow("SELECT value FROM meta WHERE key = 'last_call'").Scan(&v)
if err == sql.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, err
}
return &v, nil
}
func (c *Cache) MarkCall(now float64) error {
_, err := c.db.Exec("INSERT OR REPLACE INTO meta (key, value) VALUES ('last_call', ?)", now)
return err
}