Files
cmroubao/backend-api/internal/repository/sqlite/asset_repository.go
T

101 lines
2.1 KiB
Go

package sqlite
import (
"context"
"database/sql"
"cmroubao/backend-api/internal/domain"
"cmroubao/backend-api/internal/usecase"
)
const assetUploadOperation = "UPLOAD_TASK_REFERENCE"
func (s *Store) CreateAssetIdempotent(
ctx context.Context,
candidate domain.Asset,
idempotencyKey string,
requestHash string,
) (domain.Asset, bool, error) {
tx, err := s.db.BeginTx(ctx, nil)
if err != nil {
return domain.Asset{}, false, repositoryFailure(err)
}
defer func() { _ = tx.Rollback() }()
existingHash, resourceID, found, err := lookupIdempotency(
ctx,
tx,
candidate.CreatorSubject,
assetUploadOperation,
idempotencyKey,
)
if err != nil {
return domain.Asset{}, false, err
}
if found {
if existingHash != requestHash {
return domain.Asset{}, false, usecase.ErrIdempotencyConflict
}
existing, err := getAssetByID(
ctx,
tx,
candidate.CreatorSubject,
resourceID,
)
if err != nil {
return domain.Asset{}, false, err
}
if err := tx.Commit(); err != nil {
return domain.Asset{}, false, repositoryFailure(err)
}
return existing, false, nil
}
_, err = tx.ExecContext(
ctx,
`INSERT INTO assets (
id, creator_subject, purpose, media_type, size_bytes,
sha256, storage_key, created_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
candidate.ID,
candidate.CreatorSubject,
candidate.Purpose,
candidate.MediaType,
candidate.SizeBytes,
candidate.SHA256,
candidate.StorageKey,
formatTimestamp(candidate.CreatedAt),
)
if err != nil {
return domain.Asset{}, false, repositoryFailure(err)
}
if err := insertIdempotency(
ctx,
tx,
candidate.CreatorSubject,
assetUploadOperation,
idempotencyKey,
requestHash,
"ASSET",
candidate.ID,
candidate.CreatedAt,
); err != nil {
return domain.Asset{}, false, err
}
if err := tx.Commit(); err != nil {
return domain.Asset{}, false, repositoryFailure(err)
}
return candidate, true, nil
}
func (s *Store) GetAsset(
ctx context.Context,
creatorSubject string,
assetID string,
) (domain.Asset, error) {
return getAssetByID(ctx, s.db, creatorSubject, assetID)
}
var _ usecase.AssetRepository = (*Store)(nil)
var _ queryRower = (*sql.Tx)(nil)