From 4fe077d22981ff3626bc13990f037e5760156fd6 Mon Sep 17 00:00:00 2001 From: Iron_Felix Date: Sat, 20 Dec 2025 01:16:26 +0300 Subject: [PATCH] feat: now PostImage return Image struct even on duplicate data --- modules/backend/handlers/images.go | 66 +++++++++++++++++------------- modules/backend/queries.sql | 5 +++ sql/queries.sql.go | 13 ++++++ 3 files changed, 55 insertions(+), 29 deletions(-) diff --git a/modules/backend/handlers/images.go b/modules/backend/handlers/images.go index 5c8dce7..c3d3a7f 100644 --- a/modules/backend/handlers/images.go +++ b/modules/backend/handlers/images.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "image" "image/jpeg" @@ -17,6 +18,7 @@ import ( "strings" "github.com/disintegration/imaging" + "github.com/jackc/pgx/v5/pgconn" log "github.com/sirupsen/logrus" "golang.org/x/image/webp" ) @@ -132,15 +134,47 @@ func (s *Server) PostMediaUpload(ctx context.Context, request oapi.PostMediaUplo // TODO: param for local/s3 case _image, err := s.db.CreateImage(ctx, params) + if err != nil { + var pgErr *pgconn.PgError + if errors.As(err, &pgErr) { + if pgErr.Code == pgErrDuplicateKey { //duplicate key value + log.Errorf("%v", err) + + _image, err = s.db.GetImageByPath(ctx, storageResp.Path) + if err != nil { + log.Errorf("%v", err) + return oapi.PostMediaUpload500Response{}, nil + } + image, err := mapImage(_image) + if err != nil { + log.Errorf("%v", err) + return oapi.PostMediaUpload500Response{}, nil + } + return oapi.PostMediaUpload200JSONResponse(*image), nil + } else { + log.Errorf("%v", err) + return oapi.PostMediaUpload500Response{}, nil + } + } else { + log.Errorf("%v", err) + return oapi.PostMediaUpload500Response{}, nil + } + } + + image, err := mapImage(_image) if err != nil { log.Errorf("%v", err) return oapi.PostMediaUpload500Response{}, nil } + return oapi.PostMediaUpload200JSONResponse(*image), nil +} + +func mapImage(_image sqlc.Image) (*oapi.Image, error) { + sType, err := sql2StorageType(&_image.StorageType) if err != nil { - log.Errorf("%v", err) - return oapi.PostMediaUpload500Response{}, nil + return nil, fmt.Errorf("mapImage: %v", err) } image := oapi.Image{ @@ -149,31 +183,5 @@ func (s *Server) PostMediaUpload(ctx context.Context, request oapi.PostMediaUplo StorageType: sType, } - return oapi.PostMediaUpload200JSONResponse(image), nil -} - -// Вспомогательные функции — как раньше -func generateRandomHex(n int) string { - b := make([]byte, n) - for i := range b { - b[i] = byte('a' + (i % 16)) - } - return fmt.Sprintf("%x", b) -} - -func sanitizeFilename(name string) string { - var clean strings.Builder - for _, r := range name { - if (r >= 'a' && r <= 'z') || - (r >= 'A' && r <= 'Z') || - (r >= '0' && r <= '9') || - r == '.' || r == '_' || r == '-' { - clean.WriteRune(r) - } - } - s := clean.String() - if s == "" { - return "file" - } - return s + return &image, nil } diff --git a/modules/backend/queries.sql b/modules/backend/queries.sql index 7117456..99b59be 100644 --- a/modules/backend/queries.sql +++ b/modules/backend/queries.sql @@ -3,6 +3,11 @@ SELECT id, storage_type, image_path FROM images WHERE id = sqlc.arg('illust_id')::bigint; +-- name: GetImageByPath :one +SELECT id, storage_type, image_path +FROM images +WHERE image_path = sqlc.arg('illust_path')::text; + -- name: CreateImage :one INSERT INTO images (storage_type, image_path) VALUES ($1, $2) diff --git a/sql/queries.sql.go b/sql/queries.sql.go index 0c863e8..de8e12d 100644 --- a/sql/queries.sql.go +++ b/sql/queries.sql.go @@ -102,6 +102,19 @@ func (q *Queries) GetImageByID(ctx context.Context, illustID int64) (Image, erro return i, err } +const getImageByPath = `-- name: GetImageByPath :one +SELECT id, storage_type, image_path +FROM images +WHERE image_path = $1::text +` + +func (q *Queries) GetImageByPath(ctx context.Context, illustPath string) (Image, error) { + row := q.db.QueryRow(ctx, getImageByPath, illustPath) + var i Image + err := row.Scan(&i.ID, &i.StorageType, &i.ImagePath) + return i, err +} + const getReviewByID = `-- name: GetReviewByID :one SELECT id, data, rating, user_id, title_id, created_at