This commit is contained in:
Iron_Felix 2025-11-22 18:29:49 +03:00
parent b400f22844
commit cbbc2c179d
3 changed files with 74 additions and 66 deletions

View file

@ -103,33 +103,23 @@ func (s Server) GetUsersUserIdTitles(ctx context.Context, request oapi.GetUsersU
return oapi.GetUsersUserIdTitles400Response{}, err return oapi.GetUsersUserIdTitles400Response{}, err
} }
// Forward bool `json:"forward"` params := sqlc.SearchUserTitlesParams{
// SortBy string `json:"sort_by"` Forward: true,
// CursorYear *int32 `json:"cursor_year"` SortBy: "id",
// CursorID *int64 `json:"cursor_id"` // CursorYear :
// CursorRating *float64 `json:"cursor_rating"` // CursorID *int64 `json:"cursor_id"`
// Word *string `json:"word"` // CursorRating *float64 `json:"cursor_rating"`
// Ongoing string `json:"ongoing"` // Word *string `json:"word"`
// Planned string `json:"planned"` // Ongoing string `json:"ongoing"`
// Dropped string `json:"dropped"` // Planned string `json:"planned"`
// InProgress string `json:"in-progress"` // Dropped string `json:"dropped"`
// Finished string `json:"finished"` // InProgress string `json:"in-progress"`
// Rate *int32 `json:"rate"` // Finished string `json:"finished"`
// Rating *float64 `json:"rating"` // Rate *int32 `json:"rate"`
// ReleaseYear *int32 `json:"release_year"` // Rating *float64 `json:"rating"`
// ReleaseSeason *ReleaseSeasonT `json:"release_season"` // ReleaseYear *int32 `json:"release_year"`
// Limit *int32 `json:"limit"` // ReleaseSeason *ReleaseSeasonT `json:"release_season"`
params := sqlc.SearchTitlesParams{ // Limit *int32 `json:"limit"`
Word: word,
Ongoing: status.ongoing,
Finished: status.finished,
Planned: status.planned,
Rating: request.Params.Rating,
ReleaseYear: request.Params.ReleaseYear,
ReleaseSeason: season,
Forward: true,
SortBy: "id",
Limit: request.Params.Limit,
} }
if request.Params.SortForward != nil { if request.Params.SortForward != nil {
@ -141,32 +131,42 @@ func (s Server) GetUsersUserIdTitles(ctx context.Context, request oapi.GetUsersU
err := ParseCursorInto(string(*request.Params.Sort), string(*request.Params.Cursor), &params) err := ParseCursorInto(string(*request.Params.Sort), string(*request.Params.Cursor), &params)
if err != nil { if err != nil {
log.Errorf("%v", err) log.Errorf("%v", err)
return oapi.GetTitles400Response{}, nil return oapi.GetUsersUserIdTitles400Response{}, nil
} }
} }
} }
// param = nil means it will not be used
_sqlc_title := sqlc.SearchTitlesRow{ titles, err := s.db.SearchUserTitles(ctx, params)
ID: sqlc_title.ID, if err != nil {
StudioID: sqlc_title.StudioID, log.Errorf("%v", err)
PosterID: sqlc_title.PosterID, return oapi.GetUsersUserIdTitles500Response{}, nil
TitleStatus: sqlc_title.TitleStatus, }
Rating: sqlc_title.Rating, if len(titles) == 0 {
RatingCount: sqlc_title.RatingCount, return oapi.GetUsersUserIdTitles204Response{}, nil
ReleaseYear: sqlc_title.ReleaseYear, }
ReleaseSeason: sqlc_title.ReleaseSeason, for _, title := range titles {
Season: sqlc_title.Season, _sqlc_title := sqlc.SearchTitlesRow{
EpisodesAired: sqlc_title.EpisodesAired, ID: sqlc_title.ID,
EpisodesAll: sqlc_title.EpisodesAll, StudioID: sqlc_title.StudioID,
EpisodesLen: sqlc_title.EpisodesLen, PosterID: sqlc_title.PosterID,
TitleStorageType: sqlc_title.TitleStorageType, TitleStatus: sqlc_title.TitleStatus,
TitleImagePath: sqlc_title.TitleImagePath, Rating: sqlc_title.Rating,
TagNames: sqlc_title.TitleNames, RatingCount: sqlc_title.RatingCount,
StudioName: sqlc_title.StudioName, ReleaseYear: sqlc_title.ReleaseYear,
StudioIllustID: sqlc_title.StudioIllustID, ReleaseSeason: sqlc_title.ReleaseSeason,
StudioDesc: sqlc_title.StudioDesc, Season: sqlc_title.Season,
StudioStorageType: sqlc_title.StudioStorageType, EpisodesAired: sqlc_title.EpisodesAired,
StudioImagePath: sqlc_title.StudioImagePath, 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,
}
} }
return oapi.GetUsersUserIdTitles200JSONResponse(userTitles), nil return oapi.GetUsersUserIdTitles200JSONResponse(userTitles), nil

View file

@ -95,7 +95,7 @@ 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) LEFT JOIN images as si ON (s.illust_id = si.id)
WHERE id = sqlc.arg('title_id')::bigint WHERE t.id = sqlc.arg('title_id')::bigint
GROUP BY GROUP BY
t.id, i.id, s.id, si.id; t.id, i.id, s.id, si.id;
@ -187,7 +187,13 @@ WHERE
END END
) )
AND (t.title_status::text IN (sqlc.arg('ongoing')::text, sqlc.arg('finished')::text, sqlc.arg('planned')::text)) AND (
-- Если массив пуст (NULL или []) — не фильтруем
cardinality(sqlc.arg('title_statuses')::text[]) = 0
OR
-- Иначе: статус есть в списке
t.title_status = ANY(sqlc.arg('title_statuses')::text[])
)
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)

View file

@ -138,7 +138,7 @@ 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) LEFT JOIN images as si ON (s.illust_id = si.id)
WHERE id = $1::bigint WHERE t.id = $1::bigint
GROUP BY GROUP BY
t.id, i.id, s.id, si.id t.id, i.id, s.id, si.id
` `
@ -428,10 +428,16 @@ WHERE
END END
) )
AND (t.title_status::text IN ($7::text, $8::text, $9::text)) AND (
AND ($10::float IS NULL OR t.rating >= $10::float) -- Если массив пуст (NULL или []) не фильтруем
AND ($11::int IS NULL OR t.release_year = $11::int) cardinality($7::text[]) = 0
AND ($12::release_season_t IS NULL OR t.release_season = $12::release_season_t) OR
-- Иначе: статус есть в списке
t.title_status = ANY($7::text[])
)
AND ($8::float IS NULL OR t.rating >= $8::float)
AND ($9::int IS NULL OR t.release_year = $9::int)
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, si.id
@ -454,7 +460,7 @@ ORDER BY
CASE WHEN $2::text <> 'id' THEN t.id END ASC CASE WHEN $2::text <> 'id' THEN t.id END ASC
LIMIT COALESCE($13::int, 100) LIMIT COALESCE($11::int, 100)
` `
type SearchTitlesParams struct { type SearchTitlesParams struct {
@ -464,9 +470,7 @@ type SearchTitlesParams struct {
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"`
Finished string `json:"finished"`
Planned string `json:"planned"`
Rating *float64 `json:"rating"` Rating *float64 `json:"rating"`
ReleaseYear *int32 `json:"release_year"` ReleaseYear *int32 `json:"release_year"`
ReleaseSeason *ReleaseSeasonT `json:"release_season"` ReleaseSeason *ReleaseSeasonT `json:"release_season"`
@ -505,9 +509,7 @@ func (q *Queries) SearchTitles(ctx context.Context, arg SearchTitlesParams) ([]S
arg.CursorID, arg.CursorID,
arg.CursorRating, arg.CursorRating,
arg.Word, arg.Word,
arg.Ongoing, arg.TitleStatuses,
arg.Finished,
arg.Planned,
arg.Rating, arg.Rating,
arg.ReleaseYear, arg.ReleaseYear,
arg.ReleaseSeason, arg.ReleaseSeason,
@ -564,7 +566,7 @@ 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_strict(g.tag_name)'[]'::jsonb as tag_names, jsonb_agg(g.tag_name)'[]'::jsonb as tag_names,
s.studio_name as studio_name, s.studio_name as studio_name,
s.illust_id as studio_illust_id, s.illust_id as studio_illust_id,
s.studio_desc as studio_desc, s.studio_desc as studio_desc,
@ -718,7 +720,7 @@ type SearchUserTitlesRow struct {
UserCtime pgtype.Timestamptz `json:"user_ctime"` UserCtime pgtype.Timestamptz `json:"user_ctime"`
TitleStorageType string `json:"title_storage_type"` TitleStorageType string `json:"title_storage_type"`
TitleImagePath *string `json:"title_image_path"` TitleImagePath *string `json:"title_image_path"`
TagNames []byte `json:"tag_names"` TagNames json.RawMessage `json:"tag_names"`
StudioName *string `json:"studio_name"` StudioName *string `json:"studio_name"`
StudioIllustID *int64 `json:"studio_illust_id"` StudioIllustID *int64 `json:"studio_illust_id"`
StudioDesc *string `json:"studio_desc"` StudioDesc *string `json:"studio_desc"`