package data import ( "context" "fmt" "github.com/go-kratos/kratos/v2/log" "gorm.io/gorm" ) // ShareRepo implements share link persistence operations using GORM. type ShareRepo struct { data *Data log *log.Helper } // NewShareRepo creates a new ShareRepo. func NewShareRepo(data *Data, logger log.Logger) *ShareRepo { return &ShareRepo{ data: data, log: log.NewHelper(logger), } } // Create inserts a new share link record. func (r *ShareRepo) Create(ctx context.Context, share *ShareLinkPO) error { return r.data.DB(ctx).Create(share).Error } // GetByToken retrieves a share link by its token. Returns nil if not found. func (r *ShareRepo) GetByToken(ctx context.Context, token string) (*ShareLinkPO, error) { return r.queryOne(ctx, "token = ?", token) } // GetByID retrieves a share link by its ID. Returns nil if not found. func (r *ShareRepo) GetByID(ctx context.Context, id string) (*ShareLinkPO, error) { return r.queryOne(ctx, "id = ?", id) } // Delete removes a share link by ID and creator. Returns error if not found. func (r *ShareRepo) Delete(ctx context.Context, id string, createdBy string) error { result := r.data.DB(ctx). Where("id = ? AND created_by = ?", id, createdBy). Delete(&ShareLinkPO{}) if result.Error != nil { return fmt.Errorf("failed to delete share link: %w", result.Error) } if result.RowsAffected == 0 { return fmt.Errorf("share link not found or not owned by user") } return nil } // IncrementDownloadCount atomically increments the download count for the given token. func (r *ShareRepo) IncrementDownloadCount(ctx context.Context, token string) error { result := r.data.DB(ctx).Model(&ShareLinkPO{}). Where("token = ?", token). UpdateColumn("download_count", gorm.Expr("download_count + 1")) if result.Error != nil { return fmt.Errorf("failed to increment download count: %w", result.Error) } return nil } // ListByResource retrieves all share links for a given resource, ordered by created_at descending. func (r *ShareRepo) ListByResource(ctx context.Context, resourceType string, resourceID string) ([]ShareLinkPO, error) { var links []ShareLinkPO err := r.data.DB(ctx). Where("resource_type = ? AND resource_id = ?", resourceType, resourceID). Order("created_at DESC"). Find(&links).Error if err != nil { return nil, fmt.Errorf("failed to list share links: %w", err) } return links, nil } func (r *ShareRepo) queryOne(ctx context.Context, query string, args ...interface{}) (*ShareLinkPO, error) { var share ShareLinkPO err := r.data.DB(ctx).Where(query, args...).First(&share).Error if err != nil { if isRecordNotFound(err) { return nil, nil } return nil, fmt.Errorf("failed to query share link: %w", err) } return &share, nil }