diff --git a/api/_build/openapi.yaml b/api/_build/openapi.yaml index c059166..5ff77e0 100644 --- a/api/_build/openapi.yaml +++ b/api/_build/openapi.yaml @@ -23,12 +23,7 @@ paths: - in: query name: status schema: - type: array - items: - $ref: '#/components/schemas/TitleStatus' - description: List of title statuses to filter - style: form - explode: false + $ref: '#/components/schemas/TitleStatus' - in: query name: rating schema: diff --git a/api/api.gen.go b/api/api.gen.go index e56f6b8..f252a5a 100644 --- a/api/api.gen.go +++ b/api/api.gen.go @@ -156,13 +156,11 @@ type Cursor = string // GetTitlesParams defines parameters for GetTitles. type GetTitlesParams struct { - Cursor *Cursor `form:"cursor,omitempty" json:"cursor,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 *[]TitleStatus `form:"status,omitempty" json:"status,omitempty"` + Cursor *Cursor `form:"cursor,omitempty" json:"cursor,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 *TitleStatus `form:"status,omitempty" json:"status,omitempty"` Rating *float64 `form:"rating,omitempty" json:"rating,omitempty"` ReleaseYear *int32 `form:"release_year,omitempty" json:"release_year,omitempty"` ReleaseSeason *ReleaseSeason `form:"release_season,omitempty" json:"release_season,omitempty"` @@ -640,7 +638,7 @@ func (siw *ServerInterfaceWrapper) GetTitles(c *gin.Context) { // ------------- Optional query parameter "status" ------------- - err = runtime.BindQueryParameter("form", false, false, "status", c.Request.URL.Query(), ¶ms.Status) + err = runtime.BindQueryParameter("form", true, false, "status", c.Request.URL.Query(), ¶ms.Status) if err != nil { siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter status: %w", err), http.StatusBadRequest) return diff --git a/api/paths/titles.yaml b/api/paths/titles.yaml index af2d17b..e868ed6 100644 --- a/api/paths/titles.yaml +++ b/api/paths/titles.yaml @@ -15,13 +15,7 @@ get: - in: query name: status schema: - type: array - items: - $ref: '../schemas/enums/TitleStatus.yaml' - description: List of title statuses to filter - style: form - explode: false - + $ref: '../schemas/enums/TitleStatus.yaml' - in: query name: rating schema: diff --git a/api/schemas/Image.yaml b/api/schemas/Image.yaml index 4ae3cb7..7226b29 100644 --- a/api/schemas/Image.yaml +++ b/api/schemas/Image.yaml @@ -1,7 +1,6 @@ type: object properties: -# id выпиливаем - id: + id: type: integer format: int64 storage_type: diff --git a/api/schemas/Studio.yaml b/api/schemas/Studio.yaml index 26a2adf..35b40a8 100644 --- a/api/schemas/Studio.yaml +++ b/api/schemas/Studio.yaml @@ -3,7 +3,6 @@ required: - id - name properties: -# id не нужен id: type: integer format: int64 diff --git a/modules/backend/handlers/titles.go b/modules/backend/handlers/titles.go index 71547c2..aea6037 100644 --- a/modules/backend/handlers/titles.go +++ b/modules/backend/handlers/titles.go @@ -20,44 +20,18 @@ func Word2Sqlc(s *string) *string { return s } -type SqlcStatus struct { - ongoing string - finished string - planned string -} - -func TitleStatus2Sqlc(s []oapi.TitleStatus) (*SqlcStatus, error) { +func TitleStatus2Sqlc(s *oapi.TitleStatus) (*sqlc.TitleStatusT, error) { if s == nil { return nil, nil } - var sqlc_status SqlcStatus - for _, t := range s { - switch t { - case oapi.TitleStatusFinished: - sqlc_status.finished = "finished" - case oapi.TitleStatusOngoing: - sqlc_status.ongoing = "ongoing" - case oapi.TitleStatusPlanned: - sqlc_status.planned = "planned" - default: - return nil, fmt.Errorf("unexpected tittle status: %s", t) - } - } - return &sqlc_status, nil -} - -func TitleStatus2oapi(s *sqlc.TitleStatusT) (*oapi.TitleStatus, error) { - if s == nil { - return nil, nil - } - var t oapi.TitleStatus + var t sqlc.TitleStatusT switch *s { - case sqlc.TitleStatusTFinished: - t = oapi.TitleStatusFinished - case sqlc.TitleStatusTOngoing: - t = oapi.TitleStatusOngoing - case sqlc.TitleStatusTPlanned: - t = oapi.TitleStatusPlanned + case oapi.TitleStatusFinished: + t = sqlc.TitleStatusTFinished + case oapi.TitleStatusOngoing: + t = sqlc.TitleStatusTOngoing + case oapi.TitleStatusPlanned: + t = sqlc.TitleStatusTPlanned default: return nil, fmt.Errorf("unexpected tittle status: %s", *s) } @@ -158,75 +132,67 @@ func (s Server) GetStudio(ctx context.Context, id int64) (*oapi.Studio, error) { return &oapi_studio, nil } -func (s Server) mapTitle(ctx context.Context, title sqlc.SearchTitlesRow) (oapi.Title, error) { +func (s Server) mapTitle(ctx context.Context, title sqlc.Title) (oapi.Title, error) { - // var oapi_title oapi.Title + var oapi_title oapi.Title - title_names := make(map[string][]string, 0) + title_names := make(map[string][]string, 1) err := json.Unmarshal(title.TitleNames, &title_names) if err != nil { - 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) + episodes_lens := make(map[string]float64, 1) err = json.Unmarshal(title.EpisodesLen, &episodes_lens) if err != nil { - return oapi.Title{}, fmt.Errorf("unmarshal EpisodesLen: %v", err) + return oapi_title, fmt.Errorf("unmarshal EpisodesLen: %v", err) } - oapi_tag_names := make(oapi.Tags, 0) - err = json.Unmarshal(title.TagNames, &oapi_tag_names) + oapi_tag_names, err := s.GetTagsByTitleId(ctx, title.ID) if err != nil { - return oapi.Title{}, fmt.Errorf("unmarshalling title_tag: %v", err) + return oapi_title, fmt.Errorf("GetTagsByTitleId: %v", err) } - - var oapi_studio oapi.Studio - - oapi_studio.Id = title.StudioID - if title.StudioName != nil { - oapi_studio.Name = *title.StudioName + if oapi_tag_names != nil { + oapi_title.Tags = oapi_tag_names } - oapi_studio.Description = title.StudioDesc - if title.StudioIllustID != nil { - oapi_studio.Poster.Id = title.StudioIllustID - oapi_studio.Poster.ImagePath = title.StudioImagePath - oapi_studio.Poster.StorageType = &title.StudioStorageType - } - - var oapi_image oapi.Image if title.PosterID != nil { - oapi_image.Id = title.PosterID - oapi_image.ImagePath = title.TitleImagePath - oapi_image.StorageType = &title.TitleStorageType + oapi_image, err := s.GetImage(ctx, *title.PosterID) + if err != nil { + return oapi_title, fmt.Errorf("GetImage: %v", err) + } + if oapi_image != nil { + oapi_title.Poster = oapi_image + } } - var release_season oapi.ReleaseSeason - if title.ReleaseSeason != nil { - release_season = oapi.ReleaseSeason(*title.ReleaseSeason) - } - - oapi_status, err := TitleStatus2oapi(&title.TitleStatus) + oapi_studio, err := s.GetStudio(ctx, title.StudioID) if err != nil { - return oapi.Title{}, fmt.Errorf("TitleStatus2oapi: %v", err) + return oapi_title, fmt.Errorf("GetStudio: %v", err) } - 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: + if oapi_studio != nil { + oapi_title.Studio = oapi_studio } + if title.ReleaseSeason != nil { + rs := oapi.ReleaseSeason(*title.ReleaseSeason) + oapi_title.ReleaseSeason = &rs + } else { + oapi_title.ReleaseSeason = nil + } + + ts := oapi.TitleStatus(title.TitleStatus) + oapi_title.TitleStatus = &ts + + oapi_title.Id = title.ID + oapi_title.Rating = title.Rating + oapi_title.RatingCount = title.RatingCount + oapi_title.ReleaseYear = title.ReleaseYear + oapi_title.TitleNames = title_names + oapi_title.EpisodesAired = title.EpisodesAired + oapi_title.EpisodesAll = title.EpisodesAll + oapi_title.EpisodesLen = &episodes_lens + return oapi_title, nil } @@ -241,29 +207,8 @@ func (s Server) GetTitlesTitleId(ctx context.Context, request oapi.GetTitlesTitl log.Errorf("%v", err) return oapi.GetTitlesTitleId500Response{}, nil } - _sqlc_title := sqlc.SearchTitlesRow{ - ID: sqlc_title.ID, - 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) + + oapi_title, err = s.mapTitle(ctx, sqlc_title) if err != nil { log.Errorf("%v", err) return oapi.GetTitlesTitleId500Response{}, nil @@ -275,8 +220,19 @@ func (s Server) GetTitlesTitleId(ctx context.Context, request oapi.GetTitlesTitl func (s Server) GetTitles(ctx context.Context, request oapi.GetTitlesRequestObject) (oapi.GetTitlesResponseObject, error) { opai_titles := make([]oapi.Title, 0) + // old_cursor := oapi.CursorObj{ + // Id: 1, + // } + + // if request.Params.Cursor != nil { + // if old_cursor, err := parseCursor(*request.Params.Cursor); err != nil { + // log.Errorf("%v", err) + // return oapi.GetTitles400Response{}, err + // } + // } + word := Word2Sqlc(request.Params.Word) - status, err := TitleStatus2Sqlc(*request.Params.Status) + status, err := TitleStatus2Sqlc(request.Params.Status) if err != nil { log.Errorf("%v", err) return oapi.GetTitles400Response{}, err @@ -289,9 +245,7 @@ func (s Server) GetTitles(ctx context.Context, request oapi.GetTitlesRequestObje params := sqlc.SearchTitlesParams{ Word: word, - Ongoing: status.ongoing, - Finished: status.finished, - Planned: status.planned, + Status: status, Rating: request.Params.Rating, ReleaseYear: request.Params.ReleaseYear, ReleaseSeason: season, @@ -300,9 +254,6 @@ func (s Server) GetTitles(ctx context.Context, request oapi.GetTitlesRequestObje Limit: request.Params.Limit, } - if request.Params.SortForward != nil { - params.Forward = *request.Params.SortForward - } if request.Params.Sort != nil { params.SortBy = string(*request.Params.Sort) if request.Params.Cursor != nil { @@ -338,7 +289,7 @@ func (s Server) GetTitles(ctx context.Context, request oapi.GetTitlesRequestObje if request.Params.Sort != nil { switch string(*request.Params.Sort) { case "year": - tmp := fmt.Sprint("%d", *t.ReleaseYear) + tmp := string(*t.ReleaseYear) new_cursor.Param = &tmp case "rating": tmp := strconv.FormatFloat(*t.Rating, 'f', -1, 64) diff --git a/modules/backend/queries.sql b/modules/backend/queries.sql index 16f8120..7118781 100644 --- a/modules/backend/queries.sql +++ b/modules/backend/queries.sql @@ -73,48 +73,14 @@ RETURNING id, tag_names; -- WHERE user_id = $1; -- name: GetTitleByID :one --- sqlc.struct: TitlesFull -SELECT - t.*, - i.storage_type::text as title_storage_type, - i.image_path as title_image_path, - jsonb_agg_strict(g.tag_name)'[]'::jsonb as tag_names, - 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 -LEFT JOIN images as i ON (t.image_id = i.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 studios as s ON (t.studio_id = s.id) -LEFT JOIN images as si ON (s.illust_id = si.id) - -WHERE id = sqlc.arg('title_id')::bigint -GROUP BY - t.id, i.id, s.id, si.id; +SELECT * +FROM titles +WHERE id = sqlc.arg('title_id')::bigint; -- name: SearchTitles :many SELECT - t.*, - i.storage_type::text as title_storage_type, - i.image_path as title_image_path, - jsonb_agg_strict(g.tag_name)'[]'::jsonb as tag_names, - 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 -LEFT JOIN images as i ON (t.image_id = i.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 studios as s ON (t.studio_id = s.id) -LEFT JOIN images as si ON (s.illust_id = si.id) - + * +FROM titles WHERE CASE WHEN sqlc.arg('forward')::boolean THEN @@ -122,17 +88,17 @@ WHERE CASE sqlc.arg('sort_by')::text WHEN 'year' THEN (sqlc.narg('cursor_year')::int IS NULL) OR - (t.release_year > sqlc.narg('cursor_year')::int) OR - (t.release_year = sqlc.narg('cursor_year')::int AND t.id > sqlc.narg('cursor_id')::bigint) + (release_year > sqlc.narg('cursor_year')::int) OR + (release_year = sqlc.narg('cursor_year')::int AND id > sqlc.narg('cursor_id')::bigint) WHEN 'rating' THEN (sqlc.narg('cursor_rating')::float IS NULL) OR - (t.rating > sqlc.narg('cursor_rating')::float) OR - (t.rating = sqlc.narg('cursor_rating')::float AND t.id > sqlc.narg('cursor_id')::bigint) + (rating > sqlc.narg('cursor_rating')::float) OR + (rating = sqlc.narg('cursor_rating')::float AND id > sqlc.narg('cursor_id')::bigint) WHEN 'id' THEN (sqlc.narg('cursor_id')::bigint IS NULL) OR - (t.id > sqlc.narg('cursor_id')::bigint) + (id > sqlc.narg('cursor_id')::bigint) ELSE true -- fallback END @@ -142,17 +108,17 @@ WHERE CASE sqlc.arg('sort_by')::text WHEN 'year' THEN (sqlc.narg('cursor_year')::int IS NULL) OR - (t.release_year < sqlc.narg('cursor_year')::int) OR - (t.release_year = sqlc.narg('cursor_year')::int AND t.id < sqlc.narg('cursor_id')::bigint) + (release_year < sqlc.narg('cursor_year')::int) OR + (release_year = sqlc.narg('cursor_year')::int AND id < sqlc.narg('cursor_id')::bigint) WHEN 'rating' THEN (sqlc.narg('cursor_rating')::float IS NULL) OR - (t.rating < sqlc.narg('cursor_rating')::float) OR - (t.rating = sqlc.narg('cursor_rating')::float AND t.id < sqlc.narg('cursor_id')::bigint) + (rating < sqlc.narg('cursor_rating')::float) OR + (rating = sqlc.narg('cursor_rating')::float AND id < sqlc.narg('cursor_id')::bigint) WHEN 'id' THEN (sqlc.narg('cursor_id')::bigint IS NULL) OR - (t.id < sqlc.narg('cursor_id')::bigint) + (id < sqlc.narg('cursor_id')::bigint) ELSE true END @@ -165,7 +131,7 @@ WHERE SELECT bool_and( EXISTS ( SELECT 1 - FROM jsonb_each_text(t.title_names) AS t(key, val) + FROM jsonb_each_text(title_names) AS t(key, val) WHERE val ILIKE pattern ) ) @@ -181,31 +147,28 @@ WHERE END ) - AND (t.title_status::text IN (sqlc.arg('ongoing')::text, sqlc.arg('finished')::text, sqlc.arg('planned')::text)) - 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_season')::release_season_t IS NULL OR t.release_season = sqlc.narg('release_season')::release_season_t) - -GROUP BY - t.id, i.id, s.id, si.id + AND (sqlc.narg('status')::title_status_t IS NULL OR title_status = sqlc.narg('status')::title_status_t) + AND (sqlc.narg('rating')::float IS NULL OR rating >= sqlc.narg('rating')::float) + AND (sqlc.narg('release_year')::int IS NULL OR release_year = sqlc.narg('release_year')::int) + AND (sqlc.narg('release_season')::release_season_t IS NULL OR release_season = sqlc.narg('release_season')::release_season_t) ORDER BY CASE WHEN sqlc.arg('forward')::boolean THEN CASE - WHEN sqlc.arg('sort_by')::text = 'id' THEN t.id - WHEN sqlc.arg('sort_by')::text = 'year' THEN t.release_year - WHEN sqlc.arg('sort_by')::text = 'rating' THEN t.rating + WHEN sqlc.arg('sort_by')::text = 'id' THEN id + WHEN sqlc.arg('sort_by')::text = 'year' THEN release_year + WHEN sqlc.arg('sort_by')::text = 'rating' THEN rating END END ASC, CASE WHEN NOT sqlc.arg('forward')::boolean THEN CASE - WHEN sqlc.arg('sort_by')::text = 'id' THEN t.id - WHEN sqlc.arg('sort_by')::text = 'year' THEN t.release_year - WHEN sqlc.arg('sort_by')::text = 'rating' THEN t.rating + WHEN sqlc.arg('sort_by')::text = 'id' THEN id + WHEN sqlc.arg('sort_by')::text = 'year' THEN release_year + WHEN sqlc.arg('sort_by')::text = 'rating' THEN rating END END DESC, - CASE WHEN sqlc.arg('sort_by')::text <> 'id' THEN t.id END ASC + CASE WHEN sqlc.arg('sort_by')::text <> 'id' THEN id END ASC LIMIT COALESCE(sqlc.narg('limit')::int, 100); -- 100 is default limit diff --git a/sql/queries.sql.go b/sql/queries.sql.go index 4342a12..7d970cb 100644 --- a/sql/queries.sql.go +++ b/sql/queries.sql.go @@ -116,53 +116,11 @@ const getTitleByID = `-- name: GetTitleByID :one -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, - i.storage_type::text as title_storage_type, - i.image_path as title_image_path, - jsonb_agg_strict(g.tag_name)'[]'::jsonb as tag_names, - 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 -LEFT JOIN images as i ON (t.image_id = i.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 studios as s ON (t.studio_id = s.id) -LEFT JOIN images as si ON (s.illust_id = si.id) - +SELECT id, title_names, studio_id, poster_id, title_status, rating, rating_count, release_year, release_season, season, episodes_aired, episodes_all, episodes_len +FROM titles WHERE id = $1::bigint -GROUP BY - t.id, i.id, s.id, si.id ` -type GetTitleByIDRow struct { - ID int64 `json:"id"` - TitleNames []byte `json:"title_names"` - StudioID int64 `json:"studio_id"` - PosterID *int64 `json:"poster_id"` - TitleStatus TitleStatusT `json:"title_status"` - Rating *float64 `json:"rating"` - RatingCount *int32 `json:"rating_count"` - ReleaseYear *int32 `json:"release_year"` - ReleaseSeason *ReleaseSeasonT `json:"release_season"` - Season *int32 `json:"season"` - EpisodesAired *int32 `json:"episodes_aired"` - EpisodesAll *int32 `json:"episodes_all"` - EpisodesLen []byte `json:"episodes_len"` - TitleStorageType string `json:"title_storage_type"` - TitleImagePath *string `json:"title_image_path"` - TagNames []byte `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"` -} - // -- name: ListUsers :many // SELECT user_id, avatar_id, passhash, mail, nickname, disp_name, user_desc, creation_date // FROM users @@ -186,10 +144,9 @@ type GetTitleByIDRow struct { // -- name: DeleteUser :exec // DELETE FROM users // WHERE user_id = $1; -// sqlc.struct: TitlesFull -func (q *Queries) GetTitleByID(ctx context.Context, titleID int64) (GetTitleByIDRow, error) { +func (q *Queries) GetTitleByID(ctx context.Context, titleID int64) (Title, error) { row := q.db.QueryRow(ctx, getTitleByID, titleID) - var i GetTitleByIDRow + var i Title err := row.Scan( &i.ID, &i.TitleNames, @@ -204,14 +161,6 @@ func (q *Queries) GetTitleByID(ctx context.Context, titleID int64) (GetTitleByID &i.EpisodesAired, &i.EpisodesAll, &i.EpisodesLen, - &i.TitleStorageType, - &i.TitleImagePath, - &i.TagNames, - &i.StudioName, - &i.StudioIllustID, - &i.StudioDesc, - &i.StudioStorageType, - &i.StudioImagePath, ) return i, err } @@ -338,23 +287,8 @@ func (q *Queries) InsertTitleTags(ctx context.Context, arg InsertTitleTagsParams const searchTitles = `-- name: SearchTitles :many 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, - i.storage_type::text as title_storage_type, - i.image_path as title_image_path, - jsonb_agg_strict(g.tag_name)'[]'::jsonb as tag_names, - 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 -LEFT JOIN images as i ON (t.image_id = i.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 studios as s ON (t.studio_id = s.id) -LEFT JOIN images as si ON (s.illust_id = si.id) - + id, title_names, studio_id, poster_id, title_status, rating, rating_count, release_year, release_season, season, episodes_aired, episodes_all, episodes_len +FROM titles WHERE CASE WHEN $1::boolean THEN @@ -362,17 +296,17 @@ WHERE CASE $2::text WHEN 'year' THEN ($3::int IS NULL) OR - (t.release_year > $3::int) OR - (t.release_year = $3::int AND t.id > $4::bigint) + (release_year > $3::int) OR + (release_year = $3::int AND id > $4::bigint) WHEN 'rating' THEN ($5::float IS NULL) OR - (t.rating > $5::float) OR - (t.rating = $5::float AND t.id > $4::bigint) + (rating > $5::float) OR + (rating = $5::float AND id > $4::bigint) WHEN 'id' THEN ($4::bigint IS NULL) OR - (t.id > $4::bigint) + (id > $4::bigint) ELSE true -- fallback END @@ -382,17 +316,17 @@ WHERE CASE $2::text WHEN 'year' THEN ($3::int IS NULL) OR - (t.release_year < $3::int) OR - (t.release_year = $3::int AND t.id < $4::bigint) + (release_year < $3::int) OR + (release_year = $3::int AND id < $4::bigint) WHEN 'rating' THEN ($5::float IS NULL) OR - (t.rating < $5::float) OR - (t.rating = $5::float AND t.id < $4::bigint) + (rating < $5::float) OR + (rating = $5::float AND id < $4::bigint) WHEN 'id' THEN ($4::bigint IS NULL) OR - (t.id < $4::bigint) + (id < $4::bigint) ELSE true END @@ -405,7 +339,7 @@ WHERE SELECT bool_and( EXISTS ( SELECT 1 - FROM jsonb_each_text(t.title_names) AS t(key, val) + FROM jsonb_each_text(title_names) AS t(key, val) WHERE val ILIKE pattern ) ) @@ -421,33 +355,30 @@ WHERE END ) - AND (t.title_status::text IN ($7::text, $8::text, $9::text)) - 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 - t.id, i.id, s.id, si.id + AND ($7::title_status_t IS NULL OR title_status = $7::title_status_t) + AND ($8::float IS NULL OR rating >= $8::float) + AND ($9::int IS NULL OR release_year = $9::int) + AND ($10::release_season_t IS NULL OR release_season = $10::release_season_t) ORDER BY CASE WHEN $1::boolean THEN CASE - WHEN $2::text = 'id' THEN t.id - WHEN $2::text = 'year' THEN t.release_year - WHEN $2::text = 'rating' THEN t.rating + WHEN $2::text = 'id' THEN id + WHEN $2::text = 'year' THEN release_year + WHEN $2::text = 'rating' THEN rating END END ASC, CASE WHEN NOT $1::boolean THEN CASE - WHEN $2::text = 'id' THEN t.id - WHEN $2::text = 'year' THEN t.release_year - WHEN $2::text = 'rating' THEN t.rating + WHEN $2::text = 'id' THEN id + WHEN $2::text = 'year' THEN release_year + WHEN $2::text = 'rating' THEN rating END END DESC, - CASE WHEN $2::text <> 'id' THEN t.id END ASC + CASE WHEN $2::text <> 'id' THEN id END ASC -LIMIT COALESCE($13::int, 100) +LIMIT COALESCE($11::int, 100) ` type SearchTitlesParams struct { @@ -457,40 +388,14 @@ type SearchTitlesParams struct { CursorID *int64 `json:"cursor_id"` CursorRating *float64 `json:"cursor_rating"` Word *string `json:"word"` - Ongoing string `json:"ongoing"` - Finished string `json:"finished"` - Planned string `json:"planned"` + Status *TitleStatusT `json:"status"` Rating *float64 `json:"rating"` ReleaseYear *int32 `json:"release_year"` ReleaseSeason *ReleaseSeasonT `json:"release_season"` Limit *int32 `json:"limit"` } -type SearchTitlesRow struct { - ID int64 `json:"id"` - TitleNames []byte `json:"title_names"` - StudioID int64 `json:"studio_id"` - PosterID *int64 `json:"poster_id"` - TitleStatus TitleStatusT `json:"title_status"` - Rating *float64 `json:"rating"` - RatingCount *int32 `json:"rating_count"` - ReleaseYear *int32 `json:"release_year"` - ReleaseSeason *ReleaseSeasonT `json:"release_season"` - Season *int32 `json:"season"` - EpisodesAired *int32 `json:"episodes_aired"` - EpisodesAll *int32 `json:"episodes_all"` - EpisodesLen []byte `json:"episodes_len"` - TitleStorageType string `json:"title_storage_type"` - TitleImagePath *string `json:"title_image_path"` - TagNames []byte `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) ([]Title, error) { rows, err := q.db.Query(ctx, searchTitles, arg.Forward, arg.SortBy, @@ -498,9 +403,7 @@ func (q *Queries) SearchTitles(ctx context.Context, arg SearchTitlesParams) ([]S arg.CursorID, arg.CursorRating, arg.Word, - arg.Ongoing, - arg.Finished, - arg.Planned, + arg.Status, arg.Rating, arg.ReleaseYear, arg.ReleaseSeason, @@ -510,9 +413,9 @@ func (q *Queries) SearchTitles(ctx context.Context, arg SearchTitlesParams) ([]S return nil, err } defer rows.Close() - items := []SearchTitlesRow{} + items := []Title{} for rows.Next() { - var i SearchTitlesRow + var i Title if err := rows.Scan( &i.ID, &i.TitleNames, @@ -527,14 +430,6 @@ func (q *Queries) SearchTitles(ctx context.Context, arg SearchTitlesParams) ([]S &i.EpisodesAired, &i.EpisodesAll, &i.EpisodesLen, - &i.TitleStorageType, - &i.TitleImagePath, - &i.TagNames, - &i.StudioName, - &i.StudioIllustID, - &i.StudioDesc, - &i.StudioStorageType, - &i.StudioImagePath, ); err != nil { return nil, err }