package storage import ( "context" "database/sql" "time" "gitea.inhome.blapointe.com/local/storage/resolve" _ "modernc.org/sqlite" ) type SQLite struct { *sql.DB } func NewSQLite(path string) (*SQLite, error) { db, err := sql.Open("sqlite", path) if err != nil { return nil, err } ctx, can := context.WithTimeout(context.Background(), time.Minute) defer can() if err := db.PingContext(ctx); err != nil { db.Close() return nil, err } if _, err := db.ExecContext(ctx, ` CREATE TABLE IF NOT EXISTS data ( namespace TEXT, key TEXT, value TEXT ); CREATE UNIQUE INDEX IF NOT EXISTS data_pk ON data (namespace, key); `); err != nil { db.Close() return nil, err } return &SQLite{ DB: db, }, nil } func (sqlite *SQLite) Get(key string, ns ...string) ([]byte, error) { namespace := resolve.Namespace(ns) row := sqlite.QueryRow(`SELECT value FROM data WHERE namespace=$1 AND key=$2`, namespace, key) var value string if err := row.Scan(&value); err != nil { return nil, err } return []byte(value), row.Err() } func (sqlite *SQLite) Set(key string, value []byte, ns ...string) error { namespace := resolve.Namespace(ns) _, err := sqlite.Exec(`INSERT INTO data (namespace, key, value) VALUES ($1, $2, $3)`, namespace, key, string(value)) return err } func (sqlite *SQLite) List(ns []string, limits ...string) ([]string, error) { namespace := resolve.Namespace(ns) rows, err := sqlite.Query(`SELECT key FROM data WHERE namespace=$1`, namespace) if err != nil { return nil, err } result := []string{} for rows.Next() { var a string if err := rows.Scan(&a); err != nil { return nil, err } result = append(result, a) } return result, rows.Err() }