Replace old infrastructure layer with Kratos-style data layer: - data.go: GORM connection, transaction support, Wire ProviderSet, PO models - file_repo.go: All 12 S3 operations (upload, download, multipart, presign, buckets) - folder_repo.go: GORM queries including recursive CTE for descendant files - file_meta_repo.go: CRUD + move operations for file metadata - share_repo.go: CRUD + increment download count for share links Deleted old infrastructure/database, infrastructure/repository, infrastructure/s3. Kept infrastructure/grpc for later integration.
91 lines
2.5 KiB
Go
91 lines
2.5 KiB
Go
package data
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/go-kratos/kratos/v2/log"
|
|
)
|
|
|
|
// FileMetaRepo implements file metadata persistence operations using GORM.
|
|
type FileMetaRepo struct {
|
|
data *Data
|
|
log *log.Helper
|
|
}
|
|
|
|
// NewFileMetaRepo creates a new FileMetaRepo.
|
|
func NewFileMetaRepo(data *Data, logger log.Logger) *FileMetaRepo {
|
|
return &FileMetaRepo{
|
|
data: data,
|
|
log: log.NewHelper(logger),
|
|
}
|
|
}
|
|
|
|
// Create inserts a new file metadata record.
|
|
func (r *FileMetaRepo) Create(ctx context.Context, file *FileMetaPO) error {
|
|
return r.data.DB(ctx).Create(file).Error
|
|
}
|
|
|
|
// GetByID retrieves file metadata by ID. Returns nil if not found.
|
|
func (r *FileMetaRepo) GetByID(ctx context.Context, id string) (*FileMetaPO, error) {
|
|
var file FileMetaPO
|
|
err := r.data.DB(ctx).Where("id = ?", id).First(&file).Error
|
|
if err != nil {
|
|
if isRecordNotFound(err) {
|
|
return nil, nil
|
|
}
|
|
return nil, fmt.Errorf("failed to get file meta: %w", err)
|
|
}
|
|
return &file, nil
|
|
}
|
|
|
|
// GetByFolder retrieves all files in a folder, ordered by name.
|
|
func (r *FileMetaRepo) GetByFolder(ctx context.Context, folderID string) ([]FileMetaPO, error) {
|
|
var files []FileMetaPO
|
|
err := r.data.DB(ctx).
|
|
Where("folder_id = ?", folderID).
|
|
Order("name").
|
|
Find(&files).Error
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get files by folder: %w", err)
|
|
}
|
|
return files, nil
|
|
}
|
|
|
|
// Move updates the folder_id of a file (moves it to another folder).
|
|
func (r *FileMetaRepo) Move(ctx context.Context, fileID string, targetFolderID string, ownerID string) error {
|
|
result := r.data.DB(ctx).Model(&FileMetaPO{}).
|
|
Where("id = ? AND owner_id = ?", fileID, ownerID).
|
|
Updates(map[string]interface{}{
|
|
"folder_id": targetFolderID,
|
|
"updated_at": gormNow(),
|
|
})
|
|
if result.Error != nil {
|
|
return fmt.Errorf("failed to move file: %w", result.Error)
|
|
}
|
|
if result.RowsAffected == 0 {
|
|
return fmt.Errorf("file not found or not owned by user")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Delete removes a file metadata record by ID and ownerID.
|
|
func (r *FileMetaRepo) Delete(ctx context.Context, id string, ownerID string) error {
|
|
result := r.data.DB(ctx).
|
|
Where("id = ? AND owner_id = ?", id, ownerID).
|
|
Delete(&FileMetaPO{})
|
|
if result.Error != nil {
|
|
return fmt.Errorf("failed to delete file meta: %w", result.Error)
|
|
}
|
|
if result.RowsAffected == 0 {
|
|
return fmt.Errorf("file not found or not owned by user")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// gormNow returns the current UTC time for use in GORM updates.
|
|
func gormNow() time.Time {
|
|
return time.Now().UTC()
|
|
}
|