add file counter for upload file

This commit is contained in:
harold 2025-03-05 21:12:15 +05:00
parent ee252638cb
commit 5287f61c44
5 changed files with 82 additions and 21 deletions

View File

@ -2,10 +2,13 @@ package sysStorage
import ( import (
"bytes" "bytes"
"fmt"
"io" "io"
"mime/multipart" "mime/multipart"
"os" "os"
"path/filepath"
"strconv" "strconv"
"strings"
) )
type LocalStorage struct { type LocalStorage struct {
@ -30,35 +33,38 @@ func NewLocalStorage(basePath string) *LocalStorage {
func (ls *LocalStorage) Upload( func (ls *LocalStorage) Upload(
file *multipart.FileHeader, file *multipart.FileHeader,
streamerID int, streamerID int,
) error { ) (string, error) {
dirPath := ls.basePath + "/" + strconv.Itoa(streamerID) dirPath := ls.basePath + "/" + strconv.Itoa(streamerID)
if _, err := os.Stat(dirPath); os.IsNotExist(err) { if _, err := os.Stat(dirPath); os.IsNotExist(err) {
if err := os.MkdirAll(dirPath, os.ModePerm); err != nil { if err := os.MkdirAll(dirPath, os.ModePerm); err != nil {
return err return "", err
} }
} }
f, err := os.Create(dirPath + "/" + file.Filename) fileName := ls.ensureUniqueFileName(
dirPath,
file.Filename,
)
f, err := os.Create(dirPath + "/" + fileName)
if err != nil { if err != nil {
return err return "", err
} }
defer f.Close() defer f.Close()
// Открываем загруженный файл
srcFile, err := file.Open() srcFile, err := file.Open()
if err != nil { if err != nil {
return err return "", err
} }
defer srcFile.Close() defer srcFile.Close()
// Копируем содержимое в новый файл
_, err = io.Copy(f, srcFile) _, err = io.Copy(f, srcFile)
if err != nil { if err != nil {
return err return "", err
} }
return nil return fileName, nil
} }
func (ls *LocalStorage) Download( func (ls *LocalStorage) Download(
@ -95,3 +101,23 @@ func (ls *LocalStorage) Delete(
return nil return nil
} }
func (ls *LocalStorage) ensureUniqueFileName(
dirPath, fileName string,
) string {
ext := filepath.Ext(fileName)
name := strings.TrimSuffix(fileName, ext) // Имя файла без расширения
newFileName := fileName // Начальное имя файла
counter := 1 // Счётчик для уникальности
for {
filePath := filepath.Join(dirPath, newFileName)
if _, err := os.Stat(filePath); os.IsNotExist(err) {
break
}
newFileName = fmt.Sprintf("%s(%d)%s", name, counter, ext)
counter++
}
return newFileName
}

View File

@ -117,7 +117,7 @@ type Error interface {
} }
type Storage interface { type Storage interface {
Upload(file *multipart.FileHeader, streamerID int) error Upload(file *multipart.FileHeader, streamerID int) (string, error)
Download(filename, extension, filePath string) ([]byte, error) Download(filename, extension, filePath string) ([]byte, error)
Delete(filename, extension, filePath string) error Delete(filename, extension, filePath string) error
} }
@ -145,8 +145,13 @@ type FileRepo interface {
ctx context.Context, ctx context.Context,
streamerID int, streamerID int,
file multipart.FileHeader, file multipart.FileHeader,
fileName, extension, fileType string, extension, fileType string,
) (string, error) ) (string, error)
CheckFileExists(
ctx context.Context,
streamerID int,
fileName, extension, fileType string,
) (bool, error)
} }
type FileService interface { type FileService interface {

View File

@ -120,5 +120,9 @@ INSERT INTO files (streamer_id, file_name, file_type, extension)
VALUES VALUES
(@streamer_id, @file_name, @file_type, @extension) (@streamer_id, @file_name, @file_type, @extension)
RETURNING id; RETURNING id;
; ;`
`
var GetFileExists = `SELECT id FROM files WHERE (
streamer_id = @streamer_id AND
file_name = @file_name AND file_type = @file_type AND extension = @extension
;`

View File

@ -5,6 +5,7 @@ import (
"donat-widget/internal/model" "donat-widget/internal/model"
"donat-widget/internal/model/sql" "donat-widget/internal/model/sql"
"fmt" "fmt"
"github.com/georgysavva/scany/v2/pgxscan"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5"
"mime/multipart" "mime/multipart"
@ -29,8 +30,13 @@ func (fileRepo *RepoFile) AddNew(
ctx context.Context, ctx context.Context,
streamerID int, streamerID int,
file multipart.FileHeader, file multipart.FileHeader,
fileName, extension, fileType string, extension, fileType string,
) (string, error) { ) (string, error) {
fileName, err := fileRepo.storage.Upload(&file, streamerID)
if err != nil {
return "", err
}
args := pgx.NamedArgs{ args := pgx.NamedArgs{
"streamer_id": streamerID, "streamer_id": streamerID,
"file_name": fileName, "file_name": fileName,
@ -47,13 +53,34 @@ func (fileRepo *RepoFile) AddNew(
if !ok { if !ok {
return "", fmt.Errorf("unexpected fileID type: %T", fileIDRaw) return "", fmt.Errorf("unexpected fileID type: %T", fileIDRaw)
} }
fileID := uuid.UUID(fileIDBytes).String() fileID := uuid.UUID(fileIDBytes).String()
err = fileRepo.storage.Upload(&file, streamerID)
if err != nil {
return "", err
}
return fileID, nil return fileID, nil
} }
func (fileRepo *RepoFile) CheckFileExists(
ctx context.Context,
streamerID int,
fileName, extension, fileType string,
) (bool, error) {
args := pgx.NamedArgs{
"streamer_id": streamerID,
"file_name": fileName,
"file_type": fileType,
"extension": extension,
}
rows, err := fileRepo.db.Select(ctx, sql.GetFileExists, args)
if err != nil {
return false, err
}
var fileId [][16]uint8
err = pgxscan.ScanOne(fileId, rows)
if err != nil {
return false, nil
}
return true, nil
}

View File

@ -46,7 +46,6 @@ func (fileService *ServiceFile) AddNewFile(
ctx, ctx,
streamerID, streamerID,
file, file,
file.Filename,
fileExt, fileExt,
mimeType, mimeType,
) )