Files
jukebox_maker/internal/db/db.go
Michael Chus 29f3ad9576 Add jukebox_maker web app v1.0
Go web application for filling USB drives with media files.
Runs in Docker on Unraid with /media, /mnt/usb, /config volumes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 21:33:43 +03:00

93 lines
1.9 KiB
Go

package db
import (
"database/sql"
"time"
_ "modernc.org/sqlite"
)
type DB struct {
sql *sql.DB
}
type CopyRecord struct {
DiskID string
SourcePath string
FileSize int64
CopiedAt time.Time
}
func Open(path string) (*DB, error) {
conn, err := sql.Open("sqlite", path+"?_journal=WAL&_timeout=5000")
if err != nil {
return nil, err
}
conn.SetMaxOpenConns(1)
d := &DB{sql: conn}
if err := d.migrate(); err != nil {
conn.Close()
return nil, err
}
return d, nil
}
func (d *DB) Close() error {
return d.sql.Close()
}
func (d *DB) migrate() error {
_, err := d.sql.Exec(`
CREATE TABLE IF NOT EXISTS copy_history (
id INTEGER PRIMARY KEY AUTOINCREMENT,
disk_id TEXT NOT NULL,
source_path TEXT NOT NULL,
file_size INTEGER NOT NULL DEFAULT 0,
copied_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ','now'))
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_copy_history_disk_path
ON copy_history (disk_id, source_path);
`)
return err
}
func (d *DB) WasCopied(diskID, sourcePath string) (bool, error) {
var n int
err := d.sql.QueryRow(
`SELECT COUNT(*) FROM copy_history WHERE disk_id=? AND source_path=?`,
diskID, sourcePath,
).Scan(&n)
return n > 0, err
}
func (d *DB) RecordCopy(rec CopyRecord) error {
t := rec.CopiedAt
if t.IsZero() {
t = time.Now().UTC()
}
_, err := d.sql.Exec(
`INSERT OR IGNORE INTO copy_history (disk_id, source_path, file_size, copied_at) VALUES (?,?,?,?)`,
rec.DiskID, rec.SourcePath, rec.FileSize, t.Format(time.RFC3339),
)
return err
}
func (d *DB) CopiedPaths(diskID string) (map[string]struct{}, error) {
rows, err := d.sql.Query(
`SELECT source_path FROM copy_history WHERE disk_id=?`, diskID,
)
if err != nil {
return nil, err
}
defer rows.Close()
m := make(map[string]struct{})
for rows.Next() {
var p string
if err := rows.Scan(&p); err != nil {
return nil, err
}
m[p] = struct{}{}
}
return m, rows.Err()
}