203 lines
5.3 KiB
Go
203 lines
5.3 KiB
Go
package db
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/H1K0/Kiraku/internal/models"
|
|
"github.com/jackc/pgx/v5"
|
|
"github.com/jackc/pgx/v5/pgconn"
|
|
)
|
|
|
|
func CreditsGetByPerson(ctx context.Context, user_id, person_id, sort string) (credits []models.PersonCredit, statusCode int, err error) {
|
|
ok, _ := UserAuth(ctx, user_id)
|
|
if !ok {
|
|
err = fmt.Errorf("unauthorized")
|
|
statusCode = http.StatusUnauthorized
|
|
return
|
|
}
|
|
query := "SELECT t.id AS track_id, t.name AS track_name, t.duration AS track_duration, COALESCE(t.release_date::text, '') AS track_releaseDate, t.acquire_datetime AS track_acquireDatetime, r.id AS role_id, r.name AS role_name, COALESCE(c.alias, '') AS alias " +
|
|
"FROM credits c " +
|
|
"JOIN tracks t ON t.id=c.track_id " +
|
|
"JOIN roles r ON r.id=c.role_id " +
|
|
"WHERE c.person_id=$1"
|
|
if sort != "" {
|
|
sort_options := strings.Split(sort, ",")
|
|
query += " ORDER BY "
|
|
for i, sort_option := range sort_options {
|
|
sort_order := sort_option[:1]
|
|
sort_field := sort_option[1:]
|
|
switch sort_order {
|
|
case "+":
|
|
sort_order = "ASC"
|
|
case "-":
|
|
sort_order = "DESC"
|
|
default:
|
|
err = fmt.Errorf("invalid sorting order mark: %q", sort)
|
|
statusCode = http.StatusBadRequest
|
|
return
|
|
}
|
|
switch sort_field {
|
|
case "track.name":
|
|
fallthrough
|
|
case "track.releaseDate":
|
|
fallthrough
|
|
case "track.acquireDatetime":
|
|
fallthrough
|
|
case "track.duration":
|
|
fallthrough
|
|
case "role.name":
|
|
sort_field = strings.ReplaceAll(sort_field, ".", "_")
|
|
case "track.sortName":
|
|
sort_field = "COALESCE(t.sort_name, t.name)"
|
|
case "alias":
|
|
default:
|
|
err = fmt.Errorf("invalid sorting field: %q", sort_field)
|
|
statusCode = http.StatusBadRequest
|
|
return
|
|
}
|
|
if i > 0 {
|
|
query += ", "
|
|
}
|
|
query += fmt.Sprintf("%s %s NULLS LAST", sort_field, sort_order)
|
|
}
|
|
}
|
|
row := connPool.QueryRow(ctx, "SELECT 1 FROM persons WHERE id=$1", person_id)
|
|
err = row.Scan(nil)
|
|
if err != nil {
|
|
if err == pgx.ErrNoRows {
|
|
err = fmt.Errorf("not found")
|
|
statusCode = http.StatusNotFound
|
|
return
|
|
}
|
|
pgErr := err.(*pgconn.PgError)
|
|
if pgErr.Code == "22P02" {
|
|
err = fmt.Errorf("%s", pgErr.Message)
|
|
statusCode = http.StatusBadRequest
|
|
} else {
|
|
statusCode = http.StatusInternalServerError
|
|
}
|
|
return
|
|
}
|
|
rows, err := connPool.Query(ctx, query, person_id)
|
|
if err != nil {
|
|
statusCode = http.StatusInternalServerError
|
|
return
|
|
}
|
|
count := 0
|
|
for rows.Next() {
|
|
var credit models.PersonCredit
|
|
err = rows.Scan(
|
|
&credit.Track.ID, &credit.Track.Name, &credit.Track.Duration, &credit.Track.ReleaseDate, &credit.Track.AcquireDatetime,
|
|
&credit.Role.ID, &credit.Role.Name, &credit.Alias,
|
|
)
|
|
if err != nil {
|
|
statusCode = http.StatusInternalServerError
|
|
return
|
|
}
|
|
credits = append(credits, credit)
|
|
count++
|
|
}
|
|
err = rows.Err()
|
|
if err != nil {
|
|
statusCode = http.StatusInternalServerError
|
|
return
|
|
}
|
|
statusCode = http.StatusOK
|
|
return
|
|
}
|
|
|
|
func CreditsGetByTrack(ctx context.Context, user_id, track_id, sort string) (credits []models.TrackCredit, statusCode int, err error) {
|
|
ok, _ := UserAuth(ctx, user_id)
|
|
if !ok {
|
|
err = fmt.Errorf("unauthorized")
|
|
statusCode = http.StatusUnauthorized
|
|
return
|
|
}
|
|
query := "SELECT p.id AS person_id, p.name AS person_name, COALESCE(p.sort_name, '') AS person_sortName, r.id AS role_id, r.name AS role_name, COALESCE(c.alias, '') AS alias " +
|
|
"FROM credits c " +
|
|
"JOIN persons p ON p.id=c.person_id " +
|
|
"JOIN roles r ON r.id=c.role_id " +
|
|
"WHERE c.track_id=$1"
|
|
if sort != "" {
|
|
sort_options := strings.Split(sort, ",")
|
|
query += " ORDER BY "
|
|
for i, sort_option := range sort_options {
|
|
sort_order := sort_option[:1]
|
|
sort_field := sort_option[1:]
|
|
switch sort_order {
|
|
case "+":
|
|
sort_order = "ASC"
|
|
case "-":
|
|
sort_order = "DESC"
|
|
default:
|
|
err = fmt.Errorf("invalid sorting order mark: %q", sort)
|
|
statusCode = http.StatusBadRequest
|
|
return
|
|
}
|
|
switch sort_field {
|
|
case "person.name":
|
|
fallthrough
|
|
case "role.name":
|
|
sort_field = strings.ReplaceAll(sort_field, ".", "_")
|
|
case "person.sortName":
|
|
sort_field = "COALESCE(p.sort_name, p.name)"
|
|
case "alias":
|
|
default:
|
|
err = fmt.Errorf("invalid sorting field: %q", sort_field)
|
|
statusCode = http.StatusBadRequest
|
|
return
|
|
}
|
|
if i > 0 {
|
|
query += ", "
|
|
}
|
|
query += fmt.Sprintf("%s %s NULLS LAST", sort_field, sort_order)
|
|
}
|
|
}
|
|
row := connPool.QueryRow(ctx, "SELECT 1 FROM tracks WHERE id=$1", track_id)
|
|
err = row.Scan(nil)
|
|
if err != nil {
|
|
if err == pgx.ErrNoRows {
|
|
err = fmt.Errorf("not found")
|
|
statusCode = http.StatusNotFound
|
|
return
|
|
}
|
|
pgErr := err.(*pgconn.PgError)
|
|
if pgErr.Code == "22P02" {
|
|
err = fmt.Errorf("%s", pgErr.Message)
|
|
statusCode = http.StatusBadRequest
|
|
} else {
|
|
statusCode = http.StatusInternalServerError
|
|
}
|
|
return
|
|
}
|
|
rows, err := connPool.Query(ctx, query, track_id)
|
|
if err != nil {
|
|
statusCode = http.StatusInternalServerError
|
|
return
|
|
}
|
|
count := 0
|
|
for rows.Next() {
|
|
var credit models.TrackCredit
|
|
err = rows.Scan(
|
|
&credit.Person.ID, &credit.Person.Name, &credit.Person.SortName,
|
|
&credit.Role.ID, &credit.Role.Name, &credit.Alias,
|
|
)
|
|
if err != nil {
|
|
statusCode = http.StatusInternalServerError
|
|
return
|
|
}
|
|
credits = append(credits, credit)
|
|
count++
|
|
}
|
|
err = rows.Err()
|
|
if err != nil {
|
|
statusCode = http.StatusInternalServerError
|
|
return
|
|
}
|
|
statusCode = http.StatusOK
|
|
return
|
|
}
|