func (s *SqliteBackend) AllArtistsByTitle() ([]Artist, error) {
	return s.artistQuery("SELECT * FROM artists ORDER BY title;")
}
AllArtistsByTitle loads a slice of all Artist structs from the database, sorted alphabetically by title
package data
import (
	"database/sql"
	"log"
	"os"
	"path"
	"github.com/mdlayher/wavepipe/common"
	"github.com/jmoiron/sqlx"
	_ "github.com/mattn/go-sqlite3"
)
type SqliteBackend struct {
	Path string
	db   *sqlx.DB
}
func (s *SqliteBackend) DSN(path string) {
	s.Path = common.ExpandHomeDir(path)
}
func (s *SqliteBackend) Setup() error {
	_, err := os.Stat(s.Path)
	if err == nil {
		return nil
	}
	if !os.IsNotExist(err) {
		return err
	}
	log.Println("db: creating new database file:", s.Path)
	dir := path.Dir(s.Path) + "/"
	file := path.Base(s.Path)
	if err := os.MkdirAll(dir, 0775); err != nil {
		return err
	}
	dbBuf, err := Asset("res/sqlite/wavepipe.db")
	if err != nil {
		return err
	}
	dest, err := os.Create(dir + file)
	if err != nil {
		return err
	}
	if _, err := dest.Write(dbBuf); err != nil {
		return err
	}
	if err := dest.Close(); err != nil {
		return err
	}
	return nil
}
func (s *SqliteBackend) Open() error {
	db, err := sqlx.Open("sqlite3", s.Path)
	if err != nil {
		return err
	}
	if _, err := db.Exec("PRAGMA synchronous = OFF;"); err != nil {
		return err
	}
	if _, err := db.Exec("PRAGMA journal_mode = MEMORY;"); err != nil {
		return err
	}
	s.db = db
	return nil
}
func (s *SqliteBackend) Close() error {
	return s.db.Close()
}
func (s *SqliteBackend) ArtInPath(path string) ([]Art, error) {
	return s.artQuery("SELECT * FROM art WHERE file_name LIKE ?;", path+"%")
}
func (s *SqliteBackend) ArtNotInPath(path string) ([]Art, error) {
	return s.artQuery("SELECT * FROM art WHERE file_name NOT LIKE ?;", path+"%")
}
func (s *SqliteBackend) CountArt() (int64, error) {
	return s.integerQuery("SELECT COUNT(*) AS int FROM art;")
}
func (s *SqliteBackend) DeleteArt(a *Art) error {
	tx := s.db.MustBegin()
	tx.Exec("DELETE FROM art WHERE id = ?;", a.ID)
	tx.Exec("UPDATE songs SET art_id = 0 WHERE art_id = ?;", a.ID)
	return tx.Commit()
}
func (s *SqliteBackend) LoadArt(a *Art) error {
	if a.ID != 0 {
		if err := s.db.Get(a, "SELECT * FROM art WHERE id = ?;", a.ID); err != nil {
			return err
		}
		return nil
	}
	if err := s.db.Get(a, "SELECT * FROM art WHERE file_name = ?;", a.FileName); err != nil {
		return err
	}
	return nil
}
func (s *SqliteBackend) SaveArt(a *Art) error {
	query := "INSERT INTO art (`file_name`, `file_size`, `last_modified`) VALUES (?, ?, ?);"
	tx := s.db.MustBegin()
	tx.Exec(query, a.FileName, a.FileSize, a.LastModified)
	if err := tx.Commit(); err != nil {
		return err
	}
	if a.ID == 0 {
		if err := s.LoadArt(a); err != nil {
			return err
		}
	}
	return nil
}
func (s *SqliteBackend) AllArtists() ([]Artist, error) {
	return s.artistQuery("SELECT * FROM artists;")
}