96 lines
3.1 KiB
Go
96 lines
3.1 KiB
Go
package database
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
)
|
|
|
|
// GetSetting reads a key from the settings table, returning def if unset.
|
|
func GetSetting(db *sql.DB, key, def string) string {
|
|
var v string
|
|
err := db.QueryRow(`SELECT value FROM settings WHERE key = ?`, key).Scan(&v)
|
|
if err != nil {
|
|
return def
|
|
}
|
|
return v
|
|
}
|
|
|
|
func SetSetting(db *sql.DB, key, value string) error {
|
|
_, err := db.Exec(`INSERT INTO settings (key, value, updated_at) VALUES (?, ?, strftime('%Y-%m-%dT%H:%M:%fZ','now'))
|
|
ON CONFLICT (key) DO UPDATE SET value=excluded.value, updated_at=excluded.updated_at`, key, value)
|
|
return err
|
|
}
|
|
|
|
// --- Scan state ---
|
|
|
|
type ScanState struct {
|
|
ID string
|
|
MusicFolderID string
|
|
Status string
|
|
StartedAt sql.NullString
|
|
FinishedAt sql.NullString
|
|
FilesSeen int
|
|
FilesTotalEstimate int
|
|
FilesAdded int
|
|
FilesUpdated int
|
|
FilesRemoved int
|
|
ErrorMessage string
|
|
LastFullScanAt sql.NullString
|
|
}
|
|
|
|
const scanStateSelect = `SELECT id, music_folder_id, status, started_at, finished_at, files_seen, files_total_estimate, files_added, files_updated, files_removed, error_message, last_full_scan_at FROM scan_state`
|
|
|
|
func GetScanState(db *sql.DB, folderID string) (*ScanState, error) {
|
|
var s ScanState
|
|
err := db.QueryRow(scanStateSelect+` WHERE music_folder_id = ?`, folderID).Scan(
|
|
&s.ID, &s.MusicFolderID, &s.Status, &s.StartedAt, &s.FinishedAt, &s.FilesSeen, &s.FilesTotalEstimate,
|
|
&s.FilesAdded, &s.FilesUpdated, &s.FilesRemoved, &s.ErrorMessage, &s.LastFullScanAt)
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return nil, ErrNotFound
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &s, nil
|
|
}
|
|
|
|
func ListScanStates(db *sql.DB) ([]*ScanState, error) {
|
|
rows, err := db.Query(scanStateSelect)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var out []*ScanState
|
|
for rows.Next() {
|
|
var s ScanState
|
|
if err := rows.Scan(&s.ID, &s.MusicFolderID, &s.Status, &s.StartedAt, &s.FinishedAt, &s.FilesSeen, &s.FilesTotalEstimate,
|
|
&s.FilesAdded, &s.FilesUpdated, &s.FilesRemoved, &s.ErrorMessage, &s.LastFullScanAt); err != nil {
|
|
return nil, err
|
|
}
|
|
out = append(out, &s)
|
|
}
|
|
return out, rows.Err()
|
|
}
|
|
|
|
func StartScan(db *sql.DB, folderID string) error {
|
|
_, err := db.Exec(`UPDATE scan_state SET status='scanning', started_at=strftime('%Y-%m-%dT%H:%M:%fZ','now'), finished_at=NULL,
|
|
files_seen=0, files_added=0, files_updated=0, files_removed=0, error_message='' WHERE music_folder_id=?`, folderID)
|
|
return err
|
|
}
|
|
|
|
func UpdateScanProgress(db *sql.DB, folderID string, filesSeen, filesAdded, filesUpdated int) error {
|
|
_, err := db.Exec(`UPDATE scan_state SET files_seen=?, files_added=?, files_updated=? WHERE music_folder_id=?`,
|
|
filesSeen, filesAdded, filesUpdated, folderID)
|
|
return err
|
|
}
|
|
|
|
func FinishScan(db *sql.DB, folderID string, filesRemoved int, errMsg string) error {
|
|
status := "idle"
|
|
if errMsg != "" {
|
|
status = "error"
|
|
}
|
|
_, err := db.Exec(`UPDATE scan_state SET status=?, finished_at=strftime('%Y-%m-%dT%H:%M:%fZ','now'), files_removed=?, error_message=?,
|
|
last_full_scan_at=strftime('%Y-%m-%dT%H:%M:%fZ','now') WHERE music_folder_id=?`, status, filesRemoved, errMsg, folderID)
|
|
return err
|
|
}
|