diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2023-02-24 12:42:40 +0100 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2023-02-24 12:42:40 +0100 |
| commit | 1ca647ffd4f5170a3d8e732d515f6c1d2ec47c3a (patch) | |
| tree | ffe664229ffc87c1d4f233eb27da8576bf5bce6b /localBackend.go | |
| parent | 150f60664fa5267de3fb80cdf8c6cc9572299668 (diff) | |
| download | WRMS-web-overhaul.tar.gz WRMS-web-overhaul.zip | |
use in-memory sqlite database for local backendv0.0.6-alphaweb-overhaul
Diffstat (limited to 'localBackend.go')
| -rw-r--r-- | localBackend.go | 103 |
1 files changed, 80 insertions, 23 deletions
diff --git a/localBackend.go b/localBackend.go index 2dbd4fd..1e50817 100644 --- a/localBackend.go +++ b/localBackend.go @@ -1,44 +1,80 @@ package main import ( + "database/sql" + "fmt" "os" "path" "path/filepath" "strings" - "sync" "github.com/dhowden/tag" + _ "github.com/mattn/go-sqlite3" "muhq.space/go/wrms/llog" ) +const DB_URL = "file:songs?mode=memory&cache=shared" + type LocalBackend struct { musicDir string - lock sync.RWMutex - songs map[string]*Song + db *sql.DB } func NewLocalBackend(musicDir string) *LocalBackend { - b := LocalBackend{musicDir, sync.RWMutex{}, map[string]*Song{}} + b := LocalBackend{musicDir: musicDir} + + var err error + b.db, err = sql.Open("sqlite3", DB_URL) + if err != nil { + llog.Fatal("Opening in-memory db failed: %q", err) + } + + sqlStmt := ` + CREATE TABLE songs ( + Uri text NOT NULL PRIMARY KEY, + Title text, + Artist text + ); + ` + _, err = b.db.Exec(sqlStmt) + if err != nil { + llog.Fatal("%q: %s", err, sqlStmt) + } go b.findSongs() return &b } -func (b *LocalBackend) insert(song *Song) { - b.lock.Lock() - defer b.lock.Unlock() - b.songs[song.Uri] = song +func (b *LocalBackend) insert(songs []*Song) { + llog.Debug("Inserting %d songs into local DB", len(songs)) + tx, err := b.db.Begin() + if err != nil { + llog.Fatal("Starting insert transaction failed: %q", err) + } + + stmt, err := tx.Prepare("INSERT INTO songs(Uri, Title, Artist) VALUES(?, ?, ?)") + if err != nil { + llog.Fatal("Preparing inser statement failed: %q", err) + } + defer stmt.Close() + + for _, song := range songs { + _, err = stmt.Exec(song.Uri, song.Title, song.Artist) + if err != nil { + llog.Fatal("Executing insert statement failed: %q", err) + } + } + + err = tx.Commit() + if err != nil { + llog.Fatal("Commiting insert transaction failed: %q", err) + } } func (b *LocalBackend) findSongs() { llog.Debug("Starting song search under: %s", b.musicDir) - // Insert some Songs - song := NewSong("No!", "Bukahara", "local", "Bukahara/Phantasma/01-No!.ogg") - - for _, s := range []*Song{&song} { - b.insert(s) - } + var songs []*Song err := filepath.Walk(b.musicDir, func(p string, finfo os.FileInfo, err error) error { if err != nil { @@ -72,32 +108,53 @@ func (b *LocalBackend) findSongs() { } s := NewSong(m.Title(), m.Artist(), "local", p) - b.insert(&s) + songs = append(songs, &s) return nil }) if err != nil { llog.Error("error walking the path %q: %v", b.musicDir, err) } + + b.insert(songs) } func (b *LocalBackend) Play(song *Song, player *Player) { player.PlayUri("file://" + song.Uri) } -func (b *LocalBackend) Search(keyword string) []Song { +func (b *LocalBackend) Search(keyword string) (results []Song) { pattern := strings.ToLower(keyword) - results := []Song{} - b.lock.RLock() - defer b.lock.RUnlock() + query := fmt.Sprintf("SELECT * FROM songs WHERE Title LIKE '%%%s%%' OR Artist LIKE '%%%s%%'", + pattern, pattern) + llog.Debug("Searching in local DB using: %q", query) + rows, err := b.db.Query(query) + if err != nil { + llog.Error("Building search query %q failed: %q", query, err) + return + } + defer rows.Close() - for _, s := range b.songs { - if strings.Contains(strings.ToLower(s.Title), pattern) || - strings.Contains(strings.ToLower(s.Artist), pattern) { - results = append(results, *s) + for rows.Next() { + var uri string + var title string + var artist string + + err = rows.Scan(&uri, &title, &artist) + if err != nil { + llog.Warning("Scanning query result failed: %q", err) } + + results = append(results, NewSong(title, artist, "local", uri)) } + err = rows.Err() + if err != nil { + llog.Error("Iterator returned error: %q", err) + } + + llog.Debug("Local search returned %d results", len(results)) + return results } |
