package file import ( "context" "donat-widget/internal/model" "donat-widget/internal/model/sql" "fmt" "github.com/georgysavva/scany/v2/pgxscan" "github.com/google/uuid" "github.com/jackc/pgx/v5" "mime/multipart" "strconv" ) func New( db model.Db, storage model.Storage, ) *RepoFile { return &RepoFile{ db: db, storage: storage, } } type RepoFile struct { db model.Db storage model.Storage } func (fileRepo *RepoFile) AddNew( ctx context.Context, streamerID int, file multipart.FileHeader, extension, fileType string, entity string, ) (string, error) { fileName, err := fileRepo.storage.Upload(&file, streamerID) if err != nil { return "", err } sizeInKB := file.Size / 1024 args := pgx.NamedArgs{ "streamer_id": streamerID, "file_name": fileName, "file_type": fileType, "extension": extension, "size": sizeInKB, "entity": entity, } fileIDRaw, err := fileRepo.db.Insert(ctx, sql.AddNewFile, args) if err != nil { return "", err } fileIDBytes, ok := fileIDRaw.([16]uint8) if !ok { return "", fmt.Errorf("unexpected fileID type: %T", fileIDRaw) } fileID := uuid.UUID(fileIDBytes).String() return fileID, nil } func (fileRepo *RepoFile) GetByID( ctx context.Context, fileID string, ) ([]byte, string, error) { args := pgx.NamedArgs{ "id": fileID, } row := fileRepo.db.SelectOne(ctx, sql.FileById, args) if row == nil { return nil, "", fmt.Errorf("file %s not found", fileID) } var fileName string var streamerID int var fileType string err := row.Scan(&fileName, &streamerID, &fileType) if err != nil { return nil, "", fmt.Errorf("file %s not found", fileID) } fileContent, err := fileRepo.storage.Download(fileName, strconv.Itoa(streamerID)) if err != nil { return nil, "", fmt.Errorf("error downloading file: %v", err) } return fileContent, fileType, nil } func (fileRepo *RepoFile) WidgetsFiles( ctx context.Context, fileType string, streamerID int, ) ([]*model.DataFile, error) { args := pgx.NamedArgs{ "streamer_id": streamerID, "entity": "widget", } var stmt string if fileType == "audio" { stmt = sql.AudioFilesWidgets } else { stmt = sql.ImageFilesWidgets } rows, err := fileRepo.db.Select(ctx, stmt, args) if err != nil { return nil, fmt.Errorf("error retrieving file info: %v", err) } defer rows.Close() var files []*model.DataFile err = pgxscan.ScanAll(&files, rows) if len(files) == 0 { return nil, nil } return files, nil } func (fileRepo *RepoFile) GetFileInfoById( ctx context.Context, fileID string, ) (model.DataFile, error) { args := pgx.NamedArgs{ "id": fileID, } row := fileRepo.db.SelectOne(ctx, sql.FileInfoById, args) var dataFile model.DataFile err := row.Scan( &dataFile.ID, &dataFile.FileType, &dataFile.FileName, &dataFile.Extension, &dataFile.StreamerID, &dataFile.Entity, &dataFile.CreatedAt, &dataFile.Size, ) if err != nil { return model.DataFile{}, fmt.Errorf("error retrieving file info: %v", err) } return dataFile, nil }