Compare commits

..

No commits in common. "47989ab10da73e351f9550dbae328698c38bc68e" and "e18f4a44c3acf4b0fc36889690e853dd7b416c0e" have entirely different histories.

6 changed files with 128 additions and 387 deletions

View file

@ -31,13 +31,6 @@ const (
Planned TitleStatus = "planned"
)
// Image defines model for Image.
type Image struct {
Id *int64 `json:"id,omitempty"`
ImagePath *string `json:"image_path,omitempty"`
StorageType *string `json:"storage_type,omitempty"`
}
// ReleaseSeason Title release season
type ReleaseSeason string
@ -46,7 +39,8 @@ type Studio struct {
Description *string `json:"description,omitempty"`
Id *int64 `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
Poster *Image `json:"poster,omitempty"`
PosterId *int64 `json:"poster_id,omitempty"`
PosterPath *string `json:"poster_path,omitempty"`
}
// Tag A localized tag: keys are language codes (ISO 639-1), values are tag names
@ -63,7 +57,7 @@ type Title struct {
// Id Unique title ID (primary key)
Id int64 `json:"id"`
Poster *Image `json:"poster,omitempty"`
PosterId *int64 `json:"poster_id,omitempty"`
Rating *float64 `json:"rating,omitempty"`
RatingCount *int32 `json:"rating_count,omitempty"`
@ -122,11 +116,6 @@ type GetTitleParams struct {
Fields *string `form:"fields,omitempty" json:"fields,omitempty"`
}
// GetTitleTitleIdParams defines parameters for GetTitleTitleId.
type GetTitleTitleIdParams struct {
Fields *string `form:"fields,omitempty" json:"fields,omitempty"`
}
// GetUsersUserIdParams defines parameters for GetUsersUserId.
type GetUsersUserIdParams struct {
Fields *string `form:"fields,omitempty" json:"fields,omitempty"`
@ -189,12 +178,12 @@ func (a *Title) UnmarshalJSON(b []byte) error {
delete(object, "id")
}
if raw, found := object["poster"]; found {
err = json.Unmarshal(raw, &a.Poster)
if raw, found := object["poster_id"]; found {
err = json.Unmarshal(raw, &a.PosterId)
if err != nil {
return fmt.Errorf("error reading 'poster': %w", err)
return fmt.Errorf("error reading 'poster_id': %w", err)
}
delete(object, "poster")
delete(object, "poster_id")
}
if raw, found := object["rating"]; found {
@ -306,10 +295,10 @@ func (a Title) MarshalJSON() ([]byte, error) {
return nil, fmt.Errorf("error marshaling 'id': %w", err)
}
if a.Poster != nil {
object["poster"], err = json.Marshal(a.Poster)
if a.PosterId != nil {
object["poster_id"], err = json.Marshal(a.PosterId)
if err != nil {
return nil, fmt.Errorf("error marshaling 'poster': %w", err)
return nil, fmt.Errorf("error marshaling 'poster_id': %w", err)
}
}
@ -379,9 +368,6 @@ type ServerInterface interface {
// Get titles
// (GET /title)
GetTitle(c *gin.Context, params GetTitleParams)
// Get title description
// (GET /title/{title_id})
GetTitleTitleId(c *gin.Context, titleId int64, params GetTitleTitleIdParams)
// Get user info
// (GET /users/{user_id})
GetUsersUserId(c *gin.Context, userId string, params GetUsersUserIdParams)
@ -478,41 +464,6 @@ func (siw *ServerInterfaceWrapper) GetTitle(c *gin.Context) {
siw.Handler.GetTitle(c, params)
}
// GetTitleTitleId operation middleware
func (siw *ServerInterfaceWrapper) GetTitleTitleId(c *gin.Context) {
var err error
// ------------- Path parameter "title_id" -------------
var titleId int64
err = runtime.BindStyledParameterWithOptions("simple", "title_id", c.Param("title_id"), &titleId, runtime.BindStyledParameterOptions{Explode: false, Required: true})
if err != nil {
siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter title_id: %w", err), http.StatusBadRequest)
return
}
// Parameter object where we will unmarshal all parameters from the context
var params GetTitleTitleIdParams
// ------------- Optional query parameter "fields" -------------
err = runtime.BindQueryParameter("form", true, false, "fields", c.Request.URL.Query(), &params.Fields)
if err != nil {
siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter fields: %w", err), http.StatusBadRequest)
return
}
for _, middleware := range siw.HandlerMiddlewares {
middleware(c)
if c.IsAborted() {
return
}
}
siw.Handler.GetTitleTitleId(c, titleId, params)
}
// GetUsersUserId operation middleware
func (siw *ServerInterfaceWrapper) GetUsersUserId(c *gin.Context) {
@ -576,7 +527,6 @@ func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options
}
router.GET(options.BaseURL+"/title", wrapper.GetTitle)
router.GET(options.BaseURL+"/title/:title_id", wrapper.GetTitleTitleId)
router.GET(options.BaseURL+"/users/:user_id", wrapper.GetUsersUserId)
}
@ -621,48 +571,6 @@ func (response GetTitle500Response) VisitGetTitleResponse(w http.ResponseWriter)
return nil
}
type GetTitleTitleIdRequestObject struct {
TitleId int64 `json:"title_id"`
Params GetTitleTitleIdParams
}
type GetTitleTitleIdResponseObject interface {
VisitGetTitleTitleIdResponse(w http.ResponseWriter) error
}
type GetTitleTitleId200JSONResponse Title
func (response GetTitleTitleId200JSONResponse) VisitGetTitleTitleIdResponse(w http.ResponseWriter) error {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(200)
return json.NewEncoder(w).Encode(response)
}
type GetTitleTitleId400Response struct {
}
func (response GetTitleTitleId400Response) VisitGetTitleTitleIdResponse(w http.ResponseWriter) error {
w.WriteHeader(400)
return nil
}
type GetTitleTitleId404Response struct {
}
func (response GetTitleTitleId404Response) VisitGetTitleTitleIdResponse(w http.ResponseWriter) error {
w.WriteHeader(404)
return nil
}
type GetTitleTitleId500Response struct {
}
func (response GetTitleTitleId500Response) VisitGetTitleTitleIdResponse(w http.ResponseWriter) error {
w.WriteHeader(500)
return nil
}
type GetUsersUserIdRequestObject struct {
UserId string `json:"user_id"`
Params GetUsersUserIdParams
@ -710,9 +618,6 @@ type StrictServerInterface interface {
// Get titles
// (GET /title)
GetTitle(ctx context.Context, request GetTitleRequestObject) (GetTitleResponseObject, error)
// Get title description
// (GET /title/{title_id})
GetTitleTitleId(ctx context.Context, request GetTitleTitleIdRequestObject) (GetTitleTitleIdResponseObject, error)
// Get user info
// (GET /users/{user_id})
GetUsersUserId(ctx context.Context, request GetUsersUserIdRequestObject) (GetUsersUserIdResponseObject, error)
@ -757,34 +662,6 @@ func (sh *strictHandler) GetTitle(ctx *gin.Context, params GetTitleParams) {
}
}
// GetTitleTitleId operation middleware
func (sh *strictHandler) GetTitleTitleId(ctx *gin.Context, titleId int64, params GetTitleTitleIdParams) {
var request GetTitleTitleIdRequestObject
request.TitleId = titleId
request.Params = params
handler := func(ctx *gin.Context, request interface{}) (interface{}, error) {
return sh.ssi.GetTitleTitleId(ctx, request.(GetTitleTitleIdRequestObject))
}
for _, middleware := range sh.middlewares {
handler = middleware(handler, "GetTitleTitleId")
}
response, err := handler(ctx, request)
if err != nil {
ctx.Error(err)
ctx.Status(http.StatusInternalServerError)
} else if validResponse, ok := response.(GetTitleTitleIdResponseObject); ok {
if err := validResponse.VisitGetTitleTitleIdResponse(ctx.Writer); err != nil {
ctx.Error(err)
}
} else if response != nil {
ctx.Error(fmt.Errorf("unexpected response type: %T", response))
}
}
// GetUsersUserId operation middleware
func (sh *strictHandler) GetUsersUserId(ctx *gin.Context, userId string, params GetUsersUserIdParams) {
var request GetUsersUserIdRequestObject

View file

@ -66,34 +66,29 @@ paths:
'500':
description: Unknown server error
/title/{title_id}:
get:
summary: Get title description
parameters:
- in: path
name: title_id
required: true
schema:
type: integer
format: int64
- in: query
name: fields
schema:
type: string
default: all
responses:
'200':
description: Title description
content:
application/json:
schema:
$ref: '#/components/schemas/Title'
'404':
description: Title not found
'400':
description: Request params are not correct
'500':
description: Unknown server error
# /title/{title_id}:
# get:
# summary: Get title description
# parameters:
# - in: path
# name: title_id
# required: true
# schema:
# type: string
# - in: query
# name: fields
# schema:
# type: string
# default: all
# responses:
# '200':
# description: Title description
# content:
# application/json:
# schema:
# $ref: '#/components/schemas/Title'
# '404':
# description: Title not found
# patch:
# summary: Update title info
@ -570,17 +565,6 @@ paths:
components:
schemas:
Image:
type: object
properties:
id:
type: integer
format: int64
storage_type:
type: string
image_path:
type: string
TitleStatus:
type: string
description: Title status
@ -642,8 +626,11 @@ components:
format: int64
name:
type: string
poster:
$ref: '#/components/schemas/Image'
poster_id:
type: integer
format: int64
poster_path:
type: string
description:
type: string
@ -678,8 +665,9 @@ components:
$ref: '#/components/schemas/Studio'
tags:
$ref: '#/components/schemas/Tags'
poster:
$ref: '#/components/schemas/Image'
poster_id:
type: integer
format: int64
title_status:
$ref: '#/components/schemas/TitleStatus'
rating:

View file

@ -25,14 +25,13 @@ func TitleStatus2Sqlc(s *oapi.TitleStatus) (*sqlc.TitleStatusT, error) {
return nil, nil
}
var t sqlc.TitleStatusT
switch *s {
case oapi.Finished:
t = sqlc.TitleStatusTFinished
case oapi.Ongoing:
t = sqlc.TitleStatusTOngoing
case oapi.Planned:
t = sqlc.TitleStatusTPlanned
default:
if *s == "finished" {
t = "finished"
} else if *s == "ongoing" {
t = "ongoing"
} else if *s == "planned" {
t = "planned"
} else {
return nil, fmt.Errorf("unexpected tittle status: %s", *s)
}
return &t, nil
@ -42,153 +41,45 @@ func ReleaseSeason2sqlc(s *oapi.ReleaseSeason) (*sqlc.ReleaseSeasonT, error) {
if s == nil {
return nil, nil
}
//TODO
var t sqlc.ReleaseSeasonT
switch *s {
case oapi.Winter:
if *s == oapi.Winter {
t = sqlc.ReleaseSeasonTWinter
case oapi.Spring:
t = sqlc.ReleaseSeasonTSpring
case oapi.Summer:
t = sqlc.ReleaseSeasonTSummer
case oapi.Fall:
t = sqlc.ReleaseSeasonTFall
default:
} else if *s == "spring" {
t = "spring"
} else if *s == "summer" {
t = "summer"
} else if *s == "fall" {
t = "fall"
} else {
return nil, fmt.Errorf("unexpected release season: %s", *s)
}
return &t, nil
}
// type TitleNames map[string][]string
// type EpisodeLens map[string]float64
// type TagNames []map[string]string
type TileNames *map[string][]string
func (s Server) GetTagsByTitleId(ctx context.Context, id int64) (oapi.Tags, error) {
sqlc_title_tags, err := s.db.GetTitleTags(ctx, id)
if err != nil {
return nil, fmt.Errorf("query GetTitleTags: %v", err)
// unmarshall jsonb to map[string][]string
func jsonb2TitleNames(b []byte) (TileNames, error) {
var t TileNames
if err := json.Unmarshal(b, t); err != nil {
return nil, fmt.Errorf("invalid title_names JSON for title: %w", err)
}
var oapi_tag_names oapi.Tags
for _, title_tag := range sqlc_title_tags {
var oapi_tag_name map[string]string
err = json.Unmarshal(title_tag, &oapi_tag_name)
if err != nil {
return nil, fmt.Errorf("unmarshalling title_tag: %v", err)
}
oapi_tag_names = append(oapi_tag_names, oapi_tag_name)
}
return oapi_tag_names, nil
return t, nil
}
func (s Server) GetImage(ctx context.Context, id int64) (oapi.Image, error) {
type EpisodeLens *map[string]float64
var oapi_image oapi.Image
sqlc_image, err := s.db.GetImageByID(ctx, id)
if err != nil {
return oapi_image, fmt.Errorf("query GetImageByID: %v", err)
func jsonb2EpisodeLens(b []byte) (EpisodeLens, error) {
var t EpisodeLens
if err := json.Unmarshal(b, t); err != nil {
return nil, fmt.Errorf("invalid episodes_len JSON for title: %w", err)
}
//can cast and dont use brain cause all this fiels required
oapi_image.Id = &sqlc_image.ID
oapi_image.ImagePath = &sqlc_image.ImagePath
oapi_image.StorageType = (*string)(&sqlc_image.StorageType)
return oapi_image, nil
}
func (s Server) GetStudio(ctx context.Context, id int64) (oapi.Studio, error) {
var oapi_studio oapi.Studio
sqlc_studio, err := s.db.GetStudioByID(ctx, id)
if err != nil {
return oapi_studio, fmt.Errorf("query GetStudioByID: %v", err)
}
oapi_studio.Id = &sqlc_studio.ID
oapi_studio.Name = sqlc_studio.StudioName
oapi_studio.Description = sqlc_studio.StudioDesc
oapi_illust, err := s.GetImage(ctx, *sqlc_studio.IllustID)
if err != nil {
return oapi_studio, fmt.Errorf("GetImage: %v", err)
}
oapi_studio.Poster = &oapi_illust
return oapi_studio, nil
}
func (s Server) mapTitle(ctx context.Context, title sqlc.Title) (oapi.Title, error) {
var oapi_title oapi.Title
var title_names map[string][]string
err := json.Unmarshal(title.TitleNames, &title_names)
if err != nil {
return oapi_title, fmt.Errorf("unmarshal TitleNames: %v", err)
}
var episodes_lens map[string]float64
err = json.Unmarshal(title.EpisodesLen, &episodes_lens)
if err != nil {
return oapi_title, fmt.Errorf("unmarshal EpisodesLen: %v", err)
}
oapi_tag_names, err := s.GetTagsByTitleId(ctx, title.ID)
if err != nil {
return oapi_title, fmt.Errorf("GetTagsByTitleId: %v", err)
}
oapi_image, err := s.GetImage(ctx, *title.PosterID)
if err != nil {
return oapi_title, fmt.Errorf("GetImage: %v", err)
}
oapi_studio, err := s.GetStudio(ctx, title.StudioID)
if err != nil {
return oapi_title, fmt.Errorf("GetStudio: %v", err)
}
oapi_title = oapi.Title{
Id: title.ID,
Poster: &oapi_image,
Rating: title.Rating,
RatingCount: title.RatingCount,
ReleaseSeason: (*oapi.ReleaseSeason)(title.ReleaseSeason),
ReleaseYear: title.ReleaseYear,
Studio: &oapi_studio,
Tags: oapi_tag_names,
TitleNames: title_names,
TitleStatus: (*oapi.TitleStatus)(&title.TitleStatus),
EpisodesAired: title.EpisodesAired,
EpisodesAll: title.EpisodesAll,
EpisodesLen: &episodes_lens,
}
return oapi_title, nil
}
func (s Server) GetTitleTitleId(ctx context.Context, request oapi.GetTitleTitleIdRequestObject) (oapi.GetTitleTitleIdResponseObject, error) {
var oapi_title oapi.Title
sqlc_title, err := s.db.GetTitleByID(ctx, request.TitleId)
if err != nil {
log.Errorf("%v", err)
return oapi.GetTitleTitleId500Response{}, nil
}
oapi_title, err = s.mapTitle(ctx, sqlc_title)
if err != nil {
log.Errorf("%v", err)
return oapi.GetTitleTitleId500Response{}, nil
}
return oapi.GetTitleTitleId200JSONResponse(oapi_title), nil
return t, nil
}
func (s Server) GetTitle(ctx context.Context, request oapi.GetTitleRequestObject) (oapi.GetTitleResponseObject, error) {
var opai_titles []oapi.Title
var result []oapi.Title
word := Word2Sqlc(request.Params.Word)
status, err := TitleStatus2Sqlc(request.Params.Status)
@ -212,7 +103,6 @@ func (s Server) GetTitle(ctx context.Context, request oapi.GetTitleRequestObject
Limit: request.Params.Limit,
})
if err != nil {
log.Errorf("%v", err)
return oapi.GetTitle500Response{}, nil
}
if len(titles) == 0 {
@ -220,14 +110,33 @@ func (s Server) GetTitle(ctx context.Context, request oapi.GetTitleRequestObject
}
for _, title := range titles {
t, err := s.mapTitle(ctx, title)
title_names, err := jsonb2TitleNames(title.TitleNames)
if err != nil {
log.Errorf("%v", err)
return oapi.GetTitle500Response{}, nil
return oapi.GetTitle500Response{}, err
}
opai_titles = append(opai_titles, t)
episodes_lens, err := jsonb2EpisodeLens(title.EpisodesLen)
if err != nil {
log.Errorf("%v", err)
return oapi.GetTitle500Response{}, err
}
t := oapi.Title{
Id: &title.ID,
PosterId: title.PosterID,
Rating: title.Rating,
RatingCount: title.RatingCount,
ReleaseSeason: (*oapi.ReleaseSeason)(title.ReleaseSeason),
ReleaseYear: title.ReleaseYear,
StudioId: &title.StudioID,
// StudioName: ,
TitleNames: title_names,
TitleStatus: (*oapi.TitleStatus)(&title.TitleStatus),
EpisodesAired: title.EpisodesAired,
EpisodesAll: title.EpisodesAll,
EpisodesLen: episodes_lens,
}
result = append(result, t)
}
return oapi.GetTitle200JSONResponse(opai_titles), nil
return oapi.GetTitle200JSONResponse(result), nil
}

View file

@ -1,7 +1,7 @@
-- name: GetImageByID :one
SELECT id, storage_type, image_path
FROM images
WHERE id = sqlc.arg('illust_id');
WHERE id = $1;
-- name: CreateImage :one
INSERT INTO images (storage_type, image_path)
@ -17,7 +17,7 @@ WHERE id = $1;
-- name: GetStudioByID :one
SELECT *
FROM studios
WHERE id = sqlc.arg('studio_id')::bigint;
WHERE id = sqlc.arg('studio_id')::int;
-- name: InsertStudio :one
INSERT INTO studios (studio_name, illust_id, studio_desc)
@ -72,11 +72,6 @@ RETURNING id, tag_names;
-- DELETE FROM users
-- WHERE user_id = $1;
-- name: GetTitleByID :one
SELECT *
FROM titles
WHERE id = sqlc.arg('title_id')::bigint;
-- name: SearchTitles :many
SELECT
*

View file

@ -14,7 +14,6 @@ CREATE TABLE providers (
CREATE TABLE tags (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
-- example: { "ru": "Сёдзё", "en": "Shojo", "jp": "少女"}
tag_names jsonb NOT NULL
);

View file

@ -34,8 +34,8 @@ FROM images
WHERE id = $1
`
func (q *Queries) GetImageByID(ctx context.Context, illustID int64) (Image, error) {
row := q.db.QueryRow(ctx, getImageByID, illustID)
func (q *Queries) GetImageByID(ctx context.Context, id int64) (Image, error) {
row := q.db.QueryRow(ctx, getImageByID, id)
var i Image
err := row.Scan(&i.ID, &i.StorageType, &i.ImagePath)
return i, err
@ -44,10 +44,10 @@ func (q *Queries) GetImageByID(ctx context.Context, illustID int64) (Image, erro
const getStudioByID = `-- name: GetStudioByID :one
SELECT id, studio_name, illust_id, studio_desc
FROM studios
WHERE id = $1::bigint
WHERE id = $1::int
`
func (q *Queries) GetStudioByID(ctx context.Context, studioID int64) (Studio, error) {
func (q *Queries) GetStudioByID(ctx context.Context, studioID int32) (Studio, error) {
row := q.db.QueryRow(ctx, getStudioByID, studioID)
var i Studio
err := row.Scan(
@ -59,60 +59,6 @@ func (q *Queries) GetStudioByID(ctx context.Context, studioID int64) (Studio, er
return i, err
}
const getTitleByID = `-- name: GetTitleByID :one
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
`
// -- name: ListUsers :many
// SELECT user_id, avatar_id, passhash, mail, nickname, disp_name, user_desc, creation_date
// FROM users
// ORDER BY user_id
// LIMIT $1 OFFSET $2;
// -- name: CreateUser :one
// INSERT INTO users (avatar_id, passhash, mail, nickname, disp_name, user_desc, creation_date)
// VALUES ($1, $2, $3, $4, $5, $6, $7)
// RETURNING user_id, avatar_id, nickname, disp_name, user_desc, creation_date;
// -- name: UpdateUser :one
// UPDATE users
// SET
//
// avatar_id = COALESCE(sqlc.narg('avatar_id'), avatar_id),
// disp_name = COALESCE(sqlc.narg('disp_name'), disp_name),
// user_desc = COALESCE(sqlc.narg('user_desc'), user_desc),
// passhash = COALESCE(sqlc.narg('passhash'), passhash)
//
// WHERE user_id = sqlc.arg('user_id')
// RETURNING user_id, avatar_id, nickname, disp_name, user_desc, creation_date;
// -- name: DeleteUser :exec
// DELETE FROM users
// WHERE user_id = $1;
func (q *Queries) GetTitleByID(ctx context.Context, titleID int64) (Title, error) {
row := q.db.QueryRow(ctx, getTitleByID, titleID)
var i Title
err := row.Scan(
&i.ID,
&i.TitleNames,
&i.StudioID,
&i.PosterID,
&i.TitleStatus,
&i.Rating,
&i.RatingCount,
&i.ReleaseYear,
&i.ReleaseSeason,
&i.Season,
&i.EpisodesAired,
&i.EpisodesAll,
&i.EpisodesLen,
)
return i, err
}
const getTitleTags = `-- name: GetTitleTags :many
SELECT
tag_names
@ -234,6 +180,10 @@ func (q *Queries) InsertTitleTags(ctx context.Context, arg InsertTitleTagsParams
}
const searchTitles = `-- name: SearchTitles :many
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
@ -278,6 +228,29 @@ type SearchTitlesParams struct {
Limit *int32 `json:"limit"`
}
// -- name: ListUsers :many
// SELECT user_id, avatar_id, passhash, mail, nickname, disp_name, user_desc, creation_date
// FROM users
// ORDER BY user_id
// LIMIT $1 OFFSET $2;
// -- name: CreateUser :one
// INSERT INTO users (avatar_id, passhash, mail, nickname, disp_name, user_desc, creation_date)
// VALUES ($1, $2, $3, $4, $5, $6, $7)
// RETURNING user_id, avatar_id, nickname, disp_name, user_desc, creation_date;
// -- name: UpdateUser :one
// UPDATE users
// SET
//
// avatar_id = COALESCE(sqlc.narg('avatar_id'), avatar_id),
// disp_name = COALESCE(sqlc.narg('disp_name'), disp_name),
// user_desc = COALESCE(sqlc.narg('user_desc'), user_desc),
// passhash = COALESCE(sqlc.narg('passhash'), passhash)
//
// WHERE user_id = sqlc.arg('user_id')
// RETURNING user_id, avatar_id, nickname, disp_name, user_desc, creation_date;
// -- name: DeleteUser :exec
// DELETE FROM users
// WHERE user_id = $1;
func (q *Queries) SearchTitles(ctx context.Context, arg SearchTitlesParams) ([]Title, error) {
rows, err := q.db.Query(ctx, searchTitles,
arg.Word,