feat: now PostImage return Image struct even on duplicate data
All checks were successful
Build (backend build only) / build (push) Successful in 3m18s
Build and Deploy Go App / build (push) Successful in 8m32s
Build and Deploy Go App / deploy (push) Successful in 27s

This commit is contained in:
Iron_Felix 2025-12-20 01:16:26 +03:00
parent c58b578023
commit 4fe077d229
3 changed files with 55 additions and 29 deletions

View file

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"context" "context"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"image" "image"
"image/jpeg" "image/jpeg"
@ -17,6 +18,7 @@ import (
"strings" "strings"
"github.com/disintegration/imaging" "github.com/disintegration/imaging"
"github.com/jackc/pgx/v5/pgconn"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"golang.org/x/image/webp" "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 // TODO: param for local/s3 case
_image, err := s.db.CreateImage(ctx, params) _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 { if err != nil {
log.Errorf("%v", err) log.Errorf("%v", err)
return oapi.PostMediaUpload500Response{}, nil return oapi.PostMediaUpload500Response{}, nil
} }
return oapi.PostMediaUpload200JSONResponse(*image), nil
}
func mapImage(_image sqlc.Image) (*oapi.Image, error) {
sType, err := sql2StorageType(&_image.StorageType) sType, err := sql2StorageType(&_image.StorageType)
if err != nil { if err != nil {
log.Errorf("%v", err) return nil, fmt.Errorf("mapImage: %v", err)
return oapi.PostMediaUpload500Response{}, nil
} }
image := oapi.Image{ image := oapi.Image{
@ -149,31 +183,5 @@ func (s *Server) PostMediaUpload(ctx context.Context, request oapi.PostMediaUplo
StorageType: sType, StorageType: sType,
} }
return oapi.PostMediaUpload200JSONResponse(image), nil return &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
} }

View file

@ -3,6 +3,11 @@ SELECT id, storage_type, image_path
FROM images FROM images
WHERE id = sqlc.arg('illust_id')::bigint; 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 -- name: CreateImage :one
INSERT INTO images (storage_type, image_path) INSERT INTO images (storage_type, image_path)
VALUES ($1, $2) VALUES ($1, $2)

View file

@ -102,6 +102,19 @@ func (q *Queries) GetImageByID(ctx context.Context, illustID int64) (Image, erro
return i, err 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 const getReviewByID = `-- name: GetReviewByID :one
SELECT id, data, rating, user_id, title_id, created_at SELECT id, data, rating, user_id, title_id, created_at