initial commit
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Settings returns every stored setting as a key/value map.
|
||||
func (db *DB) Settings(ctx context.Context) (map[string]string, error) {
|
||||
rows, err := db.QueryContext(ctx, `SELECT key, value FROM settings`)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load settings: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
out := map[string]string{}
|
||||
for rows.Next() {
|
||||
var k, v string
|
||||
if err := rows.Scan(&k, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out[k] = v
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
// Setting reads a single setting. It returns ("", false, nil) when unset.
|
||||
func (db *DB) Setting(ctx context.Context, key string) (string, bool, error) {
|
||||
var v string
|
||||
err := db.QueryRowContext(ctx, `SELECT value FROM settings WHERE key = ?`, key).Scan(&v)
|
||||
switch {
|
||||
case err == sql.ErrNoRows:
|
||||
return "", false, nil
|
||||
case err != nil:
|
||||
return "", false, fmt.Errorf("read setting %s: %w", key, err)
|
||||
}
|
||||
return v, true, nil
|
||||
}
|
||||
|
||||
// SetSetting writes one setting.
|
||||
func (db *DB) SetSetting(ctx context.Context, key, value string) error {
|
||||
_, err := db.ExecContext(ctx, `
|
||||
INSERT INTO settings (key, value, updated_at) VALUES (?, ?, unixepoch())
|
||||
ON CONFLICT (key) DO UPDATE SET value = excluded.value, updated_at = unixepoch()`,
|
||||
key, value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("write setting %s: %w", key, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetSettings writes several settings atomically.
|
||||
func (db *DB) SetSettings(ctx context.Context, values map[string]string) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return db.InTx(ctx, func(tx *sql.Tx) error {
|
||||
stmt, err := tx.PrepareContext(ctx, `
|
||||
INSERT INTO settings (key, value, updated_at) VALUES (?, ?, unixepoch())
|
||||
ON CONFLICT (key) DO UPDATE SET value = excluded.value, updated_at = unixepoch()`)
|
||||
if err != nil {
|
||||
return fmt.Errorf("prepare setting write: %w", err)
|
||||
}
|
||||
defer stmt.Close()
|
||||
for k, v := range values {
|
||||
if _, err := stmt.ExecContext(ctx, k, v); err != nil {
|
||||
return fmt.Errorf("write setting %s: %w", k, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteSetting removes a setting, reverting it to its built-in default.
|
||||
func (db *DB) DeleteSetting(ctx context.Context, key string) error {
|
||||
_, err := db.ExecContext(ctx, `DELETE FROM settings WHERE key = ?`, key)
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user