feat: Rename game to soundtrack throughout codebase

- Database migration: rename game table to soundtrack
- Rename game_name to soundtrack_name, game_id to soundtrack_id
- Update all SQL queries in soundtrack.sql, song.sql, song_list.sql, statistics.sql
- Regenerate sqlc code (soundtrack.sql.go, song.sql.go, etc.)
- Update backend: music.go, sync.go, statistics.go
- Update server: musicHandler.go, syncHandler.go, routes.go
- Update frontend: hello.go
- Keep URL paths as /games for backward compatibility

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
2026-06-01 20:23:05 +02:00
parent c60f40d7e3
commit cec408187d
20 changed files with 760 additions and 694 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ func FindGameWebHandler(w http.ResponseWriter, r *http.Request) {
func search(searchText string) {
games_added = nil
games := backend.GetAllGames()
games := backend.GetAllSoundtracks()
for _, game := range games {
if is_match_exact(searchText, game) {
add_game(game)
+26 -26
View File
@@ -22,7 +22,7 @@ type SongInfo struct {
var currentSong = -1
var gamesNew []repository.Game
var gamesNew []repository.Soundtrack
var songQueNew []repository.Song
@@ -37,10 +37,10 @@ func initRepo() {
}
}
func getAllGames() []repository.Game {
func getAllGames() []repository.Soundtrack {
if len(gamesNew) == 0 {
initRepo()
gamesNew, _ = BackendRepo().FindAllGames(BackendCtx())
gamesNew, _ = BackendRepo().FindAllSoundtracks(BackendCtx())
}
return gamesNew
@@ -59,7 +59,7 @@ func Reset() {
songQueNew = nil
currentSong = -1
initRepo()
gamesNew, _ = BackendRepo().FindAllGames(BackendCtx())
gamesNew, _ = BackendRepo().FindAllSoundtracks(BackendCtx())
}
func AddLatestToQue() {
@@ -77,8 +77,8 @@ func AddLatestPlayed() {
currentSongData := songQueNew[currentSong]
initRepo()
BackendRepo().AddGamePlayed(BackendCtx(), currentSongData.GameID)
BackendRepo().AddSongPlayed(BackendCtx(), repository.AddSongPlayedParams{GameID: currentSongData.GameID, SongName: currentSongData.SongName})
BackendRepo().AddSoundtrackPlayed(BackendCtx(), currentSongData.SoundtrackID)
BackendRepo().AddSongPlayed(BackendCtx(), repository.AddSongPlayedParams{SoundtrackID: currentSongData.SoundtrackID, SongName: currentSongData.SongName})
}
func SetPlayed(songNumber int) {
@@ -87,8 +87,8 @@ func SetPlayed(songNumber int) {
}
songData := songQueNew[songNumber]
initRepo()
BackendRepo().AddGamePlayed(BackendCtx(), songData.GameID)
BackendRepo().AddSongPlayed(BackendCtx(), repository.AddSongPlayedParams{GameID: songData.GameID, SongName: songData.SongName})
BackendRepo().AddSoundtrackPlayed(BackendCtx(), songData.SoundtrackID)
BackendRepo().AddSongPlayed(BackendCtx(), repository.AddSongPlayedParams{SoundtrackID: songData.SoundtrackID, SongName: songData.SongName})
}
func GetRandomSong() string {
@@ -105,7 +105,7 @@ func GetRandomSong() string {
func GetRandomSongLowChance() string {
getAllGames()
var listOfGames []repository.Game
var listOfGames []repository.Soundtrack
var averagePlayed = getAveragePlayed()
@@ -131,7 +131,7 @@ func GetRandomSongClassic() string {
var listOfAllSongs []repository.Song
for _, game := range gamesNew {
songList, _ := BackendRepo().FindSongsFromGame(BackendCtx(), game.ID)
songList, _ := BackendRepo().FindSongsFromSoundtrack(BackendCtx(), game.ID)
listOfAllSongs = append(listOfAllSongs, songList...)
}
@@ -139,13 +139,13 @@ func GetRandomSongClassic() string {
var song repository.Song
for !songFound {
song = listOfAllSongs[rand.Intn(len(listOfAllSongs))]
gameData, err := BackendRepo().GetGameById(BackendCtx(), song.GameID)
gameData, err := BackendRepo().GetSoundtrackById(BackendCtx(), song.SoundtrackID)
if err != nil {
BackendRepo().RemoveBrokenSong(BackendCtx(), song.Path)
logging.GetLogger().Warn("Song not found, removed from database",
zap.String("song", song.SongName),
zap.String("game", gameData.GameName),
zap.String("game", gameData.SoundtrackName),
zap.String("filename", *song.FileName))
continue
}
@@ -157,7 +157,7 @@ func GetRandomSongClassic() string {
BackendRepo().RemoveBrokenSong(BackendCtx(), song.Path)
logging.GetLogger().Warn("Song not found, removed from database",
zap.String("song", song.SongName),
zap.String("game", gameData.GameName),
zap.String("game", gameData.SoundtrackName),
zap.String("filename", *song.FileName))
} else {
songFound = true
@@ -180,7 +180,7 @@ func GetSongInfo() SongInfo {
currentGameData := getCurrentGame(currentSongData)
return SongInfo{
Game: currentGameData.GameName,
Game: currentGameData.SoundtrackName,
GamePlayed: currentGameData.TimesPlayed,
Song: currentSongData.SongName,
SongPlayed: currentSongData.TimesPlayed,
@@ -195,7 +195,7 @@ func GetPlayedSongs() []SongInfo {
for i, song := range songQueNew {
gameData := getCurrentGame(song)
songList = append(songList, SongInfo{
Game: gameData.GameName,
Game: gameData.SoundtrackName,
GamePlayed: gameData.TimesPlayed,
Song: song.SongName,
SongPlayed: song.TimesPlayed,
@@ -217,22 +217,22 @@ func GetSong(song string) string {
return songData.Path
}
func GetAllGames() []string {
func GetAllSoundtracks() []string {
getAllGames()
var jsonArray []string
for _, game := range gamesNew {
jsonArray = append(jsonArray, game.GameName)
jsonArray = append(jsonArray, game.SoundtrackName)
}
return jsonArray
}
func GetAllGamesRandom() []string {
func GetAllSoundtracksRandom() []string {
getAllGames()
var jsonArray []string
for _, game := range gamesNew {
jsonArray = append(jsonArray, game.GameName)
jsonArray = append(jsonArray, game.SoundtrackName)
}
rand.Shuffle(len(jsonArray), func(i, j int) { jsonArray[i], jsonArray[j] = jsonArray[j], jsonArray[i] })
return jsonArray
@@ -266,12 +266,12 @@ func GetPreviousSong() string {
}
}
func getSongFromList(games []repository.Game) repository.Song {
func getSongFromList(games []repository.Soundtrack) repository.Song {
songFound := false
var song repository.Song
for !songFound {
game := getRandomGame(games)
songs, _ := BackendRepo().FindSongsFromGame(BackendCtx(), game.ID)
songs, _ := BackendRepo().FindSongsFromSoundtrack(BackendCtx(), game.ID)
if len(songs) == 0 {
continue
}
@@ -285,7 +285,7 @@ func getSongFromList(games []repository.Game) repository.Song {
BackendRepo().RemoveBrokenSong(BackendCtx(), song.Path)
logging.GetLogger().Warn("Song not found, removed from database",
zap.String("song", song.SongName),
zap.String("game", game.GameName),
zap.String("game", game.SoundtrackName),
zap.Any("filename", song.FileName))
} else {
songFound = true
@@ -299,13 +299,13 @@ func getSongFromList(games []repository.Game) repository.Song {
return song
}
func getCurrentGame(currentSongData repository.Song) repository.Game {
func getCurrentGame(currentSongData repository.Song) repository.Soundtrack {
for _, game := range gamesNew {
if game.ID == currentSongData.GameID {
if game.ID == currentSongData.SoundtrackID {
return game
}
}
return repository.Game{}
return repository.Soundtrack{}
}
func getAveragePlayed() int32 {
@@ -317,6 +317,6 @@ func getAveragePlayed() int32 {
return sum / int32(len(gamesNew))
}
func getRandomGame(listOfGames []repository.Game) repository.Game {
func getRandomGame(listOfGames []repository.Soundtrack) repository.Soundtrack {
return listOfGames[rand.Intn(len(listOfGames))]
}
+37 -37
View File
@@ -11,17 +11,17 @@ import (
// GameWithSongs represents a game with its songs for statistics
type GameWithSongs struct {
GameID int32 `json:"game_id"`
GameName string `json:"game_name"`
GamePlayed int32 `json:"game_played"`
GameLastPlayed *time.Time `json:"game_last_played,omitempty"`
SoundtrackID int32 `json:"game_id"`
SoundtrackName string `json:"game_name"`
SoundtrackPlayed int32 `json:"game_played"`
SoundtrackLastPlayed *time.Time `json:"game_last_played,omitempty"`
Songs []SongInfoForStats `json:"songs"`
}
// SongInfoForStats represents a song with game info for statistics
type SongInfoForStats struct {
GameID int32 `json:"game_id"`
GameName string `json:"game_name"`
SoundtrackID int32 `json:"game_id"`
SoundtrackName string `json:"game_name"`
SongName string `json:"song_name"`
Path string `json:"path"`
TimesPlayed int32 `json:"times_played"`
@@ -72,10 +72,10 @@ func (h *StatisticsHandler) GetMostPlayedGamesWithSongs(limit int32) ([]GameWith
}
}
result = append(result, GameWithSongs{
GameID: row.GameID,
GameName: row.GameName,
GamePlayed: row.GamePlayed,
GameLastPlayed: row.GameLastPlayed,
SoundtrackID: row.SoundtrackID,
SoundtrackName: row.SoundtrackName,
SoundtrackPlayed: row.SoundtrackPlayed,
SoundtrackLastPlayed: row.SoundtrackLastPlayed,
Songs: songs,
})
}
@@ -101,10 +101,10 @@ func (h *StatisticsHandler) GetLeastPlayedGamesWithSongs(limit int32) ([]GameWit
}
}
result = append(result, GameWithSongs{
GameID: row.GameID,
GameName: row.GameName,
GamePlayed: row.GamePlayed,
GameLastPlayed: row.GameLastPlayed,
SoundtrackID: row.SoundtrackID,
SoundtrackName: row.SoundtrackName,
SoundtrackPlayed: row.SoundtrackPlayed,
SoundtrackLastPlayed: row.SoundtrackLastPlayed,
Songs: songs,
})
}
@@ -124,8 +124,8 @@ func (h *StatisticsHandler) GetMostPlayedSongsWithGame(limit int32) ([]SongInfoF
var result []SongInfoForStats
for _, row := range rows {
result = append(result, SongInfoForStats{
GameID: row.GameID,
GameName: row.GameName,
SoundtrackID: row.SoundtrackID,
SoundtrackName: row.SoundtrackName,
SongName: row.SongName,
Path: row.Path,
TimesPlayed: row.TimesPlayed,
@@ -148,8 +148,8 @@ func (h *StatisticsHandler) GetLeastPlayedSongsWithGame(limit int32) ([]SongInfo
var result []SongInfoForStats
for _, row := range rows {
result = append(result, SongInfoForStats{
GameID: row.GameID,
GameName: row.GameName,
SoundtrackID: row.SoundtrackID,
SoundtrackName: row.SoundtrackName,
SongName: row.SongName,
Path: row.Path,
TimesPlayed: row.TimesPlayed,
@@ -178,10 +178,10 @@ func (h *StatisticsHandler) GetNeverPlayedGames() ([]GameWithSongs, error) {
}
}
result = append(result, GameWithSongs{
GameID: row.GameID,
GameName: row.GameName,
GamePlayed: row.GamePlayed,
GameLastPlayed: nil,
SoundtrackID: row.SoundtrackID,
SoundtrackName: row.SoundtrackName,
SoundtrackPlayed: row.SoundtrackPlayed,
SoundtrackLastPlayed: nil,
Songs: songs,
})
}
@@ -207,10 +207,10 @@ func (h *StatisticsHandler) GetLastPlayedGames(limit int32) ([]GameWithSongs, er
}
}
result = append(result, GameWithSongs{
GameID: row.GameID,
GameName: row.GameName,
GamePlayed: row.GamePlayed,
GameLastPlayed: row.GameLastPlayed,
SoundtrackID: row.SoundtrackID,
SoundtrackName: row.SoundtrackName,
SoundtrackPlayed: row.SoundtrackPlayed,
SoundtrackLastPlayed: row.SoundtrackLastPlayed,
Songs: songs,
})
}
@@ -236,10 +236,10 @@ func (h *StatisticsHandler) GetOldestPlayedGames(limit int32) ([]GameWithSongs,
}
}
result = append(result, GameWithSongs{
GameID: row.GameID,
GameName: row.GameName,
GamePlayed: row.GamePlayed,
GameLastPlayed: row.GameLastPlayed,
SoundtrackID: row.SoundtrackID,
SoundtrackName: row.SoundtrackName,
SoundtrackPlayed: row.SoundtrackPlayed,
SoundtrackLastPlayed: row.SoundtrackLastPlayed,
Songs: songs,
})
}
@@ -257,13 +257,13 @@ func (h *StatisticsHandler) GetStatisticsSummary() (*StatisticsSummary, error) {
}
return &StatisticsSummary{
TotalGames: int64(row.TotalGames),
PlayedGames: int64(row.PlayedGames),
NeverPlayedGames: int64(row.NeverPlayedGames),
TotalGamePlays: int64(row.TotalGamePlays),
AvgGamePlays: float64(row.AvgGamePlays),
MaxGamePlays: int64(row.MaxGamePlays),
MinGamePlays: int64(row.MinGamePlays),
TotalGames: int64(row.TotalSoundtracks),
PlayedGames: int64(row.PlayedSoundtracks),
NeverPlayedGames: int64(row.NeverPlayedSoundtracks),
TotalGamePlays: int64(row.TotalSoundtrackPlays),
AvgGamePlays: float64(row.AvgSoundtrackPlays),
MaxGamePlays: int64(row.MaxSoundtrackPlays),
MinGamePlays: int64(row.MinSoundtrackPlays),
}, nil
}
+46 -46
View File
@@ -30,9 +30,9 @@ var start time.Time
var totalTime time.Duration
var timeSpent time.Duration
var allGames []repository.Game
var gamesBeforeSync []repository.Game
var gamesAfterSync []repository.Game
var allGames []repository.Soundtrack
var gamesBeforeSync []repository.Soundtrack
var gamesAfterSync []repository.Soundtrack
var gamesAdded []string
var gamesReAdded []string
var gamesChangedTitle map[string]string
@@ -80,7 +80,7 @@ func (gs GameStatus) String() string {
func ResetDB() {
repo.ClearSongs(BackendCtx())
repo.ClearGames(BackendCtx())
repo.ClearSoundtracks(BackendCtx())
}
func SyncProgress() ProgressResponse {
@@ -124,13 +124,13 @@ func SyncResult() SyncResponse {
for _, beforeGame := range gamesBeforeSync {
var found = false
for _, afterGame := range gamesAfterSync {
if beforeGame.GameName == afterGame.GameName {
if beforeGame.SoundtrackName == afterGame.SoundtrackName {
found = true
break
}
}
if !found {
gamesRemovedTemp = append(gamesRemovedTemp, beforeGame.GameName)
gamesRemovedTemp = append(gamesRemovedTemp, beforeGame.SoundtrackName)
}
}
@@ -169,12 +169,12 @@ func SyncResult() SyncResponse {
}
}
func SyncGamesNewFull() {
func SyncSoundtracksNewFull() {
syncGamesNew(true)
Reset()
}
func SyncGamesNewOnlyChanges() {
func SyncSoundtracksNewOnlyChanges() {
syncGamesNew(false)
Reset()
}
@@ -205,14 +205,14 @@ func syncGamesNew(full bool) {
catchedErrors = nil
brokenSongs = nil
gamesBeforeSync, err = repo.FindAllGames(BackendCtx())
handleError("FindAllGames Before", err, "")
gamesBeforeSync, err = repo.FindAllSoundtracks(BackendCtx())
handleError("FindAllSoundtracks Before", err, "")
logging.GetLogger().Info("Starting sync", zap.Int("games_before", len(gamesBeforeSync)))
allGames, err = repo.GetAllGamesIncludingDeleted(BackendCtx())
handleError("GetAllGamesIncludingDeleted", err, "")
err = repo.SetGameDeletionDate(BackendCtx())
handleError("SetGameDeletionDate", err, "")
allGames, err = repo.GetAllSoundtracksIncludingDeleted(BackendCtx())
handleError("GetAllSoundtracksIncludingDeleted", err, "")
err = repo.SetSoundtrackDeletionDate(BackendCtx())
handleError("SetSoundtrackDeletionDate", err, "")
directories, err := os.ReadDir(musicPath)
if err != nil {
@@ -236,8 +236,8 @@ func syncGamesNew(full bool) {
syncWg.Wait()
checkBrokenSongsNew()
gamesAfterSync, err = repo.FindAllGames(BackendCtx())
handleError("FindAllGames After", err, "")
gamesAfterSync, err = repo.FindAllSoundtracks(BackendCtx())
handleError("FindAllSoundtracks After", err, "")
finished := time.Now()
totalTime = finished.Sub(start)
@@ -288,28 +288,28 @@ func syncGameNew(file os.DirEntry, foldersToSkip []string, baseDir string, full
dirHash := getHashForDir(gameDir)
var status GameStatus = NewGame
var oldGame repository.Game
var oldGame repository.Soundtrack
var id int32 = -1
//fmt.Printf("Games before: %d\n", len(gamesBeforeSync))
for _, currentGame := range allGames {
oldGame = currentGame
//fmt.Printf("%s | %s\n", oldGame.GameName, oldGame.Hash)
if oldGame.GameName == file.Name() && oldGame.Hash == dirHash {
//fmt.Printf("%s | %s\n", oldGame.SoundtrackName, oldGame.Hash)
if oldGame.SoundtrackName == file.Name() && oldGame.Hash == dirHash {
status = NotChanged
id = oldGame.ID
//fmt.Printf("Game not changed\n")
break
} else if oldGame.GameName == file.Name() && oldGame.Hash != dirHash {
} else if oldGame.SoundtrackName == file.Name() && oldGame.Hash != dirHash {
status = GameChanged
id = oldGame.ID
//fmt.Printf("Game changed\n")
break
} else if oldGame.GameName != file.Name() && oldGame.Hash == dirHash {
} else if oldGame.SoundtrackName != file.Name() && oldGame.Hash == dirHash {
status = TitleChanged
id = oldGame.ID
//fmt.Printf("GameName changed\n")
//fmt.Printf("SoundtrackName changed\n")
break
}
}
@@ -335,8 +335,8 @@ func syncGameNew(file os.DirEntry, foldersToSkip []string, baseDir string, full
break
}
}
err = repo.InsertGameWithExistingId(BackendCtx(), repository.InsertGameWithExistingIdParams{ID: id, GameName: file.Name(), Path: gameDir, Hash: dirHash})
handleError("InsertGameWithExistingId", err, "")
err = repo.InsertSoundtrackWithExistingId(BackendCtx(), repository.InsertSoundtrackWithExistingIdParams{ID: id, SoundtrackName: file.Name(), Path: gameDir, Hash: dirHash})
handleError("InsertSoundtrackWithExistingId", err, "")
if err != nil {
logging.GetLogger().Debug("Game already exists, removing old ID file",
zap.Int32("id", id),
@@ -369,24 +369,24 @@ func syncGameNew(file os.DirEntry, foldersToSkip []string, baseDir string, full
zap.String("game", file.Name()),
zap.String("hash", dirHash),
zap.String("status", status.String()))
err = repo.UpdateGameHash(BackendCtx(), repository.UpdateGameHashParams{Hash: dirHash, ID: id})
handleError("UpdateGameHash", err, "")
err = repo.UpdateSoundtrackHash(BackendCtx(), repository.UpdateSoundtrackHashParams{Hash: dirHash, ID: id})
handleError("UpdateSoundtrackHash", err, "")
gamesChangedContent = append(gamesChangedContent, file.Name())
newCheckSongs(entries, gameDir, id)
case TitleChanged:
logging.GetLogger().Debug("Game title changed",
zap.Int32("id", id),
zap.String("oldName", oldGame.GameName),
zap.String("oldName", oldGame.SoundtrackName),
zap.String("newName", file.Name()),
zap.String("hash", dirHash),
zap.String("status", status.String()))
err = repo.UpdateGameName(BackendCtx(), repository.UpdateGameNameParams{Name: file.Name(), Path: gameDir, ID: id})
handleError("UpdateGameName", err, "")
err = repo.UpdateSoundtrackName(BackendCtx(), repository.UpdateSoundtrackNameParams{Name: file.Name(), Path: gameDir, ID: id})
handleError("UpdateSoundtrackName", err, "")
newCheckSongs(entries, gameDir, id)
if gamesChangedTitle == nil {
gamesChangedTitle = make(map[string]string)
}
gamesChangedTitle[oldGame.GameName] = file.Name()
gamesChangedTitle[oldGame.SoundtrackName] = file.Name()
case NotChanged:
var found bool = false
for _, beforeGame := range gamesBeforeSync {
@@ -415,8 +415,8 @@ func syncGameNew(file os.DirEntry, foldersToSkip []string, baseDir string, full
zap.String("game", file.Name()),
zap.String("hash", dirHash),
zap.String("status", status.String()))
err = repo.RemoveDeletionDate(BackendCtx(), id)
handleError("RemoveDeletionDate", err, "")
err = repo.RemoveSoundtrackDeletionDate(BackendCtx(), id)
handleError("RemoveSoundtrackDeletionDate", err, "")
}
foldersSynced++
logging.GetLogger().Debug("Sync progress",
@@ -427,14 +427,14 @@ func syncGameNew(file os.DirEntry, foldersToSkip []string, baseDir string, full
func insertGameNew(name string, path string, hash string) int32 {
var duplicateError = errors.New("ERROR: duplicate key value violates unique")
id, err := repo.InsertGame(BackendCtx(), repository.InsertGameParams{GameName: name, Path: path, Hash: hash})
handleError("InsertGame", err, "")
id, err := repo.InsertSoundtrack(BackendCtx(), repository.InsertSoundtrackParams{SoundtrackName: name, Path: path, Hash: hash})
handleError("InsertSoundtrack", err, "")
if err != nil {
logging.GetLogger().Warn("ID collision detected, resetting sequence")
if strings.HasPrefix(err.Error(), duplicateError.Error()) {
logging.GetLogger().Debug("Resetting game ID sequence")
_, err = repo.ResetGameIdSeq(BackendCtx())
handleError("ResetGameIdSeq", err, "")
_, err = repo.ResetSoundtrackIdSeq(BackendCtx())
handleError("ResetSoundtrackIdSeq", err, "")
id = insertGameNew(name, path, hash)
}
}
@@ -478,7 +478,7 @@ func newCheckSong(entry os.DirEntry, gameDir string, id int32) bool {
songName, _ := strings.CutSuffix(fileName, ".mp3")
song, err := repo.GetSongWithHash(BackendCtx(), songHash)
handleError("GetSongWithHash", err, fmt.Sprintf("GameID: %d | Path: %s | SongName: %s | SongHash: %s", id, path, entry.Name(), songHash))
handleError("GetSongWithHash", err, fmt.Sprintf("SoundtrackID: %d | Path: %s | SongName: %s | SongHash: %s", id, path, entry.Name(), songHash))
if err == nil {
if song.SongName == songName && song.Path == path {
return false
@@ -491,31 +491,31 @@ func newCheckSong(entry os.DirEntry, gameDir string, id int32) bool {
zap.String("song_hash", songHash))
count, err := repo.CheckSongWithHash(BackendCtx(), songHash)
handleError("CheckSongWithHash", err, fmt.Sprintf("GameID: %d | Path: %s | SongName: %s | SongHash: %s\n", id, path, entry.Name(), songHash))
handleError("CheckSongWithHash", err, fmt.Sprintf("SoundtrackID: %d | Path: %s | SongName: %s | SongHash: %s\n", id, path, entry.Name(), songHash))
if err != nil {
count2, err := repo.CheckSong(BackendCtx(), path)
handleError("CheckSong", err, fmt.Sprintf("GameID: %d | Path: %s | SongName: %s | SongHash: %s\n", id, path, entry.Name(), songHash))
handleError("CheckSong", err, fmt.Sprintf("SoundtrackID: %d | Path: %s | SongName: %s | SongHash: %s\n", id, path, entry.Name(), songHash))
if count2 > 0 {
err = repo.AddHashToSong(BackendCtx(), repository.AddHashToSongParams{Hash: songHash, Path: path})
handleError("AddHashToSong", err, fmt.Sprintf("GameID: %d | Path: %s | SongName: %s | SongHash: %s", id, path, entry.Name(), songHash))
handleError("AddHashToSong", err, fmt.Sprintf("SoundtrackID: %d | Path: %s | SongName: %s | SongHash: %s", id, path, entry.Name(), songHash))
count, err = repo.CheckSongWithHash(BackendCtx(), songHash)
handleError("CheckSongWithHash 2", err, fmt.Sprintf("GameID: %d | Path: %s | SongName: %s | SongHash: %s", id, path, entry.Name(), songHash))
handleError("CheckSongWithHash 2", err, fmt.Sprintf("SoundtrackID: %d | Path: %s | SongName: %s | SongHash: %s", id, path, entry.Name(), songHash))
}
}
//count, _ := repo.CheckSong(ctx, path)
if count > 0 {
err = repo.UpdateSong(BackendCtx(), repository.UpdateSongParams{SongName: songName, FileName: &fileName, Path: path, Hash: songHash})
handleError("UpdateSong", err, fmt.Sprintf("GameID: %d | Path: %s | SongName: %s | SongHash: %s", id, path, entry.Name(), songHash))
handleError("UpdateSong", err, fmt.Sprintf("SoundtrackID: %d | Path: %s | SongName: %s | SongHash: %s", id, path, entry.Name(), songHash))
} else {
count2, err := repo.CheckSong(BackendCtx(), path)
handleError("CheckSong", err, fmt.Sprintf("GameID: %d | Path: %s | SongName: %s | SongHash: %s", id, path, entry.Name(), songHash))
handleError("CheckSong", err, fmt.Sprintf("SoundtrackID: %d | Path: %s | SongName: %s | SongHash: %s", id, path, entry.Name(), songHash))
if count2 > 0 {
err = repo.AddHashToSong(BackendCtx(), repository.AddHashToSongParams{Hash: songHash, Path: path})
handleError("AddHashToSong", err, fmt.Sprintf("GameID: %d | Path: %s | SongName: %s | SongHash: %s", id, path, entry.Name(), songHash))
handleError("AddHashToSong", err, fmt.Sprintf("SoundtrackID: %d | Path: %s | SongName: %s | SongHash: %s", id, path, entry.Name(), songHash))
} else {
err = repo.AddSong(BackendCtx(), repository.AddSongParams{GameID: id, SongName: songName, Path: path, FileName: &fileName, Hash: songHash})
handleError("AddSong", err, fmt.Sprintf("GameID: %d | Path: %s | SongName: %s | SongHash: %s", id, path, entry.Name(), songHash))
err = repo.AddSong(BackendCtx(), repository.AddSongParams{SoundtrackID: id, SongName: songName, Path: path, FileName: &fileName, Hash: songHash})
handleError("AddSong", err, fmt.Sprintf("SoundtrackID: %d | Path: %s | SongName: %s | SongHash: %s", id, path, entry.Name(), songHash))
}
}
@@ -0,0 +1,33 @@
-- Revert: Rename soundtrack table back to game
ALTER TABLE soundtrack RENAME TO game;
-- Revert primary key sequence
ALTER SEQUENCE soundtrack_id_seq RENAME TO game_id_seq;
-- Revert columns in game table
ALTER TABLE game RENAME COLUMN soundtrack_name TO game_name;
-- Revert song table: rename soundtrack_id back to game_id
ALTER TABLE song RENAME COLUMN soundtrack_id TO game_id;
-- Revert song primary key
ALTER TABLE song DROP CONSTRAINT IF EXISTS song_pkey;
ALTER TABLE song ADD PRIMARY KEY (game_id, path);
ALTER TABLE song RENAME CONSTRAINT song_pkey_soundtrack TO song_pkey;
-- Revert song_list table references
ALTER TABLE song_list RENAME COLUMN soundtrack_name TO game_name;
-- Revert foreign key constraint
ALTER TABLE song DROP CONSTRAINT IF EXISTS song_soundtrack_id_fkey;
ALTER TABLE song ADD CONSTRAINT song_game_id_fkey
FOREIGN KEY (game_id) REFERENCES game(id);
-- Revert indexes
ALTER INDEX IF EXISTS idx_soundtrack_deleted RENAME TO idx_game_deleted;
ALTER INDEX IF EXISTS idx_soundtrack_hash RENAME TO idx_game_hash;
ALTER INDEX IF EXISTS idx_soundtrack_path RENAME TO idx_game_path;
ALTER INDEX IF EXISTS idx_soundtrack_name RENAME TO idx_game_name;
ALTER INDEX IF EXISTS idx_song_soundtrack_id RENAME TO idx_song_game_id;
ALTER INDEX IF EXISTS idx_song_soundtrack_id_song_name RENAME TO idx_song_game_id_song_name;
ALTER INDEX IF EXISTS song_list_soundtrack_name_idx RENAME TO song_list_game_name_idx;
@@ -0,0 +1,33 @@
-- Rename game table to soundtrack
ALTER TABLE game RENAME TO soundtrack;
-- Rename primary key sequence
ALTER SEQUENCE game_id_seq RENAME TO soundtrack_id_seq;
-- Rename columns in soundtrack table
ALTER TABLE soundtrack RENAME COLUMN game_name TO soundtrack_name;
-- Update song table: rename game_id to soundtrack_id
ALTER TABLE song RENAME COLUMN game_id TO soundtrack_id;
-- Update song primary key
ALTER TABLE song DROP CONSTRAINT IF EXISTS song_pkey;
ALTER TABLE song ADD PRIMARY KEY (soundtrack_id, path);
ALTER TABLE song RENAME CONSTRAINT song_pkey TO song_pkey_soundtrack;
-- Update song_list table references
ALTER TABLE song_list RENAME COLUMN game_name TO soundtrack_name;
-- Rename foreign key constraint
ALTER TABLE song DROP CONSTRAINT IF EXISTS song_game_id_fkey;
ALTER TABLE song ADD CONSTRAINT song_soundtrack_id_fkey
FOREIGN KEY (soundtrack_id) REFERENCES soundtrack(id);
-- Rename indexes
ALTER INDEX IF EXISTS idx_game_deleted RENAME TO idx_soundtrack_deleted;
ALTER INDEX IF EXISTS idx_game_hash RENAME TO idx_soundtrack_hash;
ALTER INDEX IF EXISTS idx_game_path RENAME TO idx_soundtrack_path;
ALTER INDEX IF EXISTS idx_game_name RENAME TO idx_soundtrack_name;
ALTER INDEX IF EXISTS idx_song_game_id RENAME TO idx_song_soundtrack_id;
ALTER INDEX IF EXISTS idx_song_game_id_song_name RENAME TO idx_song_soundtrack_id_song_name;
ALTER INDEX IF EXISTS song_list_game_name_idx RENAME TO song_list_soundtrack_name_idx;
-49
View File
@@ -1,49 +0,0 @@
-- name: ResetGameIdSeq :one
SELECT setval('game_id_seq', (SELECT MAX(id) FROM game)+1);
-- name: GetGameNameById :one
SELECT game_name FROM game WHERE id = $1;
-- name: GetGameById :one
SELECT *
FROM game
WHERE id = $1
AND deleted IS NULL;
-- name: SetGameDeletionDate :exec
UPDATE game SET deleted=now() WHERE deleted IS NULL;
-- name: ClearGames :exec
DELETE FROM game;
-- name: UpdateGameName :exec
UPDATE game SET game_name=sqlc.arg(name), path=sqlc.arg(path), last_changed=now() WHERE id=sqlc.arg(id);
-- name: UpdateGameHash :exec
UPDATE game SET hash=sqlc.arg(hash), last_changed=now() WHERE id=sqlc.arg(id);
-- name: RemoveDeletionDate :exec
UPDATE game SET deleted=NULL WHERE id=$1;
-- name: GetIdByGameName :one
SELECT id FROM game WHERE game_name = $1;
-- name: InsertGame :one
INSERT INTO game (game_name, path, hash, added) VALUES ($1, $2, $3, now()) returning id;
-- name: InsertGameWithExistingId :exec
INSERT INTO game (id, game_name, path, hash, added) VALUES ($1, $2, $3, $4, now());
-- name: FindAllGames :many
SELECT *
FROM game
WHERE deleted IS NULL
ORDER BY game_name;
-- name: GetAllGamesIncludingDeleted :many
SELECT *
FROM game
ORDER BY game_name;
-- name: AddGamePlayed :exec
UPDATE game SET times_played = times_played + 1, last_played = now() WHERE id = $1;
+6 -6
View File
@@ -1,11 +1,11 @@
-- name: ClearSongs :exec
DELETE FROM song;
-- name: ClearSongsByGameId :exec
DELETE FROM song WHERE game_id = $1;
-- name: ClearSongsBySoundtrackId :exec
DELETE FROM song WHERE soundtrack_id = $1;
-- name: AddSong :exec
INSERT INTO song(game_id, song_name, path, file_name, hash) VALUES ($1, $2, $3, $4, $5);
INSERT INTO song(soundtrack_id, song_name, path, file_name, hash) VALUES ($1, $2, $3, $4, $5);
-- name: CheckSong :one
SELECT COUNT(*) FROM song WHERE path = $1;
@@ -22,14 +22,14 @@ UPDATE song SET song_name=$1, file_name=$2, path=$3 where hash=$4;
-- name: AddHashToSong :exec
UPDATE song SET hash=$1 where path=$2;
-- name: FindSongsFromGame :many
-- name: FindSongsFromSoundtrack :many
SELECT *
FROM song
WHERE game_id = $1;
WHERE soundtrack_id = $1;
-- name: AddSongPlayed :exec
UPDATE song SET times_played = times_played + 1
WHERE game_id = $1 AND song_name = $2;
WHERE soundtrack_id = $1 AND song_name = $2;
-- name: FetchAllSongs :many
SELECT * FROM song;
+1 -1
View File
@@ -1,5 +1,5 @@
-- name: InsertSongInList :exec
INSERT INTO song_list (match_date, match_id, song_no, game_name, song_name)
INSERT INTO song_list (match_date, match_id, song_no, soundtrack_name, song_name)
VALUES ($1, $2, $3, $4, $5);
-- name: GetSongList :many
+49
View File
@@ -0,0 +1,49 @@
-- name: ResetSoundtrackIdSeq :one
SELECT setval('soundtrack_id_seq', (SELECT MAX(id) FROM soundtrack)+1);
-- name: GetSoundtrackNameById :one
SELECT soundtrack_name FROM soundtrack WHERE id = $1;
-- name: GetSoundtrackById :one
SELECT *
FROM soundtrack
WHERE id = $1
AND deleted IS NULL;
-- name: SetSoundtrackDeletionDate :exec
UPDATE soundtrack SET deleted=now() WHERE deleted IS NULL;
-- name: ClearSoundtracks :exec
DELETE FROM soundtrack;
-- name: UpdateSoundtrackName :exec
UPDATE soundtrack SET soundtrack_name=sqlc.arg(name), path=sqlc.arg(path), last_changed=now() WHERE id=sqlc.arg(id);
-- name: UpdateSoundtrackHash :exec
UPDATE soundtrack SET hash=sqlc.arg(hash), last_changed=now() WHERE id=sqlc.arg(id);
-- name: RemoveSoundtrackDeletionDate :exec
UPDATE soundtrack SET deleted=NULL WHERE id=$1;
-- name: GetIdBySoundtrackName :one
SELECT id FROM soundtrack WHERE soundtrack_name = $1;
-- name: InsertSoundtrack :one
INSERT INTO soundtrack (soundtrack_name, path, hash, added) VALUES ($1, $2, $3, now()) returning id;
-- name: InsertSoundtrackWithExistingId :exec
INSERT INTO soundtrack (id, soundtrack_name, path, hash, added) VALUES ($1, $2, $3, $4, now());
-- name: FindAllSoundtracks :many
SELECT *
FROM soundtrack
WHERE deleted IS NULL
ORDER BY soundtrack_name;
-- name: GetAllSoundtracksIncludingDeleted :many
SELECT *
FROM soundtrack
ORDER BY soundtrack_name;
-- name: AddSoundtrackPlayed :exec
UPDATE soundtrack SET times_played = times_played + 1, last_played = now() WHERE id = $1;
+57 -57
View File
@@ -1,10 +1,10 @@
-- Most played games with their songs
-- Most played soundtracks with their songs
-- name: GetMostPlayedGamesWithSongs :many
SELECT
g.id as game_id,
g.game_name,
g.times_played as game_played,
g.last_played as game_last_played,
g.id as soundtrack_id,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
json_agg(
json_build_object(
'song_name', s.song_name,
@@ -13,20 +13,20 @@ SELECT
'file_name', s.file_name
)
) as songs
FROM game g
LEFT JOIN song s ON g.id = s.game_id
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL
GROUP BY g.id, g.game_name, g.times_played, g.last_played
ORDER BY g.times_played DESC, g.game_name
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.times_played DESC, g.soundtrack_name
LIMIT $1;
-- Least played games with their songs
-- Least played soundtracks with their songs
-- name: GetLeastPlayedGamesWithSongs :many
SELECT
g.id as game_id,
g.game_name,
g.times_played as game_played,
g.last_played as game_last_played,
g.id as soundtrack_id,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
json_agg(
json_build_object(
'song_name', s.song_name,
@@ -35,39 +35,39 @@ SELECT
'file_name', s.file_name
)
) as songs
FROM game g
LEFT JOIN song s ON g.id = s.game_id
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL
GROUP BY g.id, g.game_name, g.times_played, g.last_played
ORDER BY g.times_played ASC, g.game_name
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.times_played ASC, g.soundtrack_name
LIMIT $1;
-- Most played songs with their game info
-- Most played songs with their soundtrack info
-- name: GetMostPlayedSongsWithGame :many
SELECT
s.game_id as game_id,
g.game_name,
s.soundtrack_id as soundtrack_id,
g.soundtrack_name,
s.song_name,
s.path,
s.times_played,
s.file_name
FROM song s
JOIN game g ON s.game_id = g.id
JOIN soundtrack g ON s.soundtrack_id = g.id
WHERE g.deleted IS NULL
ORDER BY s.times_played DESC, s.song_name
LIMIT $1;
-- Least played songs with their game info
-- Least played songs with their soundtrack info
-- name: GetLeastPlayedSongsWithGame :many
SELECT
s.game_id as game_id,
g.game_name,
s.soundtrack_id as soundtrack_id,
g.soundtrack_name,
s.song_name,
s.path,
s.times_played,
s.file_name
FROM song s
JOIN game g ON s.game_id = g.id
JOIN soundtrack g ON s.soundtrack_id = g.id
WHERE g.deleted IS NULL
ORDER BY s.times_played ASC, s.song_name
LIMIT $1;
@@ -75,9 +75,9 @@ LIMIT $1;
-- Games that have never been played (times_played = 0)
-- name: GetNeverPlayedGames :many
SELECT
g.id as game_id,
g.game_name,
g.times_played as game_played,
g.id as soundtrack_id,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.added,
json_agg(
json_build_object(
@@ -86,19 +86,19 @@ SELECT
'times_played', s.times_played
)
) as songs
FROM game g
LEFT JOIN song s ON g.id = s.game_id
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL AND g.times_played = 0
GROUP BY g.id, g.game_name, g.times_played, g.added
ORDER BY g.game_name;
GROUP BY g.id, g.soundtrack_name, g.times_played, g.added
ORDER BY g.soundtrack_name;
-- Last played games (most recently played)
-- Last played soundtracks (most recently played)
-- name: GetLastPlayedGames :many
SELECT
g.id as game_id,
g.game_name,
g.times_played as game_played,
g.last_played as game_last_played,
g.id as soundtrack_id,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
json_agg(
json_build_object(
'song_name', s.song_name,
@@ -106,20 +106,20 @@ SELECT
'times_played', s.times_played
)
) as songs
FROM game g
LEFT JOIN song s ON g.id = s.game_id
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL AND g.last_played IS NOT NULL
GROUP BY g.id, g.game_name, g.times_played, g.last_played
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.last_played DESC
LIMIT $1;
-- Oldest played games (least recently played, but has been played at least once)
-- Oldest played soundtracks (least recently played, but has been played at least once)
-- name: GetOldestPlayedGames :many
SELECT
g.id as game_id,
g.game_name,
g.times_played as game_played,
g.last_played as game_last_played,
g.id as soundtrack_id,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
json_agg(
json_build_object(
'song_name', s.song_name,
@@ -127,22 +127,22 @@ SELECT
'times_played', s.times_played
)
) as songs
FROM game g
LEFT JOIN song s ON g.id = s.game_id
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL AND g.last_played IS NOT NULL
GROUP BY g.id, g.game_name, g.times_played, g.last_played
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.last_played ASC
LIMIT $1;
-- Get statistics summary
-- name: GetStatisticsSummary :one
SELECT
COUNT(*) as total_games,
SUM(CASE WHEN times_played > 0 THEN 1 ELSE 0 END) as played_games,
SUM(CASE WHEN times_played = 0 THEN 1 ELSE 0 END) as never_played_games,
COALESCE(SUM(times_played), 0)::bigint as total_game_plays,
COALESCE(AVG(times_played), 0)::float as avg_game_plays,
COALESCE(MAX(times_played), 0)::bigint as max_game_plays,
COALESCE(MIN(times_played), 0)::bigint as min_game_plays
FROM game
COUNT(*) as total_soundtracks,
SUM(CASE WHEN times_played > 0 THEN 1 ELSE 0 END) as played_soundtracks,
SUM(CASE WHEN times_played = 0 THEN 1 ELSE 0 END) as never_played_soundtracks,
COALESCE(SUM(times_played), 0)::bigint as total_soundtrack_plays,
COALESCE(AVG(times_played), 0)::float as avg_soundtrack_plays,
COALESCE(MAX(times_played), 0)::bigint as max_soundtrack_plays,
COALESCE(MIN(times_played), 0)::bigint as min_soundtrack_plays
FROM soundtrack
WHERE deleted IS NULL;
-246
View File
@@ -1,246 +0,0 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: game.sql
package repository
import (
"context"
)
const addGamePlayed = `-- name: AddGamePlayed :exec
UPDATE game SET times_played = times_played + 1, last_played = now() WHERE id = $1
`
func (q *Queries) AddGamePlayed(ctx context.Context, id int32) error {
_, err := q.db.Exec(ctx, addGamePlayed, id)
return err
}
const clearGames = `-- name: ClearGames :exec
DELETE FROM game
`
func (q *Queries) ClearGames(ctx context.Context) error {
_, err := q.db.Exec(ctx, clearGames)
return err
}
const findAllGames = `-- name: FindAllGames :many
SELECT id, game_name, added, deleted, last_changed, path, times_played, last_played, number_of_songs, hash
FROM game
WHERE deleted IS NULL
ORDER BY game_name
`
func (q *Queries) FindAllGames(ctx context.Context) ([]Game, error) {
rows, err := q.db.Query(ctx, findAllGames)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Game
for rows.Next() {
var i Game
if err := rows.Scan(
&i.ID,
&i.GameName,
&i.Added,
&i.Deleted,
&i.LastChanged,
&i.Path,
&i.TimesPlayed,
&i.LastPlayed,
&i.NumberOfSongs,
&i.Hash,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getAllGamesIncludingDeleted = `-- name: GetAllGamesIncludingDeleted :many
SELECT id, game_name, added, deleted, last_changed, path, times_played, last_played, number_of_songs, hash
FROM game
ORDER BY game_name
`
func (q *Queries) GetAllGamesIncludingDeleted(ctx context.Context) ([]Game, error) {
rows, err := q.db.Query(ctx, getAllGamesIncludingDeleted)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Game
for rows.Next() {
var i Game
if err := rows.Scan(
&i.ID,
&i.GameName,
&i.Added,
&i.Deleted,
&i.LastChanged,
&i.Path,
&i.TimesPlayed,
&i.LastPlayed,
&i.NumberOfSongs,
&i.Hash,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getGameById = `-- name: GetGameById :one
SELECT id, game_name, added, deleted, last_changed, path, times_played, last_played, number_of_songs, hash
FROM game
WHERE id = $1
AND deleted IS NULL
`
func (q *Queries) GetGameById(ctx context.Context, id int32) (Game, error) {
row := q.db.QueryRow(ctx, getGameById, id)
var i Game
err := row.Scan(
&i.ID,
&i.GameName,
&i.Added,
&i.Deleted,
&i.LastChanged,
&i.Path,
&i.TimesPlayed,
&i.LastPlayed,
&i.NumberOfSongs,
&i.Hash,
)
return i, err
}
const getGameNameById = `-- name: GetGameNameById :one
SELECT game_name FROM game WHERE id = $1
`
func (q *Queries) GetGameNameById(ctx context.Context, id int32) (string, error) {
row := q.db.QueryRow(ctx, getGameNameById, id)
var game_name string
err := row.Scan(&game_name)
return game_name, err
}
const getIdByGameName = `-- name: GetIdByGameName :one
SELECT id FROM game WHERE game_name = $1
`
func (q *Queries) GetIdByGameName(ctx context.Context, gameName string) (int32, error) {
row := q.db.QueryRow(ctx, getIdByGameName, gameName)
var id int32
err := row.Scan(&id)
return id, err
}
const insertGame = `-- name: InsertGame :one
INSERT INTO game (game_name, path, hash, added) VALUES ($1, $2, $3, now()) returning id
`
type InsertGameParams struct {
GameName string `json:"game_name"`
Path string `json:"path"`
Hash string `json:"hash"`
}
func (q *Queries) InsertGame(ctx context.Context, arg InsertGameParams) (int32, error) {
row := q.db.QueryRow(ctx, insertGame, arg.GameName, arg.Path, arg.Hash)
var id int32
err := row.Scan(&id)
return id, err
}
const insertGameWithExistingId = `-- name: InsertGameWithExistingId :exec
INSERT INTO game (id, game_name, path, hash, added) VALUES ($1, $2, $3, $4, now())
`
type InsertGameWithExistingIdParams struct {
ID int32 `json:"id"`
GameName string `json:"game_name"`
Path string `json:"path"`
Hash string `json:"hash"`
}
func (q *Queries) InsertGameWithExistingId(ctx context.Context, arg InsertGameWithExistingIdParams) error {
_, err := q.db.Exec(ctx, insertGameWithExistingId,
arg.ID,
arg.GameName,
arg.Path,
arg.Hash,
)
return err
}
const removeDeletionDate = `-- name: RemoveDeletionDate :exec
UPDATE game SET deleted=NULL WHERE id=$1
`
func (q *Queries) RemoveDeletionDate(ctx context.Context, id int32) error {
_, err := q.db.Exec(ctx, removeDeletionDate, id)
return err
}
const resetGameIdSeq = `-- name: ResetGameIdSeq :one
SELECT setval('game_id_seq', (SELECT MAX(id) FROM game)+1)
`
func (q *Queries) ResetGameIdSeq(ctx context.Context) (int64, error) {
row := q.db.QueryRow(ctx, resetGameIdSeq)
var setval int64
err := row.Scan(&setval)
return setval, err
}
const setGameDeletionDate = `-- name: SetGameDeletionDate :exec
UPDATE game SET deleted=now() WHERE deleted IS NULL
`
func (q *Queries) SetGameDeletionDate(ctx context.Context) error {
_, err := q.db.Exec(ctx, setGameDeletionDate)
return err
}
const updateGameHash = `-- name: UpdateGameHash :exec
UPDATE game SET hash=$1, last_changed=now() WHERE id=$2
`
type UpdateGameHashParams struct {
Hash string `json:"hash"`
ID int32 `json:"id"`
}
func (q *Queries) UpdateGameHash(ctx context.Context, arg UpdateGameHashParams) error {
_, err := q.db.Exec(ctx, updateGameHash, arg.Hash, arg.ID)
return err
}
const updateGameName = `-- name: UpdateGameName :exec
UPDATE game SET game_name=$1, path=$2, last_changed=now() WHERE id=$3
`
type UpdateGameNameParams struct {
Name string `json:"name"`
Path string `json:"path"`
ID int32 `json:"id"`
}
func (q *Queries) UpdateGameName(ctx context.Context, arg UpdateGameNameParams) error {
_, err := q.db.Exec(ctx, updateGameName, arg.Name, arg.Path, arg.ID)
return err
}
+24 -24
View File
@@ -10,19 +10,6 @@ import (
"github.com/jackc/pgx/v5/pgtype"
)
type Game struct {
ID int32 `json:"id"`
GameName string `json:"game_name"`
Added time.Time `json:"added"`
Deleted *time.Time `json:"deleted"`
LastChanged *time.Time `json:"last_changed"`
Path string `json:"path"`
TimesPlayed int32 `json:"times_played"`
LastPlayed *time.Time `json:"last_played"`
NumberOfSongs int32 `json:"number_of_songs"`
Hash string `json:"hash"`
}
type Session struct {
Token string `json:"token"`
IpAddress string `json:"ip_address"`
@@ -33,20 +20,33 @@ type Session struct {
}
type Song struct {
GameID int32 `json:"game_id"`
SongName string `json:"song_name"`
Path string `json:"path"`
TimesPlayed int32 `json:"times_played"`
Hash string `json:"hash"`
FileName *string `json:"file_name"`
SoundtrackID int32 `json:"soundtrack_id"`
SongName string `json:"song_name"`
Path string `json:"path"`
TimesPlayed int32 `json:"times_played"`
Hash string `json:"hash"`
FileName *string `json:"file_name"`
}
type SongList struct {
MatchDate time.Time `json:"match_date"`
MatchID int32 `json:"match_id"`
SongNo int32 `json:"song_no"`
GameName *string `json:"game_name"`
SongName *string `json:"song_name"`
MatchDate time.Time `json:"match_date"`
MatchID int32 `json:"match_id"`
SongNo int32 `json:"song_no"`
SoundtrackName *string `json:"soundtrack_name"`
SongName *string `json:"song_name"`
}
type Soundtrack struct {
ID int32 `json:"id"`
SoundtrackName string `json:"soundtrack_name"`
Added time.Time `json:"added"`
Deleted *time.Time `json:"deleted"`
LastChanged *time.Time `json:"last_changed"`
Path string `json:"path"`
TimesPlayed int32 `json:"times_played"`
LastPlayed *time.Time `json:"last_played"`
NumberOfSongs int32 `json:"number_of_songs"`
Hash string `json:"hash"`
}
type Vgmq struct {
+25 -25
View File
@@ -24,20 +24,20 @@ func (q *Queries) AddHashToSong(ctx context.Context, arg AddHashToSongParams) er
}
const addSong = `-- name: AddSong :exec
INSERT INTO song(game_id, song_name, path, file_name, hash) VALUES ($1, $2, $3, $4, $5)
INSERT INTO song(soundtrack_id, song_name, path, file_name, hash) VALUES ($1, $2, $3, $4, $5)
`
type AddSongParams struct {
GameID int32 `json:"game_id"`
SongName string `json:"song_name"`
Path string `json:"path"`
FileName *string `json:"file_name"`
Hash string `json:"hash"`
SoundtrackID int32 `json:"soundtrack_id"`
SongName string `json:"song_name"`
Path string `json:"path"`
FileName *string `json:"file_name"`
Hash string `json:"hash"`
}
func (q *Queries) AddSong(ctx context.Context, arg AddSongParams) error {
_, err := q.db.Exec(ctx, addSong,
arg.GameID,
arg.SoundtrackID,
arg.SongName,
arg.Path,
arg.FileName,
@@ -48,16 +48,16 @@ func (q *Queries) AddSong(ctx context.Context, arg AddSongParams) error {
const addSongPlayed = `-- name: AddSongPlayed :exec
UPDATE song SET times_played = times_played + 1
WHERE game_id = $1 AND song_name = $2
WHERE soundtrack_id = $1 AND song_name = $2
`
type AddSongPlayedParams struct {
GameID int32 `json:"game_id"`
SongName string `json:"song_name"`
SoundtrackID int32 `json:"soundtrack_id"`
SongName string `json:"song_name"`
}
func (q *Queries) AddSongPlayed(ctx context.Context, arg AddSongPlayedParams) error {
_, err := q.db.Exec(ctx, addSongPlayed, arg.GameID, arg.SongName)
_, err := q.db.Exec(ctx, addSongPlayed, arg.SoundtrackID, arg.SongName)
return err
}
@@ -92,17 +92,17 @@ func (q *Queries) ClearSongs(ctx context.Context) error {
return err
}
const clearSongsByGameId = `-- name: ClearSongsByGameId :exec
DELETE FROM song WHERE game_id = $1
const clearSongsBySoundtrackId = `-- name: ClearSongsBySoundtrackId :exec
DELETE FROM song WHERE soundtrack_id = $1
`
func (q *Queries) ClearSongsByGameId(ctx context.Context, gameID int32) error {
_, err := q.db.Exec(ctx, clearSongsByGameId, gameID)
func (q *Queries) ClearSongsBySoundtrackId(ctx context.Context, soundtrackID int32) error {
_, err := q.db.Exec(ctx, clearSongsBySoundtrackId, soundtrackID)
return err
}
const fetchAllSongs = `-- name: FetchAllSongs :many
SELECT game_id, song_name, path, times_played, hash, file_name FROM song
SELECT soundtrack_id, song_name, path, times_played, hash, file_name FROM song
`
func (q *Queries) FetchAllSongs(ctx context.Context) ([]Song, error) {
@@ -115,7 +115,7 @@ func (q *Queries) FetchAllSongs(ctx context.Context) ([]Song, error) {
for rows.Next() {
var i Song
if err := rows.Scan(
&i.GameID,
&i.SoundtrackID,
&i.SongName,
&i.Path,
&i.TimesPlayed,
@@ -132,14 +132,14 @@ func (q *Queries) FetchAllSongs(ctx context.Context) ([]Song, error) {
return items, nil
}
const findSongsFromGame = `-- name: FindSongsFromGame :many
SELECT game_id, song_name, path, times_played, hash, file_name
const findSongsFromSoundtrack = `-- name: FindSongsFromSoundtrack :many
SELECT soundtrack_id, song_name, path, times_played, hash, file_name
FROM song
WHERE game_id = $1
WHERE soundtrack_id = $1
`
func (q *Queries) FindSongsFromGame(ctx context.Context, gameID int32) ([]Song, error) {
rows, err := q.db.Query(ctx, findSongsFromGame, gameID)
func (q *Queries) FindSongsFromSoundtrack(ctx context.Context, soundtrackID int32) ([]Song, error) {
rows, err := q.db.Query(ctx, findSongsFromSoundtrack, soundtrackID)
if err != nil {
return nil, err
}
@@ -148,7 +148,7 @@ func (q *Queries) FindSongsFromGame(ctx context.Context, gameID int32) ([]Song,
for rows.Next() {
var i Song
if err := rows.Scan(
&i.GameID,
&i.SoundtrackID,
&i.SongName,
&i.Path,
&i.TimesPlayed,
@@ -166,14 +166,14 @@ func (q *Queries) FindSongsFromGame(ctx context.Context, gameID int32) ([]Song,
}
const getSongWithHash = `-- name: GetSongWithHash :one
SELECT game_id, song_name, path, times_played, hash, file_name FROM song WHERE hash = $1
SELECT soundtrack_id, song_name, path, times_played, hash, file_name FROM song WHERE hash = $1
`
func (q *Queries) GetSongWithHash(ctx context.Context, hash string) (Song, error) {
row := q.db.QueryRow(ctx, getSongWithHash, hash)
var i Song
err := row.Scan(
&i.GameID,
&i.SoundtrackID,
&i.SongName,
&i.Path,
&i.TimesPlayed,
+9 -9
View File
@@ -11,7 +11,7 @@ import (
)
const getSongList = `-- name: GetSongList :many
SELECT match_date, match_id, song_no, game_name, song_name
SELECT match_date, match_id, song_no, soundtrack_name, song_name
FROM song_list
WHERE match_date = $1
ORDER BY song_no DESC
@@ -30,7 +30,7 @@ func (q *Queries) GetSongList(ctx context.Context, matchDate time.Time) ([]SongL
&i.MatchDate,
&i.MatchID,
&i.SongNo,
&i.GameName,
&i.SoundtrackName,
&i.SongName,
); err != nil {
return nil, err
@@ -44,16 +44,16 @@ func (q *Queries) GetSongList(ctx context.Context, matchDate time.Time) ([]SongL
}
const insertSongInList = `-- name: InsertSongInList :exec
INSERT INTO song_list (match_date, match_id, song_no, game_name, song_name)
INSERT INTO song_list (match_date, match_id, song_no, soundtrack_name, song_name)
VALUES ($1, $2, $3, $4, $5)
`
type InsertSongInListParams struct {
MatchDate time.Time `json:"match_date"`
MatchID int32 `json:"match_id"`
SongNo int32 `json:"song_no"`
GameName *string `json:"game_name"`
SongName *string `json:"song_name"`
MatchDate time.Time `json:"match_date"`
MatchID int32 `json:"match_id"`
SongNo int32 `json:"song_no"`
SoundtrackName *string `json:"soundtrack_name"`
SongName *string `json:"song_name"`
}
func (q *Queries) InsertSongInList(ctx context.Context, arg InsertSongInListParams) error {
@@ -61,7 +61,7 @@ func (q *Queries) InsertSongInList(ctx context.Context, arg InsertSongInListPara
arg.MatchDate,
arg.MatchID,
arg.SongNo,
arg.GameName,
arg.SoundtrackName,
arg.SongName,
)
return err
+246
View File
@@ -0,0 +1,246 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: soundtrack.sql
package repository
import (
"context"
)
const addSoundtrackPlayed = `-- name: AddSoundtrackPlayed :exec
UPDATE soundtrack SET times_played = times_played + 1, last_played = now() WHERE id = $1
`
func (q *Queries) AddSoundtrackPlayed(ctx context.Context, id int32) error {
_, err := q.db.Exec(ctx, addSoundtrackPlayed, id)
return err
}
const clearSoundtracks = `-- name: ClearSoundtracks :exec
DELETE FROM soundtrack
`
func (q *Queries) ClearSoundtracks(ctx context.Context) error {
_, err := q.db.Exec(ctx, clearSoundtracks)
return err
}
const findAllSoundtracks = `-- name: FindAllSoundtracks :many
SELECT id, soundtrack_name, added, deleted, last_changed, path, times_played, last_played, number_of_songs, hash
FROM soundtrack
WHERE deleted IS NULL
ORDER BY soundtrack_name
`
func (q *Queries) FindAllSoundtracks(ctx context.Context) ([]Soundtrack, error) {
rows, err := q.db.Query(ctx, findAllSoundtracks)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Soundtrack
for rows.Next() {
var i Soundtrack
if err := rows.Scan(
&i.ID,
&i.SoundtrackName,
&i.Added,
&i.Deleted,
&i.LastChanged,
&i.Path,
&i.TimesPlayed,
&i.LastPlayed,
&i.NumberOfSongs,
&i.Hash,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getAllSoundtracksIncludingDeleted = `-- name: GetAllSoundtracksIncludingDeleted :many
SELECT id, soundtrack_name, added, deleted, last_changed, path, times_played, last_played, number_of_songs, hash
FROM soundtrack
ORDER BY soundtrack_name
`
func (q *Queries) GetAllSoundtracksIncludingDeleted(ctx context.Context) ([]Soundtrack, error) {
rows, err := q.db.Query(ctx, getAllSoundtracksIncludingDeleted)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Soundtrack
for rows.Next() {
var i Soundtrack
if err := rows.Scan(
&i.ID,
&i.SoundtrackName,
&i.Added,
&i.Deleted,
&i.LastChanged,
&i.Path,
&i.TimesPlayed,
&i.LastPlayed,
&i.NumberOfSongs,
&i.Hash,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getIdBySoundtrackName = `-- name: GetIdBySoundtrackName :one
SELECT id FROM soundtrack WHERE soundtrack_name = $1
`
func (q *Queries) GetIdBySoundtrackName(ctx context.Context, soundtrackName string) (int32, error) {
row := q.db.QueryRow(ctx, getIdBySoundtrackName, soundtrackName)
var id int32
err := row.Scan(&id)
return id, err
}
const getSoundtrackById = `-- name: GetSoundtrackById :one
SELECT id, soundtrack_name, added, deleted, last_changed, path, times_played, last_played, number_of_songs, hash
FROM soundtrack
WHERE id = $1
AND deleted IS NULL
`
func (q *Queries) GetSoundtrackById(ctx context.Context, id int32) (Soundtrack, error) {
row := q.db.QueryRow(ctx, getSoundtrackById, id)
var i Soundtrack
err := row.Scan(
&i.ID,
&i.SoundtrackName,
&i.Added,
&i.Deleted,
&i.LastChanged,
&i.Path,
&i.TimesPlayed,
&i.LastPlayed,
&i.NumberOfSongs,
&i.Hash,
)
return i, err
}
const getSoundtrackNameById = `-- name: GetSoundtrackNameById :one
SELECT soundtrack_name FROM soundtrack WHERE id = $1
`
func (q *Queries) GetSoundtrackNameById(ctx context.Context, id int32) (string, error) {
row := q.db.QueryRow(ctx, getSoundtrackNameById, id)
var soundtrack_name string
err := row.Scan(&soundtrack_name)
return soundtrack_name, err
}
const insertSoundtrack = `-- name: InsertSoundtrack :one
INSERT INTO soundtrack (soundtrack_name, path, hash, added) VALUES ($1, $2, $3, now()) returning id
`
type InsertSoundtrackParams struct {
SoundtrackName string `json:"soundtrack_name"`
Path string `json:"path"`
Hash string `json:"hash"`
}
func (q *Queries) InsertSoundtrack(ctx context.Context, arg InsertSoundtrackParams) (int32, error) {
row := q.db.QueryRow(ctx, insertSoundtrack, arg.SoundtrackName, arg.Path, arg.Hash)
var id int32
err := row.Scan(&id)
return id, err
}
const insertSoundtrackWithExistingId = `-- name: InsertSoundtrackWithExistingId :exec
INSERT INTO soundtrack (id, soundtrack_name, path, hash, added) VALUES ($1, $2, $3, $4, now())
`
type InsertSoundtrackWithExistingIdParams struct {
ID int32 `json:"id"`
SoundtrackName string `json:"soundtrack_name"`
Path string `json:"path"`
Hash string `json:"hash"`
}
func (q *Queries) InsertSoundtrackWithExistingId(ctx context.Context, arg InsertSoundtrackWithExistingIdParams) error {
_, err := q.db.Exec(ctx, insertSoundtrackWithExistingId,
arg.ID,
arg.SoundtrackName,
arg.Path,
arg.Hash,
)
return err
}
const removeSoundtrackDeletionDate = `-- name: RemoveSoundtrackDeletionDate :exec
UPDATE soundtrack SET deleted=NULL WHERE id=$1
`
func (q *Queries) RemoveSoundtrackDeletionDate(ctx context.Context, id int32) error {
_, err := q.db.Exec(ctx, removeSoundtrackDeletionDate, id)
return err
}
const resetSoundtrackIdSeq = `-- name: ResetSoundtrackIdSeq :one
SELECT setval('soundtrack_id_seq', (SELECT MAX(id) FROM soundtrack)+1)
`
func (q *Queries) ResetSoundtrackIdSeq(ctx context.Context) (int64, error) {
row := q.db.QueryRow(ctx, resetSoundtrackIdSeq)
var setval int64
err := row.Scan(&setval)
return setval, err
}
const setSoundtrackDeletionDate = `-- name: SetSoundtrackDeletionDate :exec
UPDATE soundtrack SET deleted=now() WHERE deleted IS NULL
`
func (q *Queries) SetSoundtrackDeletionDate(ctx context.Context) error {
_, err := q.db.Exec(ctx, setSoundtrackDeletionDate)
return err
}
const updateSoundtrackHash = `-- name: UpdateSoundtrackHash :exec
UPDATE soundtrack SET hash=$1, last_changed=now() WHERE id=$2
`
type UpdateSoundtrackHashParams struct {
Hash string `json:"hash"`
ID int32 `json:"id"`
}
func (q *Queries) UpdateSoundtrackHash(ctx context.Context, arg UpdateSoundtrackHashParams) error {
_, err := q.db.Exec(ctx, updateSoundtrackHash, arg.Hash, arg.ID)
return err
}
const updateSoundtrackName = `-- name: UpdateSoundtrackName :exec
UPDATE soundtrack SET soundtrack_name=$1, path=$2, last_changed=now() WHERE id=$3
`
type UpdateSoundtrackNameParams struct {
Name string `json:"name"`
Path string `json:"path"`
ID int32 `json:"id"`
}
func (q *Queries) UpdateSoundtrackName(ctx context.Context, arg UpdateSoundtrackNameParams) error {
_, err := q.db.Exec(ctx, updateSoundtrackName, arg.Name, arg.Path, arg.ID)
return err
}
+131 -131
View File
@@ -12,10 +12,10 @@ import (
const getLastPlayedGames = `-- name: GetLastPlayedGames :many
SELECT
g.id as game_id,
g.game_name,
g.times_played as game_played,
g.last_played as game_last_played,
g.id as soundtrack_id,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
json_agg(
json_build_object(
'song_name', s.song_name,
@@ -23,23 +23,23 @@ SELECT
'times_played', s.times_played
)
) as songs
FROM game g
LEFT JOIN song s ON g.id = s.game_id
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL AND g.last_played IS NOT NULL
GROUP BY g.id, g.game_name, g.times_played, g.last_played
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.last_played DESC
LIMIT $1
`
type GetLastPlayedGamesRow struct {
GameID int32 `json:"game_id"`
GameName string `json:"game_name"`
GamePlayed int32 `json:"game_played"`
GameLastPlayed *time.Time `json:"game_last_played"`
Songs []byte `json:"songs"`
SoundtrackID int32 `json:"soundtrack_id"`
SoundtrackName string `json:"soundtrack_name"`
SoundtrackPlayed int32 `json:"soundtrack_played"`
SoundtrackLastPlayed *time.Time `json:"soundtrack_last_played"`
Songs []byte `json:"songs"`
}
// Last played games (most recently played)
// Last played soundtracks (most recently played)
func (q *Queries) GetLastPlayedGames(ctx context.Context, limit int32) ([]GetLastPlayedGamesRow, error) {
rows, err := q.db.Query(ctx, getLastPlayedGames, limit)
if err != nil {
@@ -50,10 +50,10 @@ func (q *Queries) GetLastPlayedGames(ctx context.Context, limit int32) ([]GetLas
for rows.Next() {
var i GetLastPlayedGamesRow
if err := rows.Scan(
&i.GameID,
&i.GameName,
&i.GamePlayed,
&i.GameLastPlayed,
&i.SoundtrackID,
&i.SoundtrackName,
&i.SoundtrackPlayed,
&i.SoundtrackLastPlayed,
&i.Songs,
); err != nil {
return nil, err
@@ -68,10 +68,10 @@ func (q *Queries) GetLastPlayedGames(ctx context.Context, limit int32) ([]GetLas
const getLeastPlayedGamesWithSongs = `-- name: GetLeastPlayedGamesWithSongs :many
SELECT
g.id as game_id,
g.game_name,
g.times_played as game_played,
g.last_played as game_last_played,
g.id as soundtrack_id,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
json_agg(
json_build_object(
'song_name', s.song_name,
@@ -80,23 +80,23 @@ SELECT
'file_name', s.file_name
)
) as songs
FROM game g
LEFT JOIN song s ON g.id = s.game_id
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL
GROUP BY g.id, g.game_name, g.times_played, g.last_played
ORDER BY g.times_played ASC, g.game_name
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.times_played ASC, g.soundtrack_name
LIMIT $1
`
type GetLeastPlayedGamesWithSongsRow struct {
GameID int32 `json:"game_id"`
GameName string `json:"game_name"`
GamePlayed int32 `json:"game_played"`
GameLastPlayed *time.Time `json:"game_last_played"`
Songs []byte `json:"songs"`
SoundtrackID int32 `json:"soundtrack_id"`
SoundtrackName string `json:"soundtrack_name"`
SoundtrackPlayed int32 `json:"soundtrack_played"`
SoundtrackLastPlayed *time.Time `json:"soundtrack_last_played"`
Songs []byte `json:"songs"`
}
// Least played games with their songs
// Least played soundtracks with their songs
func (q *Queries) GetLeastPlayedGamesWithSongs(ctx context.Context, limit int32) ([]GetLeastPlayedGamesWithSongsRow, error) {
rows, err := q.db.Query(ctx, getLeastPlayedGamesWithSongs, limit)
if err != nil {
@@ -107,10 +107,10 @@ func (q *Queries) GetLeastPlayedGamesWithSongs(ctx context.Context, limit int32)
for rows.Next() {
var i GetLeastPlayedGamesWithSongsRow
if err := rows.Scan(
&i.GameID,
&i.GameName,
&i.GamePlayed,
&i.GameLastPlayed,
&i.SoundtrackID,
&i.SoundtrackName,
&i.SoundtrackPlayed,
&i.SoundtrackLastPlayed,
&i.Songs,
); err != nil {
return nil, err
@@ -125,29 +125,29 @@ func (q *Queries) GetLeastPlayedGamesWithSongs(ctx context.Context, limit int32)
const getLeastPlayedSongsWithGame = `-- name: GetLeastPlayedSongsWithGame :many
SELECT
s.game_id as game_id,
g.game_name,
s.soundtrack_id as soundtrack_id,
g.soundtrack_name,
s.song_name,
s.path,
s.times_played,
s.file_name
FROM song s
JOIN game g ON s.game_id = g.id
JOIN soundtrack g ON s.soundtrack_id = g.id
WHERE g.deleted IS NULL
ORDER BY s.times_played ASC, s.song_name
LIMIT $1
`
type GetLeastPlayedSongsWithGameRow struct {
GameID int32 `json:"game_id"`
GameName string `json:"game_name"`
SongName string `json:"song_name"`
Path string `json:"path"`
TimesPlayed int32 `json:"times_played"`
FileName *string `json:"file_name"`
SoundtrackID int32 `json:"soundtrack_id"`
SoundtrackName string `json:"soundtrack_name"`
SongName string `json:"song_name"`
Path string `json:"path"`
TimesPlayed int32 `json:"times_played"`
FileName *string `json:"file_name"`
}
// Least played songs with their game info
// Least played songs with their soundtrack info
func (q *Queries) GetLeastPlayedSongsWithGame(ctx context.Context, limit int32) ([]GetLeastPlayedSongsWithGameRow, error) {
rows, err := q.db.Query(ctx, getLeastPlayedSongsWithGame, limit)
if err != nil {
@@ -158,8 +158,8 @@ func (q *Queries) GetLeastPlayedSongsWithGame(ctx context.Context, limit int32)
for rows.Next() {
var i GetLeastPlayedSongsWithGameRow
if err := rows.Scan(
&i.GameID,
&i.GameName,
&i.SoundtrackID,
&i.SoundtrackName,
&i.SongName,
&i.Path,
&i.TimesPlayed,
@@ -177,10 +177,10 @@ func (q *Queries) GetLeastPlayedSongsWithGame(ctx context.Context, limit int32)
const getMostPlayedGamesWithSongs = `-- name: GetMostPlayedGamesWithSongs :many
SELECT
g.id as game_id,
g.game_name,
g.times_played as game_played,
g.last_played as game_last_played,
g.id as soundtrack_id,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
json_agg(
json_build_object(
'song_name', s.song_name,
@@ -189,23 +189,23 @@ SELECT
'file_name', s.file_name
)
) as songs
FROM game g
LEFT JOIN song s ON g.id = s.game_id
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL
GROUP BY g.id, g.game_name, g.times_played, g.last_played
ORDER BY g.times_played DESC, g.game_name
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.times_played DESC, g.soundtrack_name
LIMIT $1
`
type GetMostPlayedGamesWithSongsRow struct {
GameID int32 `json:"game_id"`
GameName string `json:"game_name"`
GamePlayed int32 `json:"game_played"`
GameLastPlayed *time.Time `json:"game_last_played"`
Songs []byte `json:"songs"`
SoundtrackID int32 `json:"soundtrack_id"`
SoundtrackName string `json:"soundtrack_name"`
SoundtrackPlayed int32 `json:"soundtrack_played"`
SoundtrackLastPlayed *time.Time `json:"soundtrack_last_played"`
Songs []byte `json:"songs"`
}
// Most played games with their songs
// Most played soundtracks with their songs
func (q *Queries) GetMostPlayedGamesWithSongs(ctx context.Context, limit int32) ([]GetMostPlayedGamesWithSongsRow, error) {
rows, err := q.db.Query(ctx, getMostPlayedGamesWithSongs, limit)
if err != nil {
@@ -216,10 +216,10 @@ func (q *Queries) GetMostPlayedGamesWithSongs(ctx context.Context, limit int32)
for rows.Next() {
var i GetMostPlayedGamesWithSongsRow
if err := rows.Scan(
&i.GameID,
&i.GameName,
&i.GamePlayed,
&i.GameLastPlayed,
&i.SoundtrackID,
&i.SoundtrackName,
&i.SoundtrackPlayed,
&i.SoundtrackLastPlayed,
&i.Songs,
); err != nil {
return nil, err
@@ -234,29 +234,29 @@ func (q *Queries) GetMostPlayedGamesWithSongs(ctx context.Context, limit int32)
const getMostPlayedSongsWithGame = `-- name: GetMostPlayedSongsWithGame :many
SELECT
s.game_id as game_id,
g.game_name,
s.soundtrack_id as soundtrack_id,
g.soundtrack_name,
s.song_name,
s.path,
s.times_played,
s.file_name
FROM song s
JOIN game g ON s.game_id = g.id
JOIN soundtrack g ON s.soundtrack_id = g.id
WHERE g.deleted IS NULL
ORDER BY s.times_played DESC, s.song_name
LIMIT $1
`
type GetMostPlayedSongsWithGameRow struct {
GameID int32 `json:"game_id"`
GameName string `json:"game_name"`
SongName string `json:"song_name"`
Path string `json:"path"`
TimesPlayed int32 `json:"times_played"`
FileName *string `json:"file_name"`
SoundtrackID int32 `json:"soundtrack_id"`
SoundtrackName string `json:"soundtrack_name"`
SongName string `json:"song_name"`
Path string `json:"path"`
TimesPlayed int32 `json:"times_played"`
FileName *string `json:"file_name"`
}
// Most played songs with their game info
// Most played songs with their soundtrack info
func (q *Queries) GetMostPlayedSongsWithGame(ctx context.Context, limit int32) ([]GetMostPlayedSongsWithGameRow, error) {
rows, err := q.db.Query(ctx, getMostPlayedSongsWithGame, limit)
if err != nil {
@@ -267,8 +267,8 @@ func (q *Queries) GetMostPlayedSongsWithGame(ctx context.Context, limit int32) (
for rows.Next() {
var i GetMostPlayedSongsWithGameRow
if err := rows.Scan(
&i.GameID,
&i.GameName,
&i.SoundtrackID,
&i.SoundtrackName,
&i.SongName,
&i.Path,
&i.TimesPlayed,
@@ -286,9 +286,9 @@ func (q *Queries) GetMostPlayedSongsWithGame(ctx context.Context, limit int32) (
const getNeverPlayedGames = `-- name: GetNeverPlayedGames :many
SELECT
g.id as game_id,
g.game_name,
g.times_played as game_played,
g.id as soundtrack_id,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.added,
json_agg(
json_build_object(
@@ -297,19 +297,19 @@ SELECT
'times_played', s.times_played
)
) as songs
FROM game g
LEFT JOIN song s ON g.id = s.game_id
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL AND g.times_played = 0
GROUP BY g.id, g.game_name, g.times_played, g.added
ORDER BY g.game_name
GROUP BY g.id, g.soundtrack_name, g.times_played, g.added
ORDER BY g.soundtrack_name
`
type GetNeverPlayedGamesRow struct {
GameID int32 `json:"game_id"`
GameName string `json:"game_name"`
GamePlayed int32 `json:"game_played"`
Added time.Time `json:"added"`
Songs []byte `json:"songs"`
SoundtrackID int32 `json:"soundtrack_id"`
SoundtrackName string `json:"soundtrack_name"`
SoundtrackPlayed int32 `json:"soundtrack_played"`
Added time.Time `json:"added"`
Songs []byte `json:"songs"`
}
// Games that have never been played (times_played = 0)
@@ -323,9 +323,9 @@ func (q *Queries) GetNeverPlayedGames(ctx context.Context) ([]GetNeverPlayedGame
for rows.Next() {
var i GetNeverPlayedGamesRow
if err := rows.Scan(
&i.GameID,
&i.GameName,
&i.GamePlayed,
&i.SoundtrackID,
&i.SoundtrackName,
&i.SoundtrackPlayed,
&i.Added,
&i.Songs,
); err != nil {
@@ -341,10 +341,10 @@ func (q *Queries) GetNeverPlayedGames(ctx context.Context) ([]GetNeverPlayedGame
const getOldestPlayedGames = `-- name: GetOldestPlayedGames :many
SELECT
g.id as game_id,
g.game_name,
g.times_played as game_played,
g.last_played as game_last_played,
g.id as soundtrack_id,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
json_agg(
json_build_object(
'song_name', s.song_name,
@@ -352,23 +352,23 @@ SELECT
'times_played', s.times_played
)
) as songs
FROM game g
LEFT JOIN song s ON g.id = s.game_id
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL AND g.last_played IS NOT NULL
GROUP BY g.id, g.game_name, g.times_played, g.last_played
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.last_played ASC
LIMIT $1
`
type GetOldestPlayedGamesRow struct {
GameID int32 `json:"game_id"`
GameName string `json:"game_name"`
GamePlayed int32 `json:"game_played"`
GameLastPlayed *time.Time `json:"game_last_played"`
Songs []byte `json:"songs"`
SoundtrackID int32 `json:"soundtrack_id"`
SoundtrackName string `json:"soundtrack_name"`
SoundtrackPlayed int32 `json:"soundtrack_played"`
SoundtrackLastPlayed *time.Time `json:"soundtrack_last_played"`
Songs []byte `json:"songs"`
}
// Oldest played games (least recently played, but has been played at least once)
// Oldest played soundtracks (least recently played, but has been played at least once)
func (q *Queries) GetOldestPlayedGames(ctx context.Context, limit int32) ([]GetOldestPlayedGamesRow, error) {
rows, err := q.db.Query(ctx, getOldestPlayedGames, limit)
if err != nil {
@@ -379,10 +379,10 @@ func (q *Queries) GetOldestPlayedGames(ctx context.Context, limit int32) ([]GetO
for rows.Next() {
var i GetOldestPlayedGamesRow
if err := rows.Scan(
&i.GameID,
&i.GameName,
&i.GamePlayed,
&i.GameLastPlayed,
&i.SoundtrackID,
&i.SoundtrackName,
&i.SoundtrackPlayed,
&i.SoundtrackLastPlayed,
&i.Songs,
); err != nil {
return nil, err
@@ -397,25 +397,25 @@ func (q *Queries) GetOldestPlayedGames(ctx context.Context, limit int32) ([]GetO
const getStatisticsSummary = `-- name: GetStatisticsSummary :one
SELECT
COUNT(*) as total_games,
SUM(CASE WHEN times_played > 0 THEN 1 ELSE 0 END) as played_games,
SUM(CASE WHEN times_played = 0 THEN 1 ELSE 0 END) as never_played_games,
COALESCE(SUM(times_played), 0)::bigint as total_game_plays,
COALESCE(AVG(times_played), 0)::float as avg_game_plays,
COALESCE(MAX(times_played), 0)::bigint as max_game_plays,
COALESCE(MIN(times_played), 0)::bigint as min_game_plays
FROM game
COUNT(*) as total_soundtracks,
SUM(CASE WHEN times_played > 0 THEN 1 ELSE 0 END) as played_soundtracks,
SUM(CASE WHEN times_played = 0 THEN 1 ELSE 0 END) as never_played_soundtracks,
COALESCE(SUM(times_played), 0)::bigint as total_soundtrack_plays,
COALESCE(AVG(times_played), 0)::float as avg_soundtrack_plays,
COALESCE(MAX(times_played), 0)::bigint as max_soundtrack_plays,
COALESCE(MIN(times_played), 0)::bigint as min_soundtrack_plays
FROM soundtrack
WHERE deleted IS NULL
`
type GetStatisticsSummaryRow struct {
TotalGames int64 `json:"total_games"`
PlayedGames int64 `json:"played_games"`
NeverPlayedGames int64 `json:"never_played_games"`
TotalGamePlays int64 `json:"total_game_plays"`
AvgGamePlays float64 `json:"avg_game_plays"`
MaxGamePlays int64 `json:"max_game_plays"`
MinGamePlays int64 `json:"min_game_plays"`
TotalSoundtracks int64 `json:"total_soundtracks"`
PlayedSoundtracks int64 `json:"played_soundtracks"`
NeverPlayedSoundtracks int64 `json:"never_played_soundtracks"`
TotalSoundtrackPlays int64 `json:"total_soundtrack_plays"`
AvgSoundtrackPlays float64 `json:"avg_soundtrack_plays"`
MaxSoundtrackPlays int64 `json:"max_soundtrack_plays"`
MinSoundtrackPlays int64 `json:"min_soundtrack_plays"`
}
// Get statistics summary
@@ -423,13 +423,13 @@ func (q *Queries) GetStatisticsSummary(ctx context.Context) (GetStatisticsSummar
row := q.db.QueryRow(ctx, getStatisticsSummary)
var i GetStatisticsSummaryRow
err := row.Scan(
&i.TotalGames,
&i.PlayedGames,
&i.NeverPlayedGames,
&i.TotalGamePlays,
&i.AvgGamePlays,
&i.MaxGamePlays,
&i.MinGamePlays,
&i.TotalSoundtracks,
&i.PlayedSoundtracks,
&i.NeverPlayedSoundtracks,
&i.TotalSoundtrackPlays,
&i.AvgSoundtrackPlays,
&i.MaxSoundtrackPlays,
&i.MinSoundtrackPlays,
)
return i, err
}
+10 -10
View File
@@ -229,8 +229,8 @@ func (m *MusicHandler) GetPreviousSong(ctx *echo.Context) error {
return ctx.Stream(http.StatusOK, "audio/mpeg", file)
}
// GetAllGames godoc
// @Summary Get all games
// GetAllSoundtracks godoc
// @Summary Get all soundtracks
// @Description Returns a list of all games in order
// @Tags music
// @Accept json
@@ -238,17 +238,17 @@ func (m *MusicHandler) GetPreviousSong(ctx *echo.Context) error {
// @Success 200 {array} map[string]interface{}
// @Failure 423 {string} string "Syncing is in progress"
// @Router /music/all/order [get]
func (m *MusicHandler) GetAllGames(ctx *echo.Context) error {
func (m *MusicHandler) GetAllSoundtracks(ctx *echo.Context) error {
if backend.Syncing {
logging.GetLogger().Info("Syncing is in progress")
return ctx.JSON(http.StatusLocked, "Syncing is in progress")
}
gameList := backend.GetAllGames()
return ctx.JSON(http.StatusOK, gameList)
soundtrackList := backend.GetAllSoundtracks()
return ctx.JSON(http.StatusOK, soundtrackList)
}
// GetAllGamesRandom godoc
// @Summary Get all games random
// GetAllSoundtracksRandom godoc
// @Summary Get all soundtracks random
// @Description Returns a list of all games in random order
// @Tags music
// @Accept json
@@ -256,13 +256,13 @@ func (m *MusicHandler) GetAllGames(ctx *echo.Context) error {
// @Success 200 {array} map[string]interface{}
// @Failure 423 {string} string "Syncing is in progress"
// @Router /music/all/random [get]
func (m *MusicHandler) GetAllGamesRandom(ctx *echo.Context) error {
func (m *MusicHandler) GetAllSoundtracksRandom(ctx *echo.Context) error {
if backend.Syncing {
logging.GetLogger().Info("Syncing is in progress")
return ctx.JSON(http.StatusLocked, "Syncing is in progress")
}
gameList := backend.GetAllGamesRandom()
return ctx.JSON(http.StatusOK, gameList)
soundtrackList := backend.GetAllSoundtracksRandom()
return ctx.JSON(http.StatusOK, soundtrackList)
}
// PutPlayed godoc
+9 -9
View File
@@ -82,13 +82,13 @@ func (s *Server) RegisterRoutes() http.Handler {
sync := NewSyncHandler()
syncGroup := e.Group("/sync")
syncGroup.GET("", deprecatedMiddleware(sync.SyncGamesNewOnlyChanges))
syncGroup.GET("", deprecatedMiddleware(sync.SyncSoundtracksNewOnlyChanges))
syncGroup.GET("/progress", deprecatedMiddleware(sync.SyncProgress))
syncGroup.GET("/new", deprecatedMiddleware(sync.SyncGamesNewOnlyChanges))
syncGroup.GET("/full", deprecatedMiddleware(sync.SyncGamesNewFull))
syncGroup.GET("/new/full", deprecatedMiddleware(sync.SyncGamesNewFull))
syncGroup.GET("/quick", deprecatedMiddleware(sync.SyncGamesNewOnlyChanges))
syncGroup.GET("/reset", deprecatedMiddleware(sync.ResetGames))
syncGroup.GET("/new", deprecatedMiddleware(sync.SyncSoundtracksNewOnlyChanges))
syncGroup.GET("/full", deprecatedMiddleware(sync.SyncSoundtracksNewFull))
syncGroup.GET("/new/full", deprecatedMiddleware(sync.SyncSoundtracksNewFull))
syncGroup.GET("/quick", deprecatedMiddleware(sync.SyncSoundtracksNewOnlyChanges))
syncGroup.GET("/reset", deprecatedMiddleware(sync.ResetDB))
music := NewMusicHandler()
musicGroup := e.Group("/music")
@@ -102,9 +102,9 @@ func (s *Server) RegisterRoutes() http.Handler {
musicGroup.GET("/list", deprecatedMiddleware(music.GetPlayedSongs))
musicGroup.GET("/next", deprecatedMiddleware(music.GetNextSong))
musicGroup.GET("/previous", deprecatedMiddleware(music.GetPreviousSong))
musicGroup.GET("/all", deprecatedMiddleware(music.GetAllGamesRandom))
musicGroup.GET("/all/order", deprecatedMiddleware(music.GetAllGames))
musicGroup.GET("/all/random", deprecatedMiddleware(music.GetAllGamesRandom))
musicGroup.GET("/all", deprecatedMiddleware(music.GetAllSoundtracksRandom))
musicGroup.GET("/all/order", deprecatedMiddleware(music.GetAllSoundtracks))
musicGroup.GET("/all/random", deprecatedMiddleware(music.GetAllSoundtracksRandom))
musicGroup.PUT("/played", deprecatedMiddleware(music.PutPlayed))
musicGroup.GET("/addQue", deprecatedMiddleware(music.AddLatestToQue))
musicGroup.GET("/addPlayed", deprecatedMiddleware(music.AddLatestPlayed))
+17 -17
View File
@@ -34,59 +34,59 @@ func (s *SyncHandler) SyncProgress(ctx *echo.Context) error {
return ctx.JSON(http.StatusOK, response)
}
// SyncGamesNewOnlyChanges godoc
// @Summary Sync games with only changes
// SyncSoundtracksNewOnlyChanges godoc
// @Summary Sync soundtracks with only changes
// @Description Starts syncing games with only new changes
// @Tags sync
// @Accept json
// @Produce json
// @Success 200 {string} string "Start syncing games"
// @Success 200 {string} string "Start syncing soundtracks"
// @Failure 423 {string} string "Syncing is in progress"
// @Router /sync [get]
func (s *SyncHandler) SyncGamesNewOnlyChanges(ctx *echo.Context) error {
func (s *SyncHandler) SyncSoundtracksNewOnlyChanges(ctx *echo.Context) error {
if backend.Syncing {
logging.GetLogger().Warn("Syncing is already in progress")
return ctx.JSON(http.StatusLocked, "Syncing is in progress")
}
logging.GetLogger().Info("Starting sync with only changes")
go backend.SyncGamesNewOnlyChanges()
return ctx.JSON(http.StatusOK, "Start syncing games")
go backend.SyncSoundtracksNewOnlyChanges()
return ctx.JSON(http.StatusOK, "Start syncing soundtracks")
}
// SyncGamesNewFull godoc
// SyncSoundtracksNewFull godoc
// @Summary Sync all games fully
// @Description Starts a full sync of all games
// @Tags sync
// @Accept json
// @Produce json
// @Success 200 {string} string "Start syncing games full"
// @Success 200 {string} string "Start syncing soundtracks full"
// @Failure 423 {string} string "Syncing is in progress"
// @Router /sync/full [get]
func (s *SyncHandler) SyncGamesNewFull(ctx *echo.Context) error {
func (s *SyncHandler) SyncSoundtracksNewFull(ctx *echo.Context) error {
if backend.Syncing {
logging.GetLogger().Warn("Syncing is already in progress")
return ctx.JSON(http.StatusLocked, "Syncing is in progress")
}
logging.GetLogger().Info("Starting full sync")
go backend.SyncGamesNewFull()
return ctx.JSON(http.StatusOK, "Start syncing games full")
go backend.SyncSoundtracksNewFull()
return ctx.JSON(http.StatusOK, "Start syncing soundtracks full")
}
// ResetGames godoc
// @Summary Reset games database
// ResetDB godoc
// @Summary Reset soundtracks database
// @Description Resets the games database by deleting all games and songs
// @Tags sync
// @Accept json
// @Produce json
// @Success 200 {string} string "Games and songs are deleted from the database"
// @Success 200 {string} string "Soundtracks and songs are deleted from the database"
// @Failure 423 {string} string "Syncing is in progress"
// @Router /sync/reset [get]
func (s *SyncHandler) ResetGames(ctx *echo.Context) error {
func (s *SyncHandler) ResetDB(ctx *echo.Context) error {
if backend.Syncing {
logging.GetLogger().Warn("Cannot reset - syncing is in progress")
return ctx.JSON(http.StatusLocked, "Syncing is in progress")
}
logging.GetLogger().Info("Resetting games database")
logging.GetLogger().Info("Resetting soundtracks database")
backend.ResetDB()
return ctx.JSON(http.StatusOK, "Games and songs are deleted from the database")
return ctx.JSON(http.StatusOK, "Soundtracks and songs are deleted from the database")
}