feat: GetUsertitles implemented
This commit is contained in:
parent
cbbc2c179d
commit
e792d5780b
8 changed files with 456 additions and 283 deletions
|
|
@ -146,11 +146,17 @@ paths:
|
||||||
summary: Get user titles
|
summary: Get user titles
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: '#/components/parameters/cursor'
|
- $ref: '#/components/parameters/cursor'
|
||||||
|
- $ref: '#/components/parameters/title_sort'
|
||||||
- in: path
|
- in: path
|
||||||
name: user_id
|
name: user_id
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
- in: query
|
||||||
|
name: sort_forward
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
- in: query
|
- in: query
|
||||||
name: word
|
name: word
|
||||||
schema:
|
schema:
|
||||||
|
|
@ -173,6 +179,11 @@ paths:
|
||||||
schema:
|
schema:
|
||||||
type: number
|
type: number
|
||||||
format: double
|
format: double
|
||||||
|
- in: query
|
||||||
|
name: my_rate
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
- in: query
|
- in: query
|
||||||
name: release_year
|
name: release_year
|
||||||
schema:
|
schema:
|
||||||
|
|
@ -199,9 +210,17 @@ paths:
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: array
|
type: object
|
||||||
items:
|
properties:
|
||||||
$ref: '#/components/schemas/UserTitle'
|
data:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/UserTitle'
|
||||||
|
cursor:
|
||||||
|
$ref: '#/components/schemas/CursorObj'
|
||||||
|
required:
|
||||||
|
- data
|
||||||
|
- cursor
|
||||||
'204':
|
'204':
|
||||||
description: No titles found
|
description: No titles found
|
||||||
'400':
|
'400':
|
||||||
|
|
|
||||||
|
|
@ -183,13 +183,16 @@ type GetUsersUserIdParams struct {
|
||||||
|
|
||||||
// GetUsersUserIdTitlesParams defines parameters for GetUsersUserIdTitles.
|
// GetUsersUserIdTitlesParams defines parameters for GetUsersUserIdTitles.
|
||||||
type GetUsersUserIdTitlesParams struct {
|
type GetUsersUserIdTitlesParams struct {
|
||||||
Cursor *Cursor `form:"cursor,omitempty" json:"cursor,omitempty"`
|
Cursor *Cursor `form:"cursor,omitempty" json:"cursor,omitempty"`
|
||||||
Word *string `form:"word,omitempty" json:"word,omitempty"`
|
Sort *TitleSort `form:"sort,omitempty" json:"sort,omitempty"`
|
||||||
|
SortForward *bool `form:"sort_forward,omitempty" json:"sort_forward,omitempty"`
|
||||||
|
Word *string `form:"word,omitempty" json:"word,omitempty"`
|
||||||
|
|
||||||
// Status List of title statuses to filter
|
// Status List of title statuses to filter
|
||||||
Status *[]TitleStatus `form:"status,omitempty" json:"status,omitempty"`
|
Status *[]TitleStatus `form:"status,omitempty" json:"status,omitempty"`
|
||||||
WatchStatus *UserTitleStatus `form:"watch_status,omitempty" json:"watch_status,omitempty"`
|
WatchStatus *UserTitleStatus `form:"watch_status,omitempty" json:"watch_status,omitempty"`
|
||||||
Rating *float64 `form:"rating,omitempty" json:"rating,omitempty"`
|
Rating *float64 `form:"rating,omitempty" json:"rating,omitempty"`
|
||||||
|
MyRate *int32 `form:"my_rate,omitempty" json:"my_rate,omitempty"`
|
||||||
ReleaseYear *int32 `form:"release_year,omitempty" json:"release_year,omitempty"`
|
ReleaseYear *int32 `form:"release_year,omitempty" json:"release_year,omitempty"`
|
||||||
ReleaseSeason *ReleaseSeason `form:"release_season,omitempty" json:"release_season,omitempty"`
|
ReleaseSeason *ReleaseSeason `form:"release_season,omitempty" json:"release_season,omitempty"`
|
||||||
Limit *int32 `form:"limit,omitempty" json:"limit,omitempty"`
|
Limit *int32 `form:"limit,omitempty" json:"limit,omitempty"`
|
||||||
|
|
@ -803,6 +806,22 @@ func (siw *ServerInterfaceWrapper) GetUsersUserIdTitles(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------- Optional query parameter "sort" -------------
|
||||||
|
|
||||||
|
err = runtime.BindQueryParameter("form", true, false, "sort", c.Request.URL.Query(), ¶ms.Sort)
|
||||||
|
if err != nil {
|
||||||
|
siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter sort: %w", err), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------- Optional query parameter "sort_forward" -------------
|
||||||
|
|
||||||
|
err = runtime.BindQueryParameter("form", true, false, "sort_forward", c.Request.URL.Query(), ¶ms.SortForward)
|
||||||
|
if err != nil {
|
||||||
|
siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter sort_forward: %w", err), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// ------------- Optional query parameter "word" -------------
|
// ------------- Optional query parameter "word" -------------
|
||||||
|
|
||||||
err = runtime.BindQueryParameter("form", true, false, "word", c.Request.URL.Query(), ¶ms.Word)
|
err = runtime.BindQueryParameter("form", true, false, "word", c.Request.URL.Query(), ¶ms.Word)
|
||||||
|
|
@ -835,6 +854,14 @@ func (siw *ServerInterfaceWrapper) GetUsersUserIdTitles(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------- Optional query parameter "my_rate" -------------
|
||||||
|
|
||||||
|
err = runtime.BindQueryParameter("form", true, false, "my_rate", c.Request.URL.Query(), ¶ms.MyRate)
|
||||||
|
if err != nil {
|
||||||
|
siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter my_rate: %w", err), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// ------------- Optional query parameter "release_year" -------------
|
// ------------- Optional query parameter "release_year" -------------
|
||||||
|
|
||||||
err = runtime.BindQueryParameter("form", true, false, "release_year", c.Request.URL.Query(), ¶ms.ReleaseYear)
|
err = runtime.BindQueryParameter("form", true, false, "release_year", c.Request.URL.Query(), ¶ms.ReleaseYear)
|
||||||
|
|
@ -1057,7 +1084,10 @@ type GetUsersUserIdTitlesResponseObject interface {
|
||||||
VisitGetUsersUserIdTitlesResponse(w http.ResponseWriter) error
|
VisitGetUsersUserIdTitlesResponse(w http.ResponseWriter) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetUsersUserIdTitles200JSONResponse []UserTitle
|
type GetUsersUserIdTitles200JSONResponse struct {
|
||||||
|
Cursor CursorObj `json:"cursor"`
|
||||||
|
Data []UserTitle `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
func (response GetUsersUserIdTitles200JSONResponse) VisitGetUsersUserIdTitlesResponse(w http.ResponseWriter) error {
|
func (response GetUsersUserIdTitles200JSONResponse) VisitGetUsersUserIdTitlesResponse(w http.ResponseWriter) error {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,17 @@ get:
|
||||||
summary: Get user titles
|
summary: Get user titles
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: '../parameters/cursor.yaml'
|
- $ref: '../parameters/cursor.yaml'
|
||||||
|
- $ref: "../parameters/title_sort.yaml"
|
||||||
- in: path
|
- in: path
|
||||||
name: user_id
|
name: user_id
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
- in: query
|
||||||
|
name: sort_forward
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
- in: query
|
- in: query
|
||||||
name: word
|
name: word
|
||||||
schema:
|
schema:
|
||||||
|
|
@ -29,6 +35,11 @@ get:
|
||||||
schema:
|
schema:
|
||||||
type: number
|
type: number
|
||||||
format: double
|
format: double
|
||||||
|
- in: query
|
||||||
|
name: my_rate
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
- in: query
|
- in: query
|
||||||
name: release_year
|
name: release_year
|
||||||
schema:
|
schema:
|
||||||
|
|
@ -55,9 +66,17 @@ get:
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: array
|
type: object
|
||||||
items:
|
properties:
|
||||||
$ref: '../schemas/UserTitle.yaml'
|
data:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '../schemas/UserTitle.yaml'
|
||||||
|
cursor:
|
||||||
|
$ref: '../schemas/CursorObj.yaml'
|
||||||
|
required:
|
||||||
|
- data
|
||||||
|
- cursor
|
||||||
'204':
|
'204':
|
||||||
description: No titles found
|
description: No titles found
|
||||||
'400':
|
'400':
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,24 @@ func NewServer(db *sqlc.Queries) Server {
|
||||||
return Server{db: db}
|
return Server{db: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Server) mapTitle(ctx context.Context, title sqlc.SearchTitlesRow) (oapi.Title, error) {
|
func (s Server) mapTitle(ctx context.Context, title sqlc.GetTitleByIDRow) (oapi.Title, error) {
|
||||||
|
|
||||||
|
oapi_title := oapi.Title{
|
||||||
|
EpisodesAired: title.EpisodesAired,
|
||||||
|
EpisodesAll: title.EpisodesAired,
|
||||||
|
// EpisodesLen: &episodes_lens,
|
||||||
|
Id: title.ID,
|
||||||
|
// Poster: &oapi_image,
|
||||||
|
Rating: title.Rating,
|
||||||
|
RatingCount: title.RatingCount,
|
||||||
|
// ReleaseSeason: &release_season,
|
||||||
|
ReleaseYear: title.ReleaseYear,
|
||||||
|
// Studio: &oapi_studio,
|
||||||
|
// Tags: oapi_tag_names,
|
||||||
|
// TitleNames: title_names,
|
||||||
|
// TitleStatus: oapi_status,
|
||||||
|
// AdditionalProperties:
|
||||||
|
}
|
||||||
|
|
||||||
title_names := make(map[string][]string, 0)
|
title_names := make(map[string][]string, 0)
|
||||||
err := json.Unmarshal(title.TitleNames, &title_names)
|
err := json.Unmarshal(title.TitleNames, &title_names)
|
||||||
|
|
@ -25,10 +42,13 @@ func (s Server) mapTitle(ctx context.Context, title sqlc.SearchTitlesRow) (oapi.
|
||||||
return oapi.Title{}, fmt.Errorf("unmarshal TitleNames: %v", err)
|
return oapi.Title{}, fmt.Errorf("unmarshal TitleNames: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
episodes_lens := make(map[string]float64, 0)
|
if title.EpisodesLen != nil && len(title.EpisodesLen) > 0 {
|
||||||
err = json.Unmarshal(title.EpisodesLen, &episodes_lens)
|
episodes_lens := make(map[string]float64, 0)
|
||||||
if err != nil {
|
err = json.Unmarshal(title.EpisodesLen, &episodes_lens)
|
||||||
return oapi.Title{}, fmt.Errorf("unmarshal EpisodesLen: %v", err)
|
if err != nil {
|
||||||
|
return oapi.Title{}, fmt.Errorf("unmarshal EpisodesLen: %v", err)
|
||||||
|
}
|
||||||
|
oapi_title.EpisodesLen = &episodes_lens
|
||||||
}
|
}
|
||||||
|
|
||||||
oapi_tag_names := make(oapi.Tags, 0)
|
oapi_tag_names := make(oapi.Tags, 0)
|
||||||
|
|
@ -38,17 +58,19 @@ func (s Server) mapTitle(ctx context.Context, title sqlc.SearchTitlesRow) (oapi.
|
||||||
}
|
}
|
||||||
|
|
||||||
var oapi_studio oapi.Studio
|
var oapi_studio oapi.Studio
|
||||||
|
|
||||||
oapi_studio.Id = title.StudioID
|
|
||||||
if title.StudioName != nil {
|
if title.StudioName != nil {
|
||||||
oapi_studio.Name = *title.StudioName
|
oapi_studio.Name = *title.StudioName
|
||||||
}
|
}
|
||||||
oapi_studio.Description = title.StudioDesc
|
if title.StudioID != 0 {
|
||||||
if title.StudioIllustID != nil {
|
oapi_studio.Id = title.StudioID
|
||||||
oapi_studio.Poster.Id = title.StudioIllustID
|
oapi_studio.Description = title.StudioDesc
|
||||||
oapi_studio.Poster.ImagePath = title.StudioImagePath
|
if title.StudioIllustID != nil {
|
||||||
oapi_studio.Poster.StorageType = &title.StudioStorageType
|
oapi_studio.Poster.Id = title.StudioIllustID
|
||||||
|
oapi_studio.Poster.ImagePath = title.StudioImagePath
|
||||||
|
oapi_studio.Poster.StorageType = &title.StudioStorageType
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
oapi_title.Studio = &oapi_studio
|
||||||
|
|
||||||
var oapi_image oapi.Image
|
var oapi_image oapi.Image
|
||||||
|
|
||||||
|
|
@ -62,27 +84,13 @@ func (s Server) mapTitle(ctx context.Context, title sqlc.SearchTitlesRow) (oapi.
|
||||||
if title.ReleaseSeason != nil {
|
if title.ReleaseSeason != nil {
|
||||||
release_season = oapi.ReleaseSeason(*title.ReleaseSeason)
|
release_season = oapi.ReleaseSeason(*title.ReleaseSeason)
|
||||||
}
|
}
|
||||||
|
oapi_title.ReleaseSeason = &release_season
|
||||||
|
|
||||||
oapi_status, err := TitleStatus2oapi(&title.TitleStatus)
|
oapi_status, err := TitleStatus2oapi(&title.TitleStatus)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return oapi.Title{}, fmt.Errorf("TitleStatus2oapi: %v", err)
|
return oapi.Title{}, fmt.Errorf("TitleStatus2oapi: %v", err)
|
||||||
}
|
}
|
||||||
oapi_title := oapi.Title{
|
oapi_title.TitleStatus = oapi_status
|
||||||
EpisodesAired: title.EpisodesAired,
|
|
||||||
EpisodesAll: title.EpisodesAired,
|
|
||||||
EpisodesLen: &episodes_lens,
|
|
||||||
Id: title.ID,
|
|
||||||
Poster: &oapi_image,
|
|
||||||
Rating: title.Rating,
|
|
||||||
RatingCount: title.RatingCount,
|
|
||||||
ReleaseSeason: &release_season,
|
|
||||||
ReleaseYear: title.ReleaseYear,
|
|
||||||
Studio: &oapi_studio,
|
|
||||||
Tags: oapi_tag_names,
|
|
||||||
TitleNames: title_names,
|
|
||||||
TitleStatus: oapi_status,
|
|
||||||
// AdditionalProperties:
|
|
||||||
}
|
|
||||||
|
|
||||||
return oapi_title, nil
|
return oapi_title, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,25 +26,25 @@ type SqlcStatus struct {
|
||||||
planned string
|
planned string
|
||||||
}
|
}
|
||||||
|
|
||||||
func TitleStatus2Sqlc(s *[]oapi.TitleStatus) (*SqlcStatus, error) {
|
// func TitleStatus2Sqlc(s *[]oapi.TitleStatus) (*SqlcStatus, error) {
|
||||||
var sqlc_status SqlcStatus
|
// var sqlc_status SqlcStatus
|
||||||
if s == nil {
|
// if s == nil {
|
||||||
return &sqlc_status, nil
|
// return &sqlc_status, nil
|
||||||
}
|
// }
|
||||||
for _, t := range *s {
|
// for _, t := range *s {
|
||||||
switch t {
|
// switch t {
|
||||||
case oapi.TitleStatusFinished:
|
// case oapi.TitleStatusFinished:
|
||||||
sqlc_status.finished = "finished"
|
// sqlc_status.finished = "finished"
|
||||||
case oapi.TitleStatusOngoing:
|
// case oapi.TitleStatusOngoing:
|
||||||
sqlc_status.ongoing = "ongoing"
|
// sqlc_status.ongoing = "ongoing"
|
||||||
case oapi.TitleStatusPlanned:
|
// case oapi.TitleStatusPlanned:
|
||||||
sqlc_status.planned = "planned"
|
// sqlc_status.planned = "planned"
|
||||||
default:
|
// default:
|
||||||
return nil, fmt.Errorf("unexpected tittle status: %s", t)
|
// return nil, fmt.Errorf("unexpected tittle status: %s", t)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return &sqlc_status, nil
|
// return &sqlc_status, nil
|
||||||
}
|
// }
|
||||||
|
|
||||||
func TitleStatus2oapi(s *sqlc.TitleStatusT) (*oapi.TitleStatus, error) {
|
func TitleStatus2oapi(s *sqlc.TitleStatusT) (*oapi.TitleStatus, error) {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
|
|
@ -169,29 +169,8 @@ func (s Server) GetTitlesTitleId(ctx context.Context, request oapi.GetTitlesTitl
|
||||||
log.Errorf("%v", err)
|
log.Errorf("%v", err)
|
||||||
return oapi.GetTitlesTitleId500Response{}, nil
|
return oapi.GetTitlesTitleId500Response{}, nil
|
||||||
}
|
}
|
||||||
_sqlc_title := sqlc.SearchTitlesRow{
|
|
||||||
ID: sqlc_title.ID,
|
oapi_title, err = s.mapTitle(ctx, sqlc_title)
|
||||||
StudioID: sqlc_title.StudioID,
|
|
||||||
PosterID: sqlc_title.PosterID,
|
|
||||||
TitleStatus: sqlc_title.TitleStatus,
|
|
||||||
Rating: sqlc_title.Rating,
|
|
||||||
RatingCount: sqlc_title.RatingCount,
|
|
||||||
ReleaseYear: sqlc_title.ReleaseYear,
|
|
||||||
ReleaseSeason: sqlc_title.ReleaseSeason,
|
|
||||||
Season: sqlc_title.Season,
|
|
||||||
EpisodesAired: sqlc_title.EpisodesAired,
|
|
||||||
EpisodesAll: sqlc_title.EpisodesAll,
|
|
||||||
EpisodesLen: sqlc_title.EpisodesLen,
|
|
||||||
TitleStorageType: sqlc_title.TitleStorageType,
|
|
||||||
TitleImagePath: sqlc_title.TitleImagePath,
|
|
||||||
TagNames: sqlc_title.TitleNames,
|
|
||||||
StudioName: sqlc_title.StudioName,
|
|
||||||
StudioIllustID: sqlc_title.StudioIllustID,
|
|
||||||
StudioDesc: sqlc_title.StudioDesc,
|
|
||||||
StudioStorageType: sqlc_title.StudioStorageType,
|
|
||||||
StudioImagePath: sqlc_title.StudioImagePath,
|
|
||||||
}
|
|
||||||
oapi_title, err = s.mapTitle(ctx, _sqlc_title)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%v", err)
|
log.Errorf("%v", err)
|
||||||
return oapi.GetTitlesTitleId500Response{}, nil
|
return oapi.GetTitlesTitleId500Response{}, nil
|
||||||
|
|
@ -204,11 +183,6 @@ func (s Server) GetTitles(ctx context.Context, request oapi.GetTitlesRequestObje
|
||||||
opai_titles := make([]oapi.Title, 0)
|
opai_titles := make([]oapi.Title, 0)
|
||||||
|
|
||||||
word := Word2Sqlc(request.Params.Word)
|
word := Word2Sqlc(request.Params.Word)
|
||||||
status, err := TitleStatus2Sqlc(request.Params.Status)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("%v", err)
|
|
||||||
return oapi.GetTitles400Response{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
season, err := ReleaseSeason2sqlc(request.Params.ReleaseSeason)
|
season, err := ReleaseSeason2sqlc(request.Params.ReleaseSeason)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -216,16 +190,22 @@ func (s Server) GetTitles(ctx context.Context, request oapi.GetTitlesRequestObje
|
||||||
return oapi.GetTitles400Response{}, err
|
return oapi.GetTitles400Response{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var statuses_sort []string
|
||||||
|
if request.Params.Status != nil {
|
||||||
|
for _, s := range *request.Params.Status {
|
||||||
|
ss := string(s) // s type is alias for string
|
||||||
|
statuses_sort = append(statuses_sort, ss)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
params := sqlc.SearchTitlesParams{
|
params := sqlc.SearchTitlesParams{
|
||||||
Word: word,
|
Word: word,
|
||||||
Ongoing: status.ongoing,
|
TitleStatuses: statuses_sort,
|
||||||
Finished: status.finished,
|
|
||||||
Planned: status.planned,
|
|
||||||
Rating: request.Params.Rating,
|
Rating: request.Params.Rating,
|
||||||
ReleaseYear: request.Params.ReleaseYear,
|
ReleaseYear: request.Params.ReleaseYear,
|
||||||
ReleaseSeason: season,
|
ReleaseSeason: season,
|
||||||
Forward: true,
|
Forward: true, // default
|
||||||
SortBy: "id",
|
SortBy: "id", // default
|
||||||
Limit: request.Params.Limit,
|
Limit: request.Params.Limit,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -235,6 +215,7 @@ func (s Server) GetTitles(ctx context.Context, request oapi.GetTitlesRequestObje
|
||||||
if request.Params.Sort != nil {
|
if request.Params.Sort != nil {
|
||||||
params.SortBy = string(*request.Params.Sort)
|
params.SortBy = string(*request.Params.Sort)
|
||||||
if request.Params.Cursor != nil {
|
if request.Params.Cursor != nil {
|
||||||
|
// here we set CursorYear CursorID CursorRating fields
|
||||||
err := ParseCursorInto(string(*request.Params.Sort), string(*request.Params.Cursor), ¶ms)
|
err := ParseCursorInto(string(*request.Params.Sort), string(*request.Params.Cursor), ¶ms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%v", err)
|
log.Errorf("%v", err)
|
||||||
|
|
@ -256,7 +237,30 @@ func (s Server) GetTitles(ctx context.Context, request oapi.GetTitlesRequestObje
|
||||||
|
|
||||||
for _, title := range titles {
|
for _, title := range titles {
|
||||||
|
|
||||||
t, err := s.mapTitle(ctx, title)
|
_title := sqlc.GetTitleByIDRow{
|
||||||
|
ID: title.ID,
|
||||||
|
// StudioID: title.StudioID,
|
||||||
|
PosterID: title.PosterID,
|
||||||
|
TitleStatus: title.TitleStatus,
|
||||||
|
Rating: title.Rating,
|
||||||
|
RatingCount: title.RatingCount,
|
||||||
|
ReleaseYear: title.ReleaseYear,
|
||||||
|
ReleaseSeason: title.ReleaseSeason,
|
||||||
|
Season: title.Season,
|
||||||
|
EpisodesAired: title.EpisodesAired,
|
||||||
|
EpisodesAll: title.EpisodesAll,
|
||||||
|
// EpisodesLen: title.EpisodesLen,
|
||||||
|
TitleStorageType: title.TitleStorageType,
|
||||||
|
TitleImagePath: title.TitleImagePath,
|
||||||
|
TagNames: title.TitleNames,
|
||||||
|
StudioName: title.StudioName,
|
||||||
|
// StudioIllustID: title.StudioIllustID,
|
||||||
|
// StudioDesc: title.StudioDesc,
|
||||||
|
// StudioStorageType: title.StudioStorageType,
|
||||||
|
// StudioImagePath: title.StudioImagePath,
|
||||||
|
}
|
||||||
|
|
||||||
|
t, err := s.mapTitle(ctx, _title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%v", err)
|
log.Errorf("%v", err)
|
||||||
return oapi.GetTitles500Response{}, nil
|
return oapi.GetTitles500Response{}, nil
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
oapi "nyanimedb/api"
|
oapi "nyanimedb/api"
|
||||||
sqlc "nyanimedb/sql"
|
sqlc "nyanimedb/sql"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
|
|
@ -53,8 +54,12 @@ func (s Server) GetUsersUserId(ctx context.Context, req oapi.GetUsersUserIdReque
|
||||||
return oapi.GetUsersUserId200JSONResponse(mapUser(user)), nil
|
return oapi.GetUsersUserId200JSONResponse(mapUser(user)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func sqlDate2oapi(p_date pgtype.Timestamptz) (time.Time, error) {
|
func sqlDate2oapi(p_date pgtype.Timestamptz) *time.Time {
|
||||||
return time.Time{}, nil
|
if p_date.Valid {
|
||||||
|
t := p_date.Time
|
||||||
|
return &t
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type SqlcUserStatus struct {
|
type SqlcUserStatus struct {
|
||||||
|
|
@ -64,26 +69,94 @@ type SqlcUserStatus struct {
|
||||||
in_progress string
|
in_progress string
|
||||||
}
|
}
|
||||||
|
|
||||||
func UserTitleStatus2Sqlc(s *[]oapi.UserTitleStatus) (*SqlcUserStatus, error) {
|
// func UserTitleStatus2Sqlc(s *[]oapi.UserTitleStatus) (*SqlcUserStatus, error) {
|
||||||
var sqlc_status SqlcUserStatus
|
// var sqlc_status SqlcUserStatus
|
||||||
if s == nil {
|
// if s == nil {
|
||||||
return &sqlc_status, nil
|
// return &sqlc_status, nil
|
||||||
|
// }
|
||||||
|
// for _, t := range *s {
|
||||||
|
// switch t {
|
||||||
|
// case oapi.UserTitleStatusFinished:
|
||||||
|
// sqlc_status.finished = "finished"
|
||||||
|
// case oapi.UserTitleStatusDropped:
|
||||||
|
// sqlc_status.dropped = "dropped"
|
||||||
|
// case oapi.UserTitleStatusPlanned:
|
||||||
|
// sqlc_status.planned = "planned"
|
||||||
|
// case oapi.UserTitleStatusInProgress:
|
||||||
|
// sqlc_status.in_progress = "in-progress"
|
||||||
|
// default:
|
||||||
|
// return nil, fmt.Errorf("unexpected tittle status: %s", t)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return &sqlc_status, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
func sql2usertitlestatus(s sqlc.UsertitleStatusT) (oapi.UserTitleStatus, error) {
|
||||||
|
var status oapi.UserTitleStatus
|
||||||
|
|
||||||
|
switch status {
|
||||||
|
case "finished":
|
||||||
|
status = oapi.UserTitleStatusFinished
|
||||||
|
case "dropped":
|
||||||
|
status = oapi.UserTitleStatusDropped
|
||||||
|
case "planned":
|
||||||
|
status = oapi.UserTitleStatusPlanned
|
||||||
|
case "in-progress":
|
||||||
|
status = oapi.UserTitleStatusInProgress
|
||||||
|
default:
|
||||||
|
return status, fmt.Errorf("unexpected tittle status: %s", s)
|
||||||
}
|
}
|
||||||
for _, t := range *s {
|
|
||||||
switch t {
|
return status, nil
|
||||||
case oapi.UserTitleStatusFinished:
|
}
|
||||||
sqlc_status.finished = "finished"
|
|
||||||
case oapi.UserTitleStatusDropped:
|
func (s Server) mapUsertitle(ctx context.Context, t sqlc.SearchUserTitlesRow) (oapi.UserTitle, error) {
|
||||||
sqlc_status.dropped = "dropped"
|
|
||||||
case oapi.UserTitleStatusPlanned:
|
oapi_usertitle := oapi.UserTitle{
|
||||||
sqlc_status.planned = "planned"
|
Ctime: sqlDate2oapi(t.UserCtime),
|
||||||
case oapi.UserTitleStatusInProgress:
|
Rate: t.UserRate,
|
||||||
sqlc_status.in_progress = "in-progress"
|
ReviewId: t.ReviewID,
|
||||||
default:
|
// Status: ,
|
||||||
return nil, fmt.Errorf("unexpected tittle status: %s", t)
|
// Title: ,
|
||||||
}
|
UserId: t.UserID,
|
||||||
}
|
}
|
||||||
return &sqlc_status, nil
|
|
||||||
|
status, err := sql2usertitlestatus(t.UsertitleStatus)
|
||||||
|
if err != nil {
|
||||||
|
return oapi_usertitle, fmt.Errorf("mapUsertitle: %v", err)
|
||||||
|
}
|
||||||
|
oapi_usertitle.Status = status
|
||||||
|
|
||||||
|
_title := sqlc.GetTitleByIDRow{
|
||||||
|
ID: t.ID,
|
||||||
|
// StudioID: title.StudioID,
|
||||||
|
PosterID: t.PosterID,
|
||||||
|
TitleStatus: t.TitleStatus,
|
||||||
|
Rating: t.Rating,
|
||||||
|
RatingCount: t.RatingCount,
|
||||||
|
ReleaseYear: t.ReleaseYear,
|
||||||
|
ReleaseSeason: t.ReleaseSeason,
|
||||||
|
Season: t.Season,
|
||||||
|
EpisodesAired: t.EpisodesAired,
|
||||||
|
EpisodesAll: t.EpisodesAll,
|
||||||
|
// EpisodesLen: title.EpisodesLen,
|
||||||
|
TitleStorageType: t.TitleStorageType,
|
||||||
|
TitleImagePath: t.TitleImagePath,
|
||||||
|
TagNames: t.TitleNames,
|
||||||
|
StudioName: t.StudioName,
|
||||||
|
// StudioIllustID: title.StudioIllustID,
|
||||||
|
// StudioDesc: title.StudioDesc,
|
||||||
|
// StudioStorageType: title.StudioStorageType,
|
||||||
|
// StudioImagePath: title.StudioImagePath,
|
||||||
|
}
|
||||||
|
|
||||||
|
oapi_title, err := s.mapTitle(ctx, _title)
|
||||||
|
if err != nil {
|
||||||
|
return oapi_usertitle, fmt.Errorf("mapUsertitle: %v", err)
|
||||||
|
}
|
||||||
|
oapi_usertitle.Title = &oapi_title
|
||||||
|
|
||||||
|
return oapi_usertitle, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Server) GetUsersUserIdTitles(ctx context.Context, request oapi.GetUsersUserIdTitlesRequestObject) (oapi.GetUsersUserIdTitlesResponseObject, error) {
|
func (s Server) GetUsersUserIdTitles(ctx context.Context, request oapi.GetUsersUserIdTitlesRequestObject) (oapi.GetUsersUserIdTitlesResponseObject, error) {
|
||||||
|
|
@ -91,11 +164,6 @@ func (s Server) GetUsersUserIdTitles(ctx context.Context, request oapi.GetUsersU
|
||||||
oapi_usertitles := make([]oapi.UserTitle, 0)
|
oapi_usertitles := make([]oapi.UserTitle, 0)
|
||||||
|
|
||||||
word := Word2Sqlc(request.Params.Word)
|
word := Word2Sqlc(request.Params.Word)
|
||||||
status, err := TitleStatus2Sqlc(request.Params.Status)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("%v", err)
|
|
||||||
return oapi.GetUsersUserIdTitles400Response{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
season, err := ReleaseSeason2sqlc(request.Params.ReleaseSeason)
|
season, err := ReleaseSeason2sqlc(request.Params.ReleaseSeason)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -103,23 +171,33 @@ func (s Server) GetUsersUserIdTitles(ctx context.Context, request oapi.GetUsersU
|
||||||
return oapi.GetUsersUserIdTitles400Response{}, err
|
return oapi.GetUsersUserIdTitles400Response{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var statuses_sort []string
|
||||||
|
if request.Params.Status != nil {
|
||||||
|
for _, s := range *request.Params.Status {
|
||||||
|
ss := string(s) // s type is alias for string
|
||||||
|
statuses_sort = append(statuses_sort, ss)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var watch_status []string
|
||||||
|
if request.Params.WatchStatus != nil {
|
||||||
|
for _, s := range *request.Params.WatchStatus {
|
||||||
|
ss := string(s) // s type is alias for string
|
||||||
|
watch_status = append(statuses_sort, ss)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
params := sqlc.SearchUserTitlesParams{
|
params := sqlc.SearchUserTitlesParams{
|
||||||
Forward: true,
|
Word: word,
|
||||||
SortBy: "id",
|
TitleStatuses: statuses_sort,
|
||||||
// CursorYear :
|
UsertitleStatuses: watch_status,
|
||||||
// CursorID *int64 `json:"cursor_id"`
|
Rating: request.Params.Rating,
|
||||||
// CursorRating *float64 `json:"cursor_rating"`
|
Rate: request.Params.MyRate,
|
||||||
// Word *string `json:"word"`
|
ReleaseYear: request.Params.ReleaseYear,
|
||||||
// Ongoing string `json:"ongoing"`
|
ReleaseSeason: season,
|
||||||
// Planned string `json:"planned"`
|
Forward: true, // default
|
||||||
// Dropped string `json:"dropped"`
|
SortBy: "id", // default
|
||||||
// InProgress string `json:"in-progress"`
|
Limit: request.Params.Limit,
|
||||||
// Finished string `json:"finished"`
|
|
||||||
// Rate *int32 `json:"rate"`
|
|
||||||
// Rating *float64 `json:"rating"`
|
|
||||||
// ReleaseYear *int32 `json:"release_year"`
|
|
||||||
// ReleaseSeason *ReleaseSeasonT `json:"release_season"`
|
|
||||||
// Limit *int32 `json:"limit"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if request.Params.SortForward != nil {
|
if request.Params.SortForward != nil {
|
||||||
|
|
@ -128,6 +206,7 @@ func (s Server) GetUsersUserIdTitles(ctx context.Context, request oapi.GetUsersU
|
||||||
if request.Params.Sort != nil {
|
if request.Params.Sort != nil {
|
||||||
params.SortBy = string(*request.Params.Sort)
|
params.SortBy = string(*request.Params.Sort)
|
||||||
if request.Params.Cursor != nil {
|
if request.Params.Cursor != nil {
|
||||||
|
// here we set CursorYear CursorID CursorRating fields
|
||||||
err := ParseCursorInto(string(*request.Params.Sort), string(*request.Params.Cursor), ¶ms)
|
err := ParseCursorInto(string(*request.Params.Sort), string(*request.Params.Cursor), ¶ms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%v", err)
|
log.Errorf("%v", err)
|
||||||
|
|
@ -144,30 +223,30 @@ func (s Server) GetUsersUserIdTitles(ctx context.Context, request oapi.GetUsersU
|
||||||
if len(titles) == 0 {
|
if len(titles) == 0 {
|
||||||
return oapi.GetUsersUserIdTitles204Response{}, nil
|
return oapi.GetUsersUserIdTitles204Response{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var new_cursor oapi.CursorObj
|
||||||
|
|
||||||
for _, title := range titles {
|
for _, title := range titles {
|
||||||
_sqlc_title := sqlc.SearchTitlesRow{
|
|
||||||
ID: sqlc_title.ID,
|
t, err := s.mapUsertitle(ctx, title)
|
||||||
StudioID: sqlc_title.StudioID,
|
if err != nil {
|
||||||
PosterID: sqlc_title.PosterID,
|
log.Errorf("%v", err)
|
||||||
TitleStatus: sqlc_title.TitleStatus,
|
return oapi.GetUsersUserIdTitles500Response{}, nil
|
||||||
Rating: sqlc_title.Rating,
|
}
|
||||||
RatingCount: sqlc_title.RatingCount,
|
oapi_usertitles = append(oapi_usertitles, t)
|
||||||
ReleaseYear: sqlc_title.ReleaseYear,
|
|
||||||
ReleaseSeason: sqlc_title.ReleaseSeason,
|
new_cursor.Id = t.Title.Id
|
||||||
Season: sqlc_title.Season,
|
if request.Params.Sort != nil {
|
||||||
EpisodesAired: sqlc_title.EpisodesAired,
|
switch string(*request.Params.Sort) {
|
||||||
EpisodesAll: sqlc_title.EpisodesAll,
|
case "year":
|
||||||
EpisodesLen: sqlc_title.EpisodesLen,
|
tmp := fmt.Sprint(*t.Title.ReleaseYear)
|
||||||
TitleStorageType: sqlc_title.TitleStorageType,
|
new_cursor.Param = &tmp
|
||||||
TitleImagePath: sqlc_title.TitleImagePath,
|
case "rating":
|
||||||
TagNames: sqlc_title.TitleNames,
|
tmp := strconv.FormatFloat(*t.Title.Rating, 'f', -1, 64)
|
||||||
StudioName: sqlc_title.StudioName,
|
new_cursor.Param = &tmp
|
||||||
StudioIllustID: sqlc_title.StudioIllustID,
|
}
|
||||||
StudioDesc: sqlc_title.StudioDesc,
|
|
||||||
StudioStorageType: sqlc_title.StudioStorageType,
|
|
||||||
StudioImagePath: sqlc_title.StudioImagePath,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return oapi.GetUsersUserIdTitles200JSONResponse(userTitles), nil
|
return oapi.GetUsersUserIdTitles200JSONResponse{Cursor: new_cursor, Data: oapi_usertitles}, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -101,25 +101,30 @@ GROUP BY
|
||||||
|
|
||||||
-- name: SearchTitles :many
|
-- name: SearchTitles :many
|
||||||
SELECT
|
SELECT
|
||||||
t.*,
|
t.id as id,
|
||||||
|
t.title_names as title_names,
|
||||||
|
t.poster_id as poster_id,
|
||||||
|
t.title_status as title_status,
|
||||||
|
t.rating as rating,
|
||||||
|
t.rating_count as rating_count,
|
||||||
|
t.release_year as release_year,
|
||||||
|
t.release_season as release_season,
|
||||||
|
t.season as season,
|
||||||
|
t.episodes_aired as episodes_aired,
|
||||||
|
t.episodes_all as episodes_all,
|
||||||
i.storage_type::text as title_storage_type,
|
i.storage_type::text as title_storage_type,
|
||||||
i.image_path as title_image_path,
|
i.image_path as title_image_path,
|
||||||
COALESCE(
|
COALESCE(
|
||||||
jsonb_agg(g.tag_names) FILTER (WHERE g.tag_names IS NOT NULL),
|
jsonb_agg(g.tag_names) FILTER (WHERE g.tag_names IS NOT NULL),
|
||||||
'[]'::jsonb
|
'[]'::jsonb
|
||||||
)::jsonb as tag_names,
|
)::jsonb as tag_names,
|
||||||
s.studio_name as studio_name,
|
s.studio_name as studio_name
|
||||||
s.illust_id as studio_illust_id,
|
|
||||||
s.studio_desc as studio_desc,
|
|
||||||
si.storage_type::text as studio_storage_type,
|
|
||||||
si.image_path as studio_image_path
|
|
||||||
|
|
||||||
FROM titles as t
|
FROM titles as t
|
||||||
LEFT JOIN images as i ON (t.poster_id = i.id)
|
LEFT JOIN images as i ON (t.poster_id = i.id)
|
||||||
LEFT JOIN title_tags as tt ON (t.id = tt.title_id)
|
LEFT JOIN title_tags as tt ON (t.id = tt.title_id)
|
||||||
LEFT JOIN tags as g ON (tt.tag_id = g.id)
|
LEFT JOIN tags as g ON (tt.tag_id = g.id)
|
||||||
LEFT JOIN studios as s ON (t.studio_id = s.id)
|
LEFT JOIN studios as s ON (t.studio_id = s.id)
|
||||||
LEFT JOIN images as si ON (s.illust_id = si.id)
|
|
||||||
|
|
||||||
WHERE
|
WHERE
|
||||||
CASE
|
CASE
|
||||||
|
|
@ -199,7 +204,7 @@ WHERE
|
||||||
AND (sqlc.narg('release_season')::release_season_t IS NULL OR t.release_season = sqlc.narg('release_season')::release_season_t)
|
AND (sqlc.narg('release_season')::release_season_t IS NULL OR t.release_season = sqlc.narg('release_season')::release_season_t)
|
||||||
|
|
||||||
GROUP BY
|
GROUP BY
|
||||||
t.id, i.id, s.id, si.id
|
t.id, i.id, s.id
|
||||||
|
|
||||||
ORDER BY
|
ORDER BY
|
||||||
CASE WHEN sqlc.arg('forward')::boolean THEN
|
CASE WHEN sqlc.arg('forward')::boolean THEN
|
||||||
|
|
@ -223,7 +228,17 @@ LIMIT COALESCE(sqlc.narg('limit')::int, 100); -- 100 is default limit
|
||||||
|
|
||||||
-- name: SearchUserTitles :many
|
-- name: SearchUserTitles :many
|
||||||
SELECT
|
SELECT
|
||||||
t.*,
|
t.id as id,
|
||||||
|
t.title_names as title_names,
|
||||||
|
t.poster_id as poster_id,
|
||||||
|
t.title_status as title_status,
|
||||||
|
t.rating as rating,
|
||||||
|
t.rating_count as rating_count,
|
||||||
|
t.release_year as release_year,
|
||||||
|
t.release_season as release_season,
|
||||||
|
t.season as season,
|
||||||
|
t.episodes_aired as episodes_aired,
|
||||||
|
t.episodes_all as episodes_all,
|
||||||
u.user_id as user_id,
|
u.user_id as user_id,
|
||||||
u.status as usertitle_status,
|
u.status as usertitle_status,
|
||||||
u.rate as user_rate,
|
u.rate as user_rate,
|
||||||
|
|
@ -231,20 +246,18 @@ SELECT
|
||||||
u.ctime as user_ctime,
|
u.ctime as user_ctime,
|
||||||
i.storage_type::text as title_storage_type,
|
i.storage_type::text as title_storage_type,
|
||||||
i.image_path as title_image_path,
|
i.image_path as title_image_path,
|
||||||
jsonb_agg(g.tag_name)'[]'::jsonb as tag_names,
|
COALESCE(
|
||||||
s.studio_name as studio_name,
|
jsonb_agg(g.tag_names) FILTER (WHERE g.tag_names IS NOT NULL),
|
||||||
s.illust_id as studio_illust_id,
|
'[]'::jsonb
|
||||||
s.studio_desc as studio_desc,
|
)::jsonb as tag_names,
|
||||||
si.storage_type::text as studio_storage_type,
|
s.studio_name as studio_name
|
||||||
si.image_path as studio_image_path
|
|
||||||
|
|
||||||
FROM usertitles as u
|
FROM usertitles as u
|
||||||
LEFT JOIN titles as t ON (u.title_id = t.id)
|
JOIN titles as t ON (u.title_id = t.id)
|
||||||
LEFT JOIN images as i ON (t.poster_id = i.id)
|
LEFT JOIN images as i ON (t.poster_id = i.id)
|
||||||
LEFT JOIN title_tags as tt ON (t.id = tt.title_id)
|
LEFT JOIN title_tags as tt ON (t.id = tt.title_id)
|
||||||
LEFT JOIN tags as g ON (tt.tag_id = g.id)
|
LEFT JOIN tags as g ON (tt.tag_id = g.id)
|
||||||
LEFT JOIN studios as s ON (t.studio_id = s.id)
|
LEFT JOIN studios as s ON (t.studio_id = s.id)
|
||||||
LEFT JOIN images as si ON (s.illust_id = si.id)
|
|
||||||
|
|
||||||
WHERE
|
WHERE
|
||||||
CASE
|
CASE
|
||||||
|
|
@ -312,15 +325,24 @@ WHERE
|
||||||
END
|
END
|
||||||
)
|
)
|
||||||
|
|
||||||
AND (u.status::text IN (sqlc.arg('ongoing')::text, sqlc.arg('planned')::text, sqlc.arg('dropped')::text, sqlc.arg('in-progress')::text))
|
AND (
|
||||||
AND (t.title_status::text IN (sqlc.arg('ongoing')::text, sqlc.arg('finished')::text, sqlc.arg('planned')::text))
|
-- Если массив пуст (NULL или []) — не фильтруем
|
||||||
|
cardinality(sqlc.arg('title_statuses')::text[]) = 0
|
||||||
|
OR
|
||||||
|
t.title_status = ANY(sqlc.arg('title_statuses')::text[])
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
cardinality(sqlc.arg('usertitle_statuses')::text[]) = 0
|
||||||
|
OR
|
||||||
|
u.status = ANY(sqlc.arg('usertitle_statuses')::text[])
|
||||||
|
)
|
||||||
AND (sqlc.narg('rate')::int IS NULL OR u.rate >= sqlc.narg('rate')::int)
|
AND (sqlc.narg('rate')::int IS NULL OR u.rate >= sqlc.narg('rate')::int)
|
||||||
AND (sqlc.narg('rating')::float IS NULL OR t.rating >= sqlc.narg('rating')::float)
|
AND (sqlc.narg('rating')::float IS NULL OR t.rating >= sqlc.narg('rating')::float)
|
||||||
AND (sqlc.narg('release_year')::int IS NULL OR t.release_year = sqlc.narg('release_year')::int)
|
AND (sqlc.narg('release_year')::int IS NULL OR t.release_year = sqlc.narg('release_year')::int)
|
||||||
AND (sqlc.narg('release_season')::release_season_t IS NULL OR t.release_season = sqlc.narg('release_season')::release_season_t)
|
AND (sqlc.narg('release_season')::release_season_t IS NULL OR t.release_season = sqlc.narg('release_season')::release_season_t)
|
||||||
|
|
||||||
GROUP BY
|
GROUP BY
|
||||||
t.id, i.id, s.id, si.id
|
t.id, i.id, s.id
|
||||||
|
|
||||||
ORDER BY
|
ORDER BY
|
||||||
CASE WHEN sqlc.arg('forward')::boolean THEN
|
CASE WHEN sqlc.arg('forward')::boolean THEN
|
||||||
|
|
|
||||||
|
|
@ -342,25 +342,30 @@ func (q *Queries) InsertTitleTags(ctx context.Context, arg InsertTitleTagsParams
|
||||||
|
|
||||||
const searchTitles = `-- name: SearchTitles :many
|
const searchTitles = `-- name: SearchTitles :many
|
||||||
SELECT
|
SELECT
|
||||||
t.id, t.title_names, t.studio_id, t.poster_id, t.title_status, t.rating, t.rating_count, t.release_year, t.release_season, t.season, t.episodes_aired, t.episodes_all, t.episodes_len,
|
t.id as id,
|
||||||
|
t.title_names as title_names,
|
||||||
|
t.poster_id as poster_id,
|
||||||
|
t.title_status as title_status,
|
||||||
|
t.rating as rating,
|
||||||
|
t.rating_count as rating_count,
|
||||||
|
t.release_year as release_year,
|
||||||
|
t.release_season as release_season,
|
||||||
|
t.season as season,
|
||||||
|
t.episodes_aired as episodes_aired,
|
||||||
|
t.episodes_all as episodes_all,
|
||||||
i.storage_type::text as title_storage_type,
|
i.storage_type::text as title_storage_type,
|
||||||
i.image_path as title_image_path,
|
i.image_path as title_image_path,
|
||||||
COALESCE(
|
COALESCE(
|
||||||
jsonb_agg(g.tag_names) FILTER (WHERE g.tag_names IS NOT NULL),
|
jsonb_agg(g.tag_names) FILTER (WHERE g.tag_names IS NOT NULL),
|
||||||
'[]'::jsonb
|
'[]'::jsonb
|
||||||
)::jsonb as tag_names,
|
)::jsonb as tag_names,
|
||||||
s.studio_name as studio_name,
|
s.studio_name as studio_name
|
||||||
s.illust_id as studio_illust_id,
|
|
||||||
s.studio_desc as studio_desc,
|
|
||||||
si.storage_type::text as studio_storage_type,
|
|
||||||
si.image_path as studio_image_path
|
|
||||||
|
|
||||||
FROM titles as t
|
FROM titles as t
|
||||||
LEFT JOIN images as i ON (t.poster_id = i.id)
|
LEFT JOIN images as i ON (t.poster_id = i.id)
|
||||||
LEFT JOIN title_tags as tt ON (t.id = tt.title_id)
|
LEFT JOIN title_tags as tt ON (t.id = tt.title_id)
|
||||||
LEFT JOIN tags as g ON (tt.tag_id = g.id)
|
LEFT JOIN tags as g ON (tt.tag_id = g.id)
|
||||||
LEFT JOIN studios as s ON (t.studio_id = s.id)
|
LEFT JOIN studios as s ON (t.studio_id = s.id)
|
||||||
LEFT JOIN images as si ON (s.illust_id = si.id)
|
|
||||||
|
|
||||||
WHERE
|
WHERE
|
||||||
CASE
|
CASE
|
||||||
|
|
@ -440,7 +445,7 @@ WHERE
|
||||||
AND ($10::release_season_t IS NULL OR t.release_season = $10::release_season_t)
|
AND ($10::release_season_t IS NULL OR t.release_season = $10::release_season_t)
|
||||||
|
|
||||||
GROUP BY
|
GROUP BY
|
||||||
t.id, i.id, s.id, si.id
|
t.id, i.id, s.id
|
||||||
|
|
||||||
ORDER BY
|
ORDER BY
|
||||||
CASE WHEN $1::boolean THEN
|
CASE WHEN $1::boolean THEN
|
||||||
|
|
@ -478,27 +483,21 @@ type SearchTitlesParams struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type SearchTitlesRow struct {
|
type SearchTitlesRow struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
TitleNames json.RawMessage `json:"title_names"`
|
TitleNames json.RawMessage `json:"title_names"`
|
||||||
StudioID int64 `json:"studio_id"`
|
PosterID *int64 `json:"poster_id"`
|
||||||
PosterID *int64 `json:"poster_id"`
|
TitleStatus TitleStatusT `json:"title_status"`
|
||||||
TitleStatus TitleStatusT `json:"title_status"`
|
Rating *float64 `json:"rating"`
|
||||||
Rating *float64 `json:"rating"`
|
RatingCount *int32 `json:"rating_count"`
|
||||||
RatingCount *int32 `json:"rating_count"`
|
ReleaseYear *int32 `json:"release_year"`
|
||||||
ReleaseYear *int32 `json:"release_year"`
|
ReleaseSeason *ReleaseSeasonT `json:"release_season"`
|
||||||
ReleaseSeason *ReleaseSeasonT `json:"release_season"`
|
Season *int32 `json:"season"`
|
||||||
Season *int32 `json:"season"`
|
EpisodesAired *int32 `json:"episodes_aired"`
|
||||||
EpisodesAired *int32 `json:"episodes_aired"`
|
EpisodesAll *int32 `json:"episodes_all"`
|
||||||
EpisodesAll *int32 `json:"episodes_all"`
|
TitleStorageType string `json:"title_storage_type"`
|
||||||
EpisodesLen []byte `json:"episodes_len"`
|
TitleImagePath *string `json:"title_image_path"`
|
||||||
TitleStorageType string `json:"title_storage_type"`
|
TagNames json.RawMessage `json:"tag_names"`
|
||||||
TitleImagePath *string `json:"title_image_path"`
|
StudioName *string `json:"studio_name"`
|
||||||
TagNames json.RawMessage `json:"tag_names"`
|
|
||||||
StudioName *string `json:"studio_name"`
|
|
||||||
StudioIllustID *int64 `json:"studio_illust_id"`
|
|
||||||
StudioDesc *string `json:"studio_desc"`
|
|
||||||
StudioStorageType string `json:"studio_storage_type"`
|
|
||||||
StudioImagePath *string `json:"studio_image_path"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) SearchTitles(ctx context.Context, arg SearchTitlesParams) ([]SearchTitlesRow, error) {
|
func (q *Queries) SearchTitles(ctx context.Context, arg SearchTitlesParams) ([]SearchTitlesRow, error) {
|
||||||
|
|
@ -525,7 +524,6 @@ func (q *Queries) SearchTitles(ctx context.Context, arg SearchTitlesParams) ([]S
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.TitleNames,
|
&i.TitleNames,
|
||||||
&i.StudioID,
|
|
||||||
&i.PosterID,
|
&i.PosterID,
|
||||||
&i.TitleStatus,
|
&i.TitleStatus,
|
||||||
&i.Rating,
|
&i.Rating,
|
||||||
|
|
@ -535,15 +533,10 @@ func (q *Queries) SearchTitles(ctx context.Context, arg SearchTitlesParams) ([]S
|
||||||
&i.Season,
|
&i.Season,
|
||||||
&i.EpisodesAired,
|
&i.EpisodesAired,
|
||||||
&i.EpisodesAll,
|
&i.EpisodesAll,
|
||||||
&i.EpisodesLen,
|
|
||||||
&i.TitleStorageType,
|
&i.TitleStorageType,
|
||||||
&i.TitleImagePath,
|
&i.TitleImagePath,
|
||||||
&i.TagNames,
|
&i.TagNames,
|
||||||
&i.StudioName,
|
&i.StudioName,
|
||||||
&i.StudioIllustID,
|
|
||||||
&i.StudioDesc,
|
|
||||||
&i.StudioStorageType,
|
|
||||||
&i.StudioImagePath,
|
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -558,7 +551,17 @@ func (q *Queries) SearchTitles(ctx context.Context, arg SearchTitlesParams) ([]S
|
||||||
const searchUserTitles = `-- name: SearchUserTitles :many
|
const searchUserTitles = `-- name: SearchUserTitles :many
|
||||||
|
|
||||||
SELECT
|
SELECT
|
||||||
t.id, t.title_names, t.studio_id, t.poster_id, t.title_status, t.rating, t.rating_count, t.release_year, t.release_season, t.season, t.episodes_aired, t.episodes_all, t.episodes_len,
|
t.id as id,
|
||||||
|
t.title_names as title_names,
|
||||||
|
t.poster_id as poster_id,
|
||||||
|
t.title_status as title_status,
|
||||||
|
t.rating as rating,
|
||||||
|
t.rating_count as rating_count,
|
||||||
|
t.release_year as release_year,
|
||||||
|
t.release_season as release_season,
|
||||||
|
t.season as season,
|
||||||
|
t.episodes_aired as episodes_aired,
|
||||||
|
t.episodes_all as episodes_all,
|
||||||
u.user_id as user_id,
|
u.user_id as user_id,
|
||||||
u.status as usertitle_status,
|
u.status as usertitle_status,
|
||||||
u.rate as user_rate,
|
u.rate as user_rate,
|
||||||
|
|
@ -566,20 +569,18 @@ SELECT
|
||||||
u.ctime as user_ctime,
|
u.ctime as user_ctime,
|
||||||
i.storage_type::text as title_storage_type,
|
i.storage_type::text as title_storage_type,
|
||||||
i.image_path as title_image_path,
|
i.image_path as title_image_path,
|
||||||
jsonb_agg(g.tag_name)'[]'::jsonb as tag_names,
|
COALESCE(
|
||||||
s.studio_name as studio_name,
|
jsonb_agg(g.tag_names) FILTER (WHERE g.tag_names IS NOT NULL),
|
||||||
s.illust_id as studio_illust_id,
|
'[]'::jsonb
|
||||||
s.studio_desc as studio_desc,
|
)::jsonb as tag_names,
|
||||||
si.storage_type::text as studio_storage_type,
|
s.studio_name as studio_name
|
||||||
si.image_path as studio_image_path
|
|
||||||
|
|
||||||
FROM usertitles as u
|
FROM usertitles as u
|
||||||
LEFT JOIN titles as t ON (u.title_id = t.id)
|
JOIN titles as t ON (u.title_id = t.id)
|
||||||
LEFT JOIN images as i ON (t.poster_id = i.id)
|
LEFT JOIN images as i ON (t.poster_id = i.id)
|
||||||
LEFT JOIN title_tags as tt ON (t.id = tt.title_id)
|
LEFT JOIN title_tags as tt ON (t.id = tt.title_id)
|
||||||
LEFT JOIN tags as g ON (tt.tag_id = g.id)
|
LEFT JOIN tags as g ON (tt.tag_id = g.id)
|
||||||
LEFT JOIN studios as s ON (t.studio_id = s.id)
|
LEFT JOIN studios as s ON (t.studio_id = s.id)
|
||||||
LEFT JOIN images as si ON (s.illust_id = si.id)
|
|
||||||
|
|
||||||
WHERE
|
WHERE
|
||||||
CASE
|
CASE
|
||||||
|
|
@ -647,15 +648,24 @@ WHERE
|
||||||
END
|
END
|
||||||
)
|
)
|
||||||
|
|
||||||
AND (u.status::text IN ($7::text, $8::text, $9::text, $10::text))
|
AND (
|
||||||
AND (t.title_status::text IN ($7::text, $11::text, $8::text))
|
-- Если массив пуст (NULL или []) — не фильтруем
|
||||||
AND ($12::int IS NULL OR u.rate >= $12::int)
|
cardinality($7::text[]) = 0
|
||||||
AND ($13::float IS NULL OR t.rating >= $13::float)
|
OR
|
||||||
AND ($14::int IS NULL OR t.release_year = $14::int)
|
t.title_status = ANY($7::text[])
|
||||||
AND ($15::release_season_t IS NULL OR t.release_season = $15::release_season_t)
|
)
|
||||||
|
AND (
|
||||||
|
cardinality($8::text[]) = 0
|
||||||
|
OR
|
||||||
|
u.status = ANY($8::text[])
|
||||||
|
)
|
||||||
|
AND ($9::int IS NULL OR u.rate >= $9::int)
|
||||||
|
AND ($10::float IS NULL OR t.rating >= $10::float)
|
||||||
|
AND ($11::int IS NULL OR t.release_year = $11::int)
|
||||||
|
AND ($12::release_season_t IS NULL OR t.release_season = $12::release_season_t)
|
||||||
|
|
||||||
GROUP BY
|
GROUP BY
|
||||||
t.id, i.id, s.id, si.id
|
t.id, i.id, s.id
|
||||||
|
|
||||||
ORDER BY
|
ORDER BY
|
||||||
CASE WHEN $1::boolean THEN
|
CASE WHEN $1::boolean THEN
|
||||||
|
|
@ -677,55 +687,46 @@ ORDER BY
|
||||||
|
|
||||||
CASE WHEN $2::text <> 'id' THEN t.id END ASC
|
CASE WHEN $2::text <> 'id' THEN t.id END ASC
|
||||||
|
|
||||||
LIMIT COALESCE($16::int, 100)
|
LIMIT COALESCE($13::int, 100)
|
||||||
`
|
`
|
||||||
|
|
||||||
type SearchUserTitlesParams struct {
|
type SearchUserTitlesParams struct {
|
||||||
Forward bool `json:"forward"`
|
Forward bool `json:"forward"`
|
||||||
SortBy string `json:"sort_by"`
|
SortBy string `json:"sort_by"`
|
||||||
CursorYear *int32 `json:"cursor_year"`
|
CursorYear *int32 `json:"cursor_year"`
|
||||||
CursorID *int64 `json:"cursor_id"`
|
CursorID *int64 `json:"cursor_id"`
|
||||||
CursorRating *float64 `json:"cursor_rating"`
|
CursorRating *float64 `json:"cursor_rating"`
|
||||||
Word *string `json:"word"`
|
Word *string `json:"word"`
|
||||||
Ongoing string `json:"ongoing"`
|
TitleStatuses []string `json:"title_statuses"`
|
||||||
Planned string `json:"planned"`
|
UsertitleStatuses []string `json:"usertitle_statuses"`
|
||||||
Dropped string `json:"dropped"`
|
Rate *int32 `json:"rate"`
|
||||||
InProgress string `json:"in-progress"`
|
Rating *float64 `json:"rating"`
|
||||||
Finished string `json:"finished"`
|
ReleaseYear *int32 `json:"release_year"`
|
||||||
Rate *int32 `json:"rate"`
|
ReleaseSeason *ReleaseSeasonT `json:"release_season"`
|
||||||
Rating *float64 `json:"rating"`
|
Limit *int32 `json:"limit"`
|
||||||
ReleaseYear *int32 `json:"release_year"`
|
|
||||||
ReleaseSeason *ReleaseSeasonT `json:"release_season"`
|
|
||||||
Limit *int32 `json:"limit"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type SearchUserTitlesRow struct {
|
type SearchUserTitlesRow struct {
|
||||||
ID *int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
TitleNames []byte `json:"title_names"`
|
TitleNames json.RawMessage `json:"title_names"`
|
||||||
StudioID *int64 `json:"studio_id"`
|
PosterID *int64 `json:"poster_id"`
|
||||||
PosterID *int64 `json:"poster_id"`
|
TitleStatus TitleStatusT `json:"title_status"`
|
||||||
TitleStatus *TitleStatusT `json:"title_status"`
|
Rating *float64 `json:"rating"`
|
||||||
Rating *float64 `json:"rating"`
|
RatingCount *int32 `json:"rating_count"`
|
||||||
RatingCount *int32 `json:"rating_count"`
|
ReleaseYear *int32 `json:"release_year"`
|
||||||
ReleaseYear *int32 `json:"release_year"`
|
ReleaseSeason *ReleaseSeasonT `json:"release_season"`
|
||||||
ReleaseSeason *ReleaseSeasonT `json:"release_season"`
|
Season *int32 `json:"season"`
|
||||||
Season *int32 `json:"season"`
|
EpisodesAired *int32 `json:"episodes_aired"`
|
||||||
EpisodesAired *int32 `json:"episodes_aired"`
|
EpisodesAll *int32 `json:"episodes_all"`
|
||||||
EpisodesAll *int32 `json:"episodes_all"`
|
UserID int64 `json:"user_id"`
|
||||||
EpisodesLen []byte `json:"episodes_len"`
|
UsertitleStatus UsertitleStatusT `json:"usertitle_status"`
|
||||||
UserID int64 `json:"user_id"`
|
UserRate *int32 `json:"user_rate"`
|
||||||
UsertitleStatus UsertitleStatusT `json:"usertitle_status"`
|
ReviewID *int64 `json:"review_id"`
|
||||||
UserRate *int32 `json:"user_rate"`
|
UserCtime pgtype.Timestamptz `json:"user_ctime"`
|
||||||
ReviewID *int64 `json:"review_id"`
|
TitleStorageType string `json:"title_storage_type"`
|
||||||
UserCtime pgtype.Timestamptz `json:"user_ctime"`
|
TitleImagePath *string `json:"title_image_path"`
|
||||||
TitleStorageType string `json:"title_storage_type"`
|
TagNames json.RawMessage `json:"tag_names"`
|
||||||
TitleImagePath *string `json:"title_image_path"`
|
StudioName *string `json:"studio_name"`
|
||||||
TagNames json.RawMessage `json:"tag_names"`
|
|
||||||
StudioName *string `json:"studio_name"`
|
|
||||||
StudioIllustID *int64 `json:"studio_illust_id"`
|
|
||||||
StudioDesc *string `json:"studio_desc"`
|
|
||||||
StudioStorageType string `json:"studio_storage_type"`
|
|
||||||
StudioImagePath *string `json:"studio_image_path"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 100 is default limit
|
// 100 is default limit
|
||||||
|
|
@ -737,11 +738,8 @@ func (q *Queries) SearchUserTitles(ctx context.Context, arg SearchUserTitlesPara
|
||||||
arg.CursorID,
|
arg.CursorID,
|
||||||
arg.CursorRating,
|
arg.CursorRating,
|
||||||
arg.Word,
|
arg.Word,
|
||||||
arg.Ongoing,
|
arg.TitleStatuses,
|
||||||
arg.Planned,
|
arg.UsertitleStatuses,
|
||||||
arg.Dropped,
|
|
||||||
arg.InProgress,
|
|
||||||
arg.Finished,
|
|
||||||
arg.Rate,
|
arg.Rate,
|
||||||
arg.Rating,
|
arg.Rating,
|
||||||
arg.ReleaseYear,
|
arg.ReleaseYear,
|
||||||
|
|
@ -758,7 +756,6 @@ func (q *Queries) SearchUserTitles(ctx context.Context, arg SearchUserTitlesPara
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.TitleNames,
|
&i.TitleNames,
|
||||||
&i.StudioID,
|
|
||||||
&i.PosterID,
|
&i.PosterID,
|
||||||
&i.TitleStatus,
|
&i.TitleStatus,
|
||||||
&i.Rating,
|
&i.Rating,
|
||||||
|
|
@ -768,7 +765,6 @@ func (q *Queries) SearchUserTitles(ctx context.Context, arg SearchUserTitlesPara
|
||||||
&i.Season,
|
&i.Season,
|
||||||
&i.EpisodesAired,
|
&i.EpisodesAired,
|
||||||
&i.EpisodesAll,
|
&i.EpisodesAll,
|
||||||
&i.EpisodesLen,
|
|
||||||
&i.UserID,
|
&i.UserID,
|
||||||
&i.UsertitleStatus,
|
&i.UsertitleStatus,
|
||||||
&i.UserRate,
|
&i.UserRate,
|
||||||
|
|
@ -778,10 +774,6 @@ func (q *Queries) SearchUserTitles(ctx context.Context, arg SearchUserTitlesPara
|
||||||
&i.TitleImagePath,
|
&i.TitleImagePath,
|
||||||
&i.TagNames,
|
&i.TagNames,
|
||||||
&i.StudioName,
|
&i.StudioName,
|
||||||
&i.StudioIllustID,
|
|
||||||
&i.StudioDesc,
|
|
||||||
&i.StudioStorageType,
|
|
||||||
&i.StudioImagePath,
|
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue