#9 Major routes refactor and expansion, #15 Added API for statistics, Added search cache backend and functionality tests, Backend sync improvements
Build / build (push) Successful in 56s
Build / build (push) Successful in 56s
This commit is contained in:
1 parent
e86c0f8e04
commit
a8a2602f50
34 files changed
+1819
-1294
No files matched your search
@@ -1,33 +0,0 @@
|
||||
-- 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;
|
||||
@@ -1,32 +0,0 @@
|
||||
-- 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);
|
||||
|
||||
-- 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;
|
||||
@@ -1,24 +0,0 @@
|
||||
-- Rollback: Remove id column and restore composite PK
|
||||
|
||||
-- Step 1: Drop indexes created in up migration
|
||||
DROP INDEX IF EXISTS idx_song_soundtrack_id;
|
||||
DROP INDEX IF EXISTS idx_song_path;
|
||||
|
||||
-- Step 2: Drop foreign key constraint
|
||||
ALTER TABLE song DROP CONSTRAINT IF EXISTS song_soundtrack_id_fkey;
|
||||
|
||||
-- Step 3: Drop new primary key
|
||||
ALTER TABLE song DROP CONSTRAINT song_pkey;
|
||||
|
||||
-- Step 4: Drop unique constraint on id
|
||||
ALTER TABLE song DROP CONSTRAINT IF EXISTS song_id_unique;
|
||||
|
||||
-- Step 5: Restore composite primary key
|
||||
ALTER TABLE song ADD CONSTRAINT song_pkey PRIMARY KEY (soundtrack_id, path);
|
||||
|
||||
-- Step 6: Drop the id column
|
||||
ALTER TABLE song DROP COLUMN id;
|
||||
|
||||
-- Step 7: Recreate original foreign key (soundtrack_id references soundtrack.id)
|
||||
ALTER TABLE song ADD CONSTRAINT song_soundtrack_id_fkey
|
||||
FOREIGN KEY (soundtrack_id) REFERENCES soundtrack(id);
|
||||
@@ -1,36 +0,0 @@
|
||||
-- Migration: Add id column to song table and change PK from composite to single column
|
||||
-- This prepares the song table for eventual UUID migration
|
||||
|
||||
-- Step 1: Add new id column (nullable initially)
|
||||
ALTER TABLE song ADD COLUMN id serial4;
|
||||
|
||||
-- Step 2: Create unique constraint on id (allows backfilling)
|
||||
ALTER TABLE song ADD CONSTRAINT song_id_unique UNIQUE (id);
|
||||
|
||||
-- Step 3: Backfill existing rows with sequential IDs
|
||||
-- Use DEFAULT which pulls from the sequence
|
||||
UPDATE song SET id = DEFAULT WHERE id IS NULL;
|
||||
|
||||
-- Step 4: Verify all rows have an id
|
||||
-- If this returns 0, backfill worked
|
||||
-- SELECT COUNT(*) FROM song WHERE id IS NULL;
|
||||
|
||||
-- Step 5: Drop the composite primary key (soundtrack_id, path)
|
||||
ALTER TABLE song DROP CONSTRAINT song_pkey;
|
||||
|
||||
-- Step 6: Add new primary key on id column
|
||||
ALTER TABLE song ADD CONSTRAINT song_pkey PRIMARY KEY (id);
|
||||
|
||||
-- Step 7: Ensure soundtrack_id remains a foreign key to soundtrack
|
||||
-- First drop existing FK if it exists (from the rename migration)
|
||||
ALTER TABLE song DROP CONSTRAINT IF EXISTS song_soundtrack_id_fkey;
|
||||
|
||||
-- Then recreate it
|
||||
ALTER TABLE song ADD CONSTRAINT song_soundtrack_id_fkey
|
||||
FOREIGN KEY (soundtrack_id) REFERENCES soundtrack(id);
|
||||
|
||||
-- Step 8: Create index on soundtrack_id for query performance
|
||||
CREATE INDEX IF NOT EXISTS idx_song_soundtrack_id ON song(soundtrack_id);
|
||||
|
||||
-- Step 9: Create index on path for lookups (previously part of PK)
|
||||
CREATE INDEX IF NOT EXISTS idx_song_path ON song(path);
|
||||
@@ -5,7 +5,7 @@ DELETE FROM song;
|
||||
DELETE FROM song WHERE soundtrack_id = $1;
|
||||
|
||||
-- name: AddSong :exec
|
||||
INSERT INTO song(soundtrack_id, song_name, path, file_name, hash) VALUES ($1, $2, $3, $4, $5);
|
||||
INSERT INTO song(soundtrack_id, song_name, path, file_name, hash, uuid, soundtrack_uuid) VALUES ($1, $2, $3, $4, $5, $6, $7);
|
||||
|
||||
-- name: CheckSong :one
|
||||
SELECT COUNT(*) FROM song WHERE soundtrack_id = $1 AND path = $2;
|
||||
@@ -34,11 +34,19 @@ WHERE soundtrack_id = $1 AND song_name = $2;
|
||||
-- name: FetchAllSongs :many
|
||||
SELECT * FROM song;
|
||||
|
||||
-- name: GetSongById :one
|
||||
SELECT * FROM song WHERE id = $1;
|
||||
-- name: GetSongByUUID :one
|
||||
SELECT * FROM song WHERE uuid = $1;
|
||||
|
||||
-- name: RemoveBrokenSong :exec
|
||||
DELETE FROM song WHERE soundtrack_id = $1 AND path = $2;
|
||||
|
||||
-- name: RemoveBrokenSongs :exec
|
||||
DELETE FROM song WHERE id = ANY($1);
|
||||
DELETE FROM song WHERE uuid = ANY($1);
|
||||
|
||||
-- name: GetSongsBySoundtrackUUID :many
|
||||
SELECT *
|
||||
FROM song
|
||||
WHERE soundtrack_uuid = $1;
|
||||
|
||||
-- name: GetSongUUIDsBySoundtrackId :many
|
||||
SELECT uuid, soundtrack_uuid FROM song WHERE soundtrack_id = $1;
|
||||
@@ -29,7 +29,7 @@ UPDATE soundtrack SET deleted=NULL WHERE id=$1;
|
||||
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;
|
||||
INSERT INTO soundtrack (soundtrack_name, path, hash, added, uuid) VALUES ($1, $2, $3, now(), $4) returning id, uuid;
|
||||
|
||||
-- name: InsertSoundtrackWithExistingId :exec
|
||||
INSERT INTO soundtrack (id, soundtrack_name, path, hash, added) VALUES ($1, $2, $3, $4, now());
|
||||
@@ -47,3 +47,12 @@ ORDER BY soundtrack_name;
|
||||
|
||||
-- name: AddSoundtrackPlayed :exec
|
||||
UPDATE soundtrack SET times_played = times_played + 1, last_played = now() WHERE id = $1;
|
||||
|
||||
-- name: GetSoundtrackByUUID :one
|
||||
SELECT *
|
||||
FROM soundtrack
|
||||
WHERE uuid = $1
|
||||
AND deleted IS NULL;
|
||||
|
||||
-- name: GetSoundtrackUUIDById :one
|
||||
SELECT uuid FROM soundtrack WHERE id = $1;
|
||||
@@ -7,6 +7,7 @@ package repository
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
@@ -20,13 +21,14 @@ type Session struct {
|
||||
}
|
||||
|
||||
type Song struct {
|
||||
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"`
|
||||
ID pgtype.Int4 `json:"id"`
|
||||
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"`
|
||||
Uuid uuid.UUID `json:"uuid"`
|
||||
SoundtrackUuid uuid.UUID `json:"soundtrack_uuid"`
|
||||
}
|
||||
|
||||
type SongList struct {
|
||||
@@ -48,6 +50,7 @@ type Soundtrack struct {
|
||||
LastPlayed *time.Time `json:"last_played"`
|
||||
NumberOfSongs int32 `json:"number_of_songs"`
|
||||
Hash string `json:"hash"`
|
||||
Uuid uuid.UUID `json:"uuid"`
|
||||
}
|
||||
|
||||
type Vgmq struct {
|
||||
|
||||
@@ -8,7 +8,7 @@ package repository
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const addHashToSong = `-- name: AddHashToSong :exec
|
||||
@@ -27,15 +27,17 @@ func (q *Queries) AddHashToSong(ctx context.Context, arg AddHashToSongParams) er
|
||||
}
|
||||
|
||||
const addSong = `-- name: AddSong :exec
|
||||
INSERT INTO song(soundtrack_id, song_name, path, file_name, hash) VALUES ($1, $2, $3, $4, $5)
|
||||
INSERT INTO song(soundtrack_id, song_name, path, file_name, hash, uuid, soundtrack_uuid) VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||
`
|
||||
|
||||
type AddSongParams struct {
|
||||
SoundtrackID int32 `json:"soundtrack_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"`
|
||||
Uuid uuid.UUID `json:"uuid"`
|
||||
SoundtrackUuid uuid.UUID `json:"soundtrack_uuid"`
|
||||
}
|
||||
|
||||
func (q *Queries) AddSong(ctx context.Context, arg AddSongParams) error {
|
||||
@@ -45,6 +47,8 @@ func (q *Queries) AddSong(ctx context.Context, arg AddSongParams) error {
|
||||
arg.Path,
|
||||
arg.FileName,
|
||||
arg.Hash,
|
||||
arg.Uuid,
|
||||
arg.SoundtrackUuid,
|
||||
)
|
||||
return err
|
||||
}
|
||||
@@ -110,7 +114,7 @@ func (q *Queries) ClearSongsBySoundtrackId(ctx context.Context, soundtrackID int
|
||||
}
|
||||
|
||||
const fetchAllSongs = `-- name: FetchAllSongs :many
|
||||
SELECT soundtrack_id, song_name, path, times_played, hash, file_name, id FROM song
|
||||
SELECT soundtrack_id, song_name, path, times_played, hash, file_name, uuid, soundtrack_uuid FROM song
|
||||
`
|
||||
|
||||
func (q *Queries) FetchAllSongs(ctx context.Context) ([]Song, error) {
|
||||
@@ -129,7 +133,8 @@ func (q *Queries) FetchAllSongs(ctx context.Context) ([]Song, error) {
|
||||
&i.TimesPlayed,
|
||||
&i.Hash,
|
||||
&i.FileName,
|
||||
&i.ID,
|
||||
&i.Uuid,
|
||||
&i.SoundtrackUuid,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -142,7 +147,7 @@ func (q *Queries) FetchAllSongs(ctx context.Context) ([]Song, error) {
|
||||
}
|
||||
|
||||
const findSongsFromSoundtrack = `-- name: FindSongsFromSoundtrack :many
|
||||
SELECT soundtrack_id, song_name, path, times_played, hash, file_name, id
|
||||
SELECT soundtrack_id, song_name, path, times_played, hash, file_name, uuid, soundtrack_uuid
|
||||
FROM song
|
||||
WHERE soundtrack_id = $1
|
||||
`
|
||||
@@ -163,7 +168,8 @@ func (q *Queries) FindSongsFromSoundtrack(ctx context.Context, soundtrackID int3
|
||||
&i.TimesPlayed,
|
||||
&i.Hash,
|
||||
&i.FileName,
|
||||
&i.ID,
|
||||
&i.Uuid,
|
||||
&i.SoundtrackUuid,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -175,12 +181,12 @@ func (q *Queries) FindSongsFromSoundtrack(ctx context.Context, soundtrackID int3
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getSongById = `-- name: GetSongById :one
|
||||
SELECT soundtrack_id, song_name, path, times_played, hash, file_name, id FROM song WHERE id = $1
|
||||
const getSongByUUID = `-- name: GetSongByUUID :one
|
||||
SELECT soundtrack_id, song_name, path, times_played, hash, file_name, uuid, soundtrack_uuid FROM song WHERE uuid = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetSongById(ctx context.Context, id pgtype.Int4) (Song, error) {
|
||||
row := q.db.QueryRow(ctx, getSongById, id)
|
||||
func (q *Queries) GetSongByUUID(ctx context.Context, argUuid uuid.UUID) (Song, error) {
|
||||
row := q.db.QueryRow(ctx, getSongByUUID, argUuid)
|
||||
var i Song
|
||||
err := row.Scan(
|
||||
&i.SoundtrackID,
|
||||
@@ -189,13 +195,43 @@ func (q *Queries) GetSongById(ctx context.Context, id pgtype.Int4) (Song, error)
|
||||
&i.TimesPlayed,
|
||||
&i.Hash,
|
||||
&i.FileName,
|
||||
&i.ID,
|
||||
&i.Uuid,
|
||||
&i.SoundtrackUuid,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getSongUUIDsBySoundtrackId = `-- name: GetSongUUIDsBySoundtrackId :many
|
||||
SELECT uuid, soundtrack_uuid FROM song WHERE soundtrack_id = $1
|
||||
`
|
||||
|
||||
type GetSongUUIDsBySoundtrackIdRow struct {
|
||||
Uuid uuid.UUID `json:"uuid"`
|
||||
SoundtrackUuid uuid.UUID `json:"soundtrack_uuid"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetSongUUIDsBySoundtrackId(ctx context.Context, soundtrackID int32) ([]GetSongUUIDsBySoundtrackIdRow, error) {
|
||||
rows, err := q.db.Query(ctx, getSongUUIDsBySoundtrackId, soundtrackID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetSongUUIDsBySoundtrackIdRow
|
||||
for rows.Next() {
|
||||
var i GetSongUUIDsBySoundtrackIdRow
|
||||
if err := rows.Scan(&i.Uuid, &i.SoundtrackUuid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getSongWithHash = `-- name: GetSongWithHash :one
|
||||
SELECT soundtrack_id, song_name, path, times_played, hash, file_name, id FROM song WHERE hash = $1
|
||||
SELECT soundtrack_id, song_name, path, times_played, hash, file_name, uuid, soundtrack_uuid FROM song WHERE hash = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetSongWithHash(ctx context.Context, hash string) (Song, error) {
|
||||
@@ -208,11 +244,47 @@ func (q *Queries) GetSongWithHash(ctx context.Context, hash string) (Song, error
|
||||
&i.TimesPlayed,
|
||||
&i.Hash,
|
||||
&i.FileName,
|
||||
&i.ID,
|
||||
&i.Uuid,
|
||||
&i.SoundtrackUuid,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getSongsBySoundtrackUUID = `-- name: GetSongsBySoundtrackUUID :many
|
||||
SELECT soundtrack_id, song_name, path, times_played, hash, file_name, uuid, soundtrack_uuid
|
||||
FROM song
|
||||
WHERE soundtrack_uuid = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetSongsBySoundtrackUUID(ctx context.Context, soundtrackUuid uuid.UUID) ([]Song, error) {
|
||||
rows, err := q.db.Query(ctx, getSongsBySoundtrackUUID, soundtrackUuid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Song
|
||||
for rows.Next() {
|
||||
var i Song
|
||||
if err := rows.Scan(
|
||||
&i.SoundtrackID,
|
||||
&i.SongName,
|
||||
&i.Path,
|
||||
&i.TimesPlayed,
|
||||
&i.Hash,
|
||||
&i.FileName,
|
||||
&i.Uuid,
|
||||
&i.SoundtrackUuid,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const removeBrokenSong = `-- name: RemoveBrokenSong :exec
|
||||
DELETE FROM song WHERE soundtrack_id = $1 AND path = $2
|
||||
`
|
||||
@@ -228,11 +300,11 @@ func (q *Queries) RemoveBrokenSong(ctx context.Context, arg RemoveBrokenSongPara
|
||||
}
|
||||
|
||||
const removeBrokenSongs = `-- name: RemoveBrokenSongs :exec
|
||||
DELETE FROM song WHERE id = ANY($1)
|
||||
DELETE FROM song WHERE uuid = ANY($1)
|
||||
`
|
||||
|
||||
func (q *Queries) RemoveBrokenSongs(ctx context.Context, id pgtype.Int4) error {
|
||||
_, err := q.db.Exec(ctx, removeBrokenSongs, id)
|
||||
func (q *Queries) RemoveBrokenSongs(ctx context.Context, argUuid uuid.UUID) error {
|
||||
_, err := q.db.Exec(ctx, removeBrokenSongs, argUuid)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const addSoundtrackPlayed = `-- name: AddSoundtrackPlayed :exec
|
||||
@@ -28,7 +30,7 @@ func (q *Queries) ClearSoundtracks(ctx context.Context) error {
|
||||
}
|
||||
|
||||
const findAllSoundtracks = `-- name: FindAllSoundtracks :many
|
||||
SELECT id, soundtrack_name, added, deleted, last_changed, path, times_played, last_played, number_of_songs, hash
|
||||
SELECT id, soundtrack_name, added, deleted, last_changed, path, times_played, last_played, number_of_songs, hash, uuid
|
||||
FROM soundtrack
|
||||
WHERE deleted IS NULL
|
||||
ORDER BY soundtrack_name
|
||||
@@ -54,6 +56,7 @@ func (q *Queries) FindAllSoundtracks(ctx context.Context) ([]Soundtrack, error)
|
||||
&i.LastPlayed,
|
||||
&i.NumberOfSongs,
|
||||
&i.Hash,
|
||||
&i.Uuid,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -66,7 +69,7 @@ func (q *Queries) FindAllSoundtracks(ctx context.Context) ([]Soundtrack, error)
|
||||
}
|
||||
|
||||
const getAllSoundtracksIncludingDeleted = `-- name: GetAllSoundtracksIncludingDeleted :many
|
||||
SELECT id, soundtrack_name, added, deleted, last_changed, path, times_played, last_played, number_of_songs, hash
|
||||
SELECT id, soundtrack_name, added, deleted, last_changed, path, times_played, last_played, number_of_songs, hash, uuid
|
||||
FROM soundtrack
|
||||
ORDER BY soundtrack_name
|
||||
`
|
||||
@@ -91,6 +94,7 @@ func (q *Queries) GetAllSoundtracksIncludingDeleted(ctx context.Context) ([]Soun
|
||||
&i.LastPlayed,
|
||||
&i.NumberOfSongs,
|
||||
&i.Hash,
|
||||
&i.Uuid,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -114,7 +118,7 @@ func (q *Queries) GetIdBySoundtrackName(ctx context.Context, soundtrackName stri
|
||||
}
|
||||
|
||||
const getSoundtrackById = `-- name: GetSoundtrackById :one
|
||||
SELECT id, soundtrack_name, added, deleted, last_changed, path, times_played, last_played, number_of_songs, hash
|
||||
SELECT id, soundtrack_name, added, deleted, last_changed, path, times_played, last_played, number_of_songs, hash, uuid
|
||||
FROM soundtrack
|
||||
WHERE id = $1
|
||||
AND deleted IS NULL
|
||||
@@ -134,6 +138,33 @@ func (q *Queries) GetSoundtrackById(ctx context.Context, id int32) (Soundtrack,
|
||||
&i.LastPlayed,
|
||||
&i.NumberOfSongs,
|
||||
&i.Hash,
|
||||
&i.Uuid,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getSoundtrackByUUID = `-- name: GetSoundtrackByUUID :one
|
||||
SELECT id, soundtrack_name, added, deleted, last_changed, path, times_played, last_played, number_of_songs, hash, uuid
|
||||
FROM soundtrack
|
||||
WHERE uuid = $1
|
||||
AND deleted IS NULL
|
||||
`
|
||||
|
||||
func (q *Queries) GetSoundtrackByUUID(ctx context.Context, argUuid uuid.UUID) (Soundtrack, error) {
|
||||
row := q.db.QueryRow(ctx, getSoundtrackByUUID, argUuid)
|
||||
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,
|
||||
&i.Uuid,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@@ -149,21 +180,43 @@ func (q *Queries) GetSoundtrackNameById(ctx context.Context, id int32) (string,
|
||||
return soundtrack_name, err
|
||||
}
|
||||
|
||||
const getSoundtrackUUIDById = `-- name: GetSoundtrackUUIDById :one
|
||||
SELECT uuid FROM soundtrack WHERE id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetSoundtrackUUIDById(ctx context.Context, id int32) (uuid.UUID, error) {
|
||||
row := q.db.QueryRow(ctx, getSoundtrackUUIDById, id)
|
||||
var uuid uuid.UUID
|
||||
err := row.Scan(&uuid)
|
||||
return uuid, err
|
||||
}
|
||||
|
||||
const insertSoundtrack = `-- name: InsertSoundtrack :one
|
||||
INSERT INTO soundtrack (soundtrack_name, path, hash, added) VALUES ($1, $2, $3, now()) returning id
|
||||
INSERT INTO soundtrack (soundtrack_name, path, hash, added, uuid) VALUES ($1, $2, $3, now(), $4) returning id, uuid
|
||||
`
|
||||
|
||||
type InsertSoundtrackParams struct {
|
||||
SoundtrackName string `json:"soundtrack_name"`
|
||||
Path string `json:"path"`
|
||||
Hash string `json:"hash"`
|
||||
SoundtrackName string `json:"soundtrack_name"`
|
||||
Path string `json:"path"`
|
||||
Hash string `json:"hash"`
|
||||
Uuid uuid.UUID `json:"uuid"`
|
||||
}
|
||||
|
||||
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
|
||||
type InsertSoundtrackRow struct {
|
||||
ID int32 `json:"id"`
|
||||
Uuid uuid.UUID `json:"uuid"`
|
||||
}
|
||||
|
||||
func (q *Queries) InsertSoundtrack(ctx context.Context, arg InsertSoundtrackParams) (InsertSoundtrackRow, error) {
|
||||
row := q.db.QueryRow(ctx, insertSoundtrack,
|
||||
arg.SoundtrackName,
|
||||
arg.Path,
|
||||
arg.Hash,
|
||||
arg.Uuid,
|
||||
)
|
||||
var i InsertSoundtrackRow
|
||||
err := row.Scan(&i.ID, &i.Uuid)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const insertSoundtrackWithExistingId = `-- name: InsertSoundtrackWithExistingId :exec
|
||||
|
||||
@@ -66,63 +66,6 @@ func (q *Queries) GetLastPlayedSoundtracks(ctx context.Context, limit int32) ([]
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getLeastPlayedSoundtracksWithSongs = `-- name: GetLeastPlayedSoundtracksWithSongs :many
|
||||
SELECT
|
||||
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,
|
||||
'path', s.path,
|
||||
'times_played', s.times_played,
|
||||
'file_name', s.file_name
|
||||
)
|
||||
) as songs
|
||||
FROM soundtrack g
|
||||
LEFT JOIN song s ON g.id = s.soundtrack_id
|
||||
WHERE g.deleted IS NULL
|
||||
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 GetLeastPlayedSoundtracksWithSongsRow struct {
|
||||
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 soundtracks with their songs
|
||||
func (q *Queries) GetLeastPlayedSoundtracksWithSongs(ctx context.Context, limit int32) ([]GetLeastPlayedSoundtracksWithSongsRow, error) {
|
||||
rows, err := q.db.Query(ctx, getLeastPlayedSoundtracksWithSongs, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetLeastPlayedSoundtracksWithSongsRow
|
||||
for rows.Next() {
|
||||
var i GetLeastPlayedSoundtracksWithSongsRow
|
||||
if err := rows.Scan(
|
||||
&i.SoundtrackID,
|
||||
&i.SoundtrackName,
|
||||
&i.SoundtrackPlayed,
|
||||
&i.SoundtrackLastPlayed,
|
||||
&i.Songs,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getLeastPlayedSongsWithSoundtrack = `-- name: GetLeastPlayedSongsWithSoundtrack :many
|
||||
SELECT
|
||||
s.soundtrack_id as soundtrack_id,
|
||||
@@ -175,7 +118,7 @@ func (q *Queries) GetLeastPlayedSongsWithSoundtrack(ctx context.Context, limit i
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getMostPlayedSoundtracksWithSongs = `-- name: GetMostPlayedSoundtracksWithSongs :many
|
||||
const getLeastPlayedSoundtracksWithSongs = `-- name: GetLeastPlayedSoundtracksWithSongs :many
|
||||
SELECT
|
||||
g.id as soundtrack_id,
|
||||
g.soundtrack_name,
|
||||
@@ -193,11 +136,11 @@ FROM soundtrack g
|
||||
LEFT JOIN song s ON g.id = s.soundtrack_id
|
||||
WHERE g.deleted IS NULL
|
||||
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
|
||||
ORDER BY g.times_played DESC, g.soundtrack_name
|
||||
ORDER BY g.times_played ASC, g.soundtrack_name
|
||||
LIMIT $1
|
||||
`
|
||||
|
||||
type GetMostPlayedSoundtracksWithSongsRow struct {
|
||||
type GetLeastPlayedSoundtracksWithSongsRow struct {
|
||||
SoundtrackID int32 `json:"soundtrack_id"`
|
||||
SoundtrackName string `json:"soundtrack_name"`
|
||||
SoundtrackPlayed int32 `json:"soundtrack_played"`
|
||||
@@ -205,16 +148,16 @@ type GetMostPlayedSoundtracksWithSongsRow struct {
|
||||
Songs []byte `json:"songs"`
|
||||
}
|
||||
|
||||
// Most played soundtracks with their songs
|
||||
func (q *Queries) GetMostPlayedSoundtracksWithSongs(ctx context.Context, limit int32) ([]GetMostPlayedSoundtracksWithSongsRow, error) {
|
||||
rows, err := q.db.Query(ctx, getMostPlayedSoundtracksWithSongs, limit)
|
||||
// Least played soundtracks with their songs
|
||||
func (q *Queries) GetLeastPlayedSoundtracksWithSongs(ctx context.Context, limit int32) ([]GetLeastPlayedSoundtracksWithSongsRow, error) {
|
||||
rows, err := q.db.Query(ctx, getLeastPlayedSoundtracksWithSongs, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetMostPlayedSoundtracksWithSongsRow
|
||||
var items []GetLeastPlayedSoundtracksWithSongsRow
|
||||
for rows.Next() {
|
||||
var i GetMostPlayedSoundtracksWithSongsRow
|
||||
var i GetLeastPlayedSoundtracksWithSongsRow
|
||||
if err := rows.Scan(
|
||||
&i.SoundtrackID,
|
||||
&i.SoundtrackName,
|
||||
@@ -284,6 +227,63 @@ func (q *Queries) GetMostPlayedSongsWithSoundtrack(ctx context.Context, limit in
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getMostPlayedSoundtracksWithSongs = `-- name: GetMostPlayedSoundtracksWithSongs :many
|
||||
SELECT
|
||||
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,
|
||||
'path', s.path,
|
||||
'times_played', s.times_played,
|
||||
'file_name', s.file_name
|
||||
)
|
||||
) as songs
|
||||
FROM soundtrack g
|
||||
LEFT JOIN song s ON g.id = s.soundtrack_id
|
||||
WHERE g.deleted IS NULL
|
||||
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 GetMostPlayedSoundtracksWithSongsRow struct {
|
||||
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 soundtracks with their songs
|
||||
func (q *Queries) GetMostPlayedSoundtracksWithSongs(ctx context.Context, limit int32) ([]GetMostPlayedSoundtracksWithSongsRow, error) {
|
||||
rows, err := q.db.Query(ctx, getMostPlayedSoundtracksWithSongs, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetMostPlayedSoundtracksWithSongsRow
|
||||
for rows.Next() {
|
||||
var i GetMostPlayedSoundtracksWithSongsRow
|
||||
if err := rows.Scan(
|
||||
&i.SoundtrackID,
|
||||
&i.SoundtrackName,
|
||||
&i.SoundtrackPlayed,
|
||||
&i.SoundtrackLastPlayed,
|
||||
&i.Songs,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getNeverPlayedSoundtracks = `-- name: GetNeverPlayedSoundtracks :many
|
||||
SELECT
|
||||
g.id as soundtrack_id,
|
||||
|
||||
Reference in new issue
Block a user