package database import ( "database/sql" "errors" "time" "git.noroutes.net/NoRoutes/vibetunes/internal/idgen" ) type MusicFolder struct { ID string Name string Path string Kind string Enabled bool CreatedAt time.Time } func CreateMusicFolder(db *sql.DB, name, path, kind string) (*MusicFolder, error) { id := idgen.New("mf") _, err := db.Exec(`INSERT INTO music_folders (id, name, path, kind) VALUES (?, ?, ?, ?)`, id, name, path, kind) if err != nil { return nil, err } if _, err := db.Exec(`INSERT INTO scan_state (id, music_folder_id) VALUES (?, ?)`, idgen.New("sc"), id); err != nil { return nil, err } return GetMusicFolder(db, id) } func GetMusicFolder(db *sql.DB, id string) (*MusicFolder, error) { return scanFolder(db.QueryRow(`SELECT id, name, path, kind, enabled, created_at FROM music_folders WHERE id = ?`, id)) } func scanFolder(row *sql.Row) (*MusicFolder, error) { var f MusicFolder var enabled int var createdAt string err := row.Scan(&f.ID, &f.Name, &f.Path, &f.Kind, &enabled, &createdAt) if errors.Is(err, sql.ErrNoRows) { return nil, ErrNotFound } if err != nil { return nil, err } f.Enabled = enabled != 0 f.CreatedAt, _ = parseTime(createdAt) return &f, nil } func ListMusicFolders(db *sql.DB) ([]*MusicFolder, error) { rows, err := db.Query(`SELECT id, name, path, kind, enabled, created_at FROM music_folders ORDER BY name COLLATE NOCASE`) if err != nil { return nil, err } defer rows.Close() var out []*MusicFolder for rows.Next() { var f MusicFolder var enabled int var createdAt string if err := rows.Scan(&f.ID, &f.Name, &f.Path, &f.Kind, &enabled, &createdAt); err != nil { return nil, err } f.Enabled = enabled != 0 f.CreatedAt, _ = parseTime(createdAt) out = append(out, &f) } return out, rows.Err() } func SetMusicFolderEnabled(db *sql.DB, id string, enabled bool) error { _, err := db.Exec(`UPDATE music_folders SET enabled = ? WHERE id = ?`, boolInt(enabled), id) return err } func DeleteMusicFolder(db *sql.DB, id string) error { _, err := db.Exec(`DELETE FROM music_folders WHERE id = ?`, id) return err }