Moved around more code. Implemented more sqlc. Added support to generate swagger.

Added support for profiling. Removed the pkg module altogether.
Everything except old sync is now using code generated by sqlc.
This commit is contained in:
2025-01-15 16:04:14 +01:00
parent db8214cb02
commit d653463f58
43 changed files with 947 additions and 1133 deletions

199
internal/db/dbHelper.go Normal file
View File

@@ -0,0 +1,199 @@
package db
import (
"context"
"database/sql"
"embed"
"fmt"
"log"
"os"
"strconv"
"time"
"github.com/golang-migrate/migrate/v4"
"github.com/golang-migrate/migrate/v4/database/postgres"
_ "github.com/golang-migrate/migrate/v4/database/postgres"
_ "github.com/golang-migrate/migrate/v4/source/file"
"github.com/golang-migrate/migrate/v4/source/iofs"
"github.com/jackc/pgx/v5/pgxpool"
_ "github.com/lib/pq"
)
var Dbpool *pgxpool.Pool
var Ctx = context.Background()
//go:embed "migrations/*.sql"
var MigrationsFs embed.FS
func InitDB(host string, port string, user string, password string, dbname string) {
psqlInfo := fmt.Sprintf("host=%s port=%s user=%s "+
"password=%s dbname=%s sslmode=disable",
host, port, user, password, dbname)
fmt.Println(psqlInfo)
var err error
Dbpool, err = pgxpool.New(Ctx, psqlInfo)
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
os.Exit(1)
}
var success string
err = Dbpool.QueryRow(Ctx, "select 'Successfully connected!'").Scan(&success)
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", err)
os.Exit(1)
}
Testf()
fmt.Println(success)
}
func CloseDb() {
fmt.Println("Closing connection to database")
Dbpool.Close()
}
func Testf() {
rows, dbErr := Dbpool.Query(Ctx, "select game_name from game")
if dbErr != nil {
_, _ = fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", dbErr)
os.Exit(1)
}
for rows.Next() {
var gameName string
dbErr = rows.Scan(&gameName)
if dbErr != nil {
_, _ = fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", dbErr)
}
_, _ = fmt.Fprintf(os.Stderr, "%v\n", gameName)
}
}
func ResetGameIdSeq() {
_, err := Dbpool.Query(Ctx, "SELECT setval('game_id_seq', (SELECT MAX(id) FROM game)+1);")
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Exec failed: %v\n", err)
}
}
func Migrate_db(host string, port string, user string, password string, dbname string) {
migrationInfo := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=disable",
user, password, host, port, dbname)
fmt.Println("Migration Info: ", migrationInfo)
db, err := sql.Open("postgres", migrationInfo)
if err != nil {
log.Println(err)
}
driver, err := postgres.WithInstance(db, &postgres.Config{})
if err != nil {
log.Println(err)
}
files, err := iofs.New(MigrationsFs, "migrations")
if err != nil {
log.Fatal(err)
}
m, err := migrate.NewWithInstance("iofs", files, "postgres", driver)
if err != nil {
log.Fatal(err)
}
/*m, err := migrate.NewWithDatabaseInstance(
"file://./db/migrations/",
"postgres", driver)
if err != nil {
log.Println(err)
}*/
version, _, err := m.Version()
if err != nil {
log.Println("Migration version err: ", err)
}
fmt.Println("Migration version before: ", version)
err = m.Force(1)
//err = m.Up() // or m.Steps(2) if you want to explicitly set the number of migrations to run
if err != nil {
log.Println("Force err: ", err)
}
err = m.Migrate(2)
//err = m.Up() // or m.Steps(2) if you want to explicitly set the number of migrations to run
if err != nil {
log.Println("Migration err: ", err)
}
versionAfter, _, err := m.Version()
if err != nil {
log.Println("Migration version err: ", err)
}
fmt.Println("Migration version after: ", versionAfter)
fmt.Println("Migration done")
db.Close()
}
// Health checks the health of the database connection by pinging the database.
// It returns a map with keys indicating various health statistics.
func Health() map[string]string {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
stats := make(map[string]string)
// Ping the database
//err := s.db.PingContext(ctx)
err := Dbpool.Ping(ctx)
if err != nil {
stats["status"] = "down"
stats["error"] = fmt.Sprintf("db down: %v", err)
log.Fatalf("db down: %v", err) // Log the error and terminate the program
return stats
}
// Database is up, add more statistics
stats["status"] = "up"
stats["message"] = "It's healthy"
// Get database stats (like open connections, in use, idle, etc.)
//dbStats := s.db.Stats()
dbStats := Dbpool.Stat()
//stats["open_connections"] = strconv.Itoa(dbStats.OpenConnections)
stats["open_connections"] = strconv.Itoa(int(dbStats.NewConnsCount()))
//stats["in_use"] = strconv.Itoa(dbStats.InUse)
stats["in_use"] = strconv.Itoa(int(dbStats.AcquiredConns()))
//stats["idle"] = strconv.Itoa(dbStats.Idle)
stats["idle"] = strconv.Itoa(int(dbStats.IdleConns()))
//stats["wait_count"] = strconv.FormatInt(dbStats.WaitCount, 10)
stats["wait_count"] = strconv.FormatInt(dbStats.AcquireCount(), 10)
//stats["wait_duration"] = dbStats.WaitDuration.String()
stats["wait_duration"] = dbStats.AcquireDuration().String()
//stats["max_idle_closed"] = strconv.FormatInt(dbStats.MaxIdleClosed, 10)
stats["max_idle_closed"] = strconv.FormatInt(dbStats.MaxIdleDestroyCount(), 10)
//stats["max_lifetime_closed"] = strconv.FormatInt(dbStats.MaxLifetimeClosed, 10)
stats["max_lifetime_closed"] = strconv.FormatInt(dbStats.MaxLifetimeDestroyCount(), 10)
// Evaluate stats to provide a health message
if int(dbStats.NewConnsCount()) > 40 { // Assuming 50 is the max for this example
stats["message"] = "The database is experiencing heavy load."
}
if dbStats.AcquireCount() > 1000 {
stats["message"] = "The database has a high number of wait events, indicating potential bottlenecks."
}
if dbStats.MaxIdleDestroyCount() > int64(dbStats.NewConnsCount())/2 {
stats["message"] = "Many idle connections are being closed, consider revising the connection pool settings."
}
if dbStats.MaxLifetimeDestroyCount() > int64(dbStats.NewConnsCount())/2 {
stats["message"] = "Many connections are being closed due to max lifetime, consider increasing max lifetime or revising the connection usage pattern."
}
return stats
}

View File

@@ -0,0 +1,4 @@
DROP TABLE game;
DROP TABLE song;
DROP TABLE song_list;
DROP TABLE vgmq;

View File

@@ -0,0 +1,43 @@
CREATE TABLE game (
id serial4 NOT NULL,
game_name varchar NOT NULL,
added timestamp NOT NULL,
deleted timestamp NULL,
last_changed timestamp NULL,
"path" varchar NOT NULL,
times_played int4 DEFAULT 0 NULL,
last_played timestamp NULL,
number_of_songs int4 NULL,
hash varchar NULL,
CONSTRAINT game_pkey PRIMARY KEY (id)
);
CREATE TABLE song (
game_id int4 NOT NULL,
song_name varchar NOT NULL,
"path" varchar NOT NULL,
times_played int4 DEFAULT 0 NULL,
hash varchar NULL,
file_name varchar NULL,
CONSTRAINT song_pkey PRIMARY KEY (game_id, path)
);
CREATE TABLE vgmq (
song_no int4 NOT NULL,
"path" varchar(50) NULL,
clue varchar(200) NULL,
answered bool DEFAULT false NOT NULL,
answer varchar(50) NULL,
CONSTRAINT vgmq_pk PRIMARY KEY (song_no)
);
CREATE UNIQUE INDEX vgmq_song_no_uindex ON vgmq USING btree (song_no);
CREATE TABLE song_list (
match_date date NOT NULL,
match_id int4 NOT NULL,
song_no int4 NOT NULL,
game_name varchar(50) NULL,
song_name varchar(50) NULL,
CONSTRAINT song_list_pkey PRIMARY KEY (match_date, match_id, song_no)
);
CREATE INDEX song_list_game_name_idx ON song_list USING btree (game_name);

View File

@@ -0,0 +1,3 @@
Alter table game
alter column number_of_songs set null,
alter column hash set null;

View File

@@ -0,0 +1,19 @@
BEGIN;
UPDATE game
SET number_of_songs = 0
WHERE number_of_songs IS NULL;
UPDATE game
SET hash = ''
WHERE hash IS NULL;
UPDATE song
SET hash = ''
WHERE hash IS NULL;
COMMIT;
BEGIN;
Alter table game
alter column number_of_songs set not null,
alter column number_of_songs set default 0,
ALTER COLUMN hash SET NOT NULL;
ALTER TABLE song
ALTER COLUMN hash SET NOT NULL;
COMMIT;

View File

@@ -0,0 +1,5 @@
Alter table game
alter column times_played set null;
Alter table song
alter column times_played set null;

View File

@@ -0,0 +1,5 @@
Alter table game
alter column times_played set not null;
Alter table song
alter column times_played set not null;

View File

@@ -0,0 +1,49 @@
-- 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;

View File

@@ -0,0 +1,41 @@
-- name: ClearSongs :exec
DELETE FROM song;
-- name: ClearSongsByGameId :exec
DELETE FROM song WHERE game_id = $1;
-- name: AddSong :exec
INSERT INTO song(game_id, song_name, path, file_name, hash) VALUES ($1, $2, $3, $4, $5);
-- name: CheckSong :one
SELECT COUNT(*) FROM song WHERE path = $1;
-- name: CheckSongWithHash :one
SELECT COUNT(*) FROM song WHERE hash = $1;
-- name: GetSongWithHash :one
SELECT * FROM song WHERE hash = $1;
-- name: UpdateSong :exec
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
SELECT *
FROM song
WHERE game_id = $1;
-- name: AddSongPlayed :exec
UPDATE song SET times_played = times_played + 1
WHERE game_id = $1 AND song_name = $2;
-- name: FetchAllSongs :many
SELECT * FROM song;
-- name: RemoveBrokenSong :exec
DELETE FROM song WHERE path = $1;
-- name: RemoveBrokenSongs :exec
DELETE FROM song where path = any (sqlc.slice('paths'));

View File

@@ -0,0 +1,9 @@
-- name: InsertSongInList :exec
INSERT INTO song_list (match_date, match_id, song_no, game_name, song_name)
VALUES ($1, $2, $3, $4, $5);
-- name: GetSongList :many
SELECT *
FROM song_list
WHERE match_date = $1
ORDER BY song_no DESC;

View File

View File

@@ -0,0 +1,32 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.27.0
package repository
import (
"context"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn"
)
type DBTX interface {
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
QueryRow(context.Context, string, ...interface{}) pgx.Row
}
func New(db DBTX) *Queries {
return &Queries{db: db}
}
type Queries struct {
db DBTX
}
func (q *Queries) WithTx(tx pgx.Tx) *Queries {
return &Queries{
db: tx,
}
}

View File

@@ -0,0 +1,246 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.27.0
// 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
}

View File

@@ -0,0 +1,47 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.27.0
package repository
import (
"time"
)
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 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"`
}
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"`
}
type Vgmq struct {
SongNo int32 `json:"song_no"`
Path *string `json:"path"`
Clue *string `json:"clue"`
Answered bool `json:"answered"`
Answer *string `json:"answer"`
}

View File

@@ -0,0 +1,223 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.27.0
// source: song.sql
package repository
import (
"context"
)
const addHashToSong = `-- name: AddHashToSong :exec
UPDATE song SET hash=$1 where path=$2
`
type AddHashToSongParams struct {
Hash string `json:"hash"`
Path string `json:"path"`
}
func (q *Queries) AddHashToSong(ctx context.Context, arg AddHashToSongParams) error {
_, err := q.db.Exec(ctx, addHashToSong, arg.Hash, arg.Path)
return err
}
const addSong = `-- name: AddSong :exec
INSERT INTO song(game_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"`
}
func (q *Queries) AddSong(ctx context.Context, arg AddSongParams) error {
_, err := q.db.Exec(ctx, addSong,
arg.GameID,
arg.SongName,
arg.Path,
arg.FileName,
arg.Hash,
)
return err
}
const addSongPlayed = `-- name: AddSongPlayed :exec
UPDATE song SET times_played = times_played + 1
WHERE game_id = $1 AND song_name = $2
`
type AddSongPlayedParams struct {
GameID int32 `json:"game_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)
return err
}
const checkSong = `-- name: CheckSong :one
SELECT COUNT(*) FROM song WHERE path = $1
`
func (q *Queries) CheckSong(ctx context.Context, path string) (int64, error) {
row := q.db.QueryRow(ctx, checkSong, path)
var count int64
err := row.Scan(&count)
return count, err
}
const checkSongWithHash = `-- name: CheckSongWithHash :one
SELECT COUNT(*) FROM song WHERE hash = $1
`
func (q *Queries) CheckSongWithHash(ctx context.Context, hash string) (int64, error) {
row := q.db.QueryRow(ctx, checkSongWithHash, hash)
var count int64
err := row.Scan(&count)
return count, err
}
const clearSongs = `-- name: ClearSongs :exec
DELETE FROM song
`
func (q *Queries) ClearSongs(ctx context.Context) error {
_, err := q.db.Exec(ctx, clearSongs)
return err
}
const clearSongsByGameId = `-- name: ClearSongsByGameId :exec
DELETE FROM song WHERE game_id = $1
`
func (q *Queries) ClearSongsByGameId(ctx context.Context, gameID int32) error {
_, err := q.db.Exec(ctx, clearSongsByGameId, gameID)
return err
}
const fetchAllSongs = `-- name: FetchAllSongs :many
SELECT game_id, song_name, path, times_played, hash, file_name FROM song
`
func (q *Queries) FetchAllSongs(ctx context.Context) ([]Song, error) {
rows, err := q.db.Query(ctx, fetchAllSongs)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Song
for rows.Next() {
var i Song
if err := rows.Scan(
&i.GameID,
&i.SongName,
&i.Path,
&i.TimesPlayed,
&i.Hash,
&i.FileName,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const findSongsFromGame = `-- name: FindSongsFromGame :many
SELECT game_id, song_name, path, times_played, hash, file_name
FROM song
WHERE game_id = $1
`
func (q *Queries) FindSongsFromGame(ctx context.Context, gameID int32) ([]Song, error) {
rows, err := q.db.Query(ctx, findSongsFromGame, gameID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Song
for rows.Next() {
var i Song
if err := rows.Scan(
&i.GameID,
&i.SongName,
&i.Path,
&i.TimesPlayed,
&i.Hash,
&i.FileName,
); 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 game_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.SongName,
&i.Path,
&i.TimesPlayed,
&i.Hash,
&i.FileName,
)
return i, err
}
const removeBrokenSong = `-- name: RemoveBrokenSong :exec
DELETE FROM song WHERE path = $1
`
func (q *Queries) RemoveBrokenSong(ctx context.Context, path string) error {
_, err := q.db.Exec(ctx, removeBrokenSong, path)
return err
}
const removeBrokenSongs = `-- name: RemoveBrokenSongs :exec
DELETE FROM song where path = any ($1)
`
func (q *Queries) RemoveBrokenSongs(ctx context.Context, paths []string) error {
_, err := q.db.Exec(ctx, removeBrokenSongs, paths)
return err
}
const updateSong = `-- name: UpdateSong :exec
UPDATE song SET song_name=$1, file_name=$2, path=$3 where hash=$4
`
type UpdateSongParams struct {
SongName string `json:"song_name"`
FileName *string `json:"file_name"`
Path string `json:"path"`
Hash string `json:"hash"`
}
func (q *Queries) UpdateSong(ctx context.Context, arg UpdateSongParams) error {
_, err := q.db.Exec(ctx, updateSong,
arg.SongName,
arg.FileName,
arg.Path,
arg.Hash,
)
return err
}

View File

@@ -0,0 +1,68 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.27.0
// source: song_list.sql
package repository
import (
"context"
"time"
)
const getSongList = `-- name: GetSongList :many
SELECT match_date, match_id, song_no, game_name, song_name
FROM song_list
WHERE match_date = $1
ORDER BY song_no DESC
`
func (q *Queries) GetSongList(ctx context.Context, matchDate time.Time) ([]SongList, error) {
rows, err := q.db.Query(ctx, getSongList, matchDate)
if err != nil {
return nil, err
}
defer rows.Close()
var items []SongList
for rows.Next() {
var i SongList
if err := rows.Scan(
&i.MatchDate,
&i.MatchID,
&i.SongNo,
&i.GameName,
&i.SongName,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const insertSongInList = `-- name: InsertSongInList :exec
INSERT INTO song_list (match_date, match_id, song_no, game_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"`
}
func (q *Queries) InsertSongInList(ctx context.Context, arg InsertSongInListParams) error {
_, err := q.db.Exec(ctx, insertSongInList,
arg.MatchDate,
arg.MatchID,
arg.SongNo,
arg.GameName,
arg.SongName,
)
return err
}