Files
kandev/apps/backend/internal/system/settings/store.go
T

88 lines
2.1 KiB
Go

package settings
import (
"context"
"database/sql"
"time"
"github.com/jmoiron/sqlx"
"github.com/kandev/kandev/internal/db"
"github.com/kandev/kandev/internal/db/dialect"
)
// Store persists install-wide Kandev settings that are not scoped to a user,
// workspace, agent profile, or integration.
type Store struct {
db *sqlx.DB
ro *sqlx.DB
}
func NewStore(pool *db.Pool) (*Store, error) {
store := &Store{db: pool.Writer(), ro: pool.Reader()}
if err := store.initSchema(); err != nil {
return nil, err
}
return store, nil
}
func (s *Store) initSchema() error {
if _, err := s.db.Exec(`
CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY,
value TEXT NOT NULL,
updated_at TIMESTAMP NOT NULL
);
`); err != nil {
return err
}
return s.migrateLegacySystemSettings()
}
func (s *Store) migrateLegacySystemSettings() error {
if dialect.IsPostgres(s.db.DriverName()) {
return nil
}
var exists int
if err := s.db.QueryRow(`
SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name = 'system_settings'
`).Scan(&exists); err != nil {
return err
}
if exists == 0 {
return nil
}
_, err := s.db.Exec(`
INSERT OR IGNORE INTO settings (key, value, updated_at)
SELECT key, value, updated_at FROM system_settings
`)
return err
}
func (s *Store) Get(ctx context.Context, key string) ([]byte, bool, error) {
var raw string
err := s.ro.QueryRowContext(ctx, s.ro.Rebind(`SELECT value FROM settings WHERE key = ?`), key).Scan(&raw)
if err != nil {
if err == sql.ErrNoRows {
return nil, false, nil
}
return nil, false, err
}
return []byte(raw), true, nil
}
func (s *Store) Save(ctx context.Context, key string, value []byte) error {
_, err := s.db.ExecContext(ctx, s.db.Rebind(`
INSERT INTO settings (key, value, updated_at)
VALUES (?, ?, ?)
ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at
`), key, string(value), time.Now().UTC())
return err
}
func (s *Store) Delete(ctx context.Context, key string) error {
_, err := s.db.ExecContext(ctx, s.db.Rebind(`DELETE FROM settings WHERE key = ?`), key)
return err
}