asset_store.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package postgres
  2. import (
  3. "context"
  4. "github.com/jackc/pgx/v5"
  5. )
  6. type ManagedAssetRecord struct {
  7. ID string
  8. PublicID string
  9. AssetType string
  10. AssetCode string
  11. Version string
  12. Title *string
  13. SourceMode string
  14. StorageProvider string
  15. ObjectKey *string
  16. PublicURL string
  17. FileName *string
  18. ContentType *string
  19. FileSizeBytes *int64
  20. ChecksumSHA256 *string
  21. Status string
  22. MetadataJSONB map[string]any
  23. }
  24. type CreateManagedAssetParams struct {
  25. PublicID string
  26. AssetType string
  27. AssetCode string
  28. Version string
  29. Title *string
  30. SourceMode string
  31. StorageProvider string
  32. ObjectKey *string
  33. PublicURL string
  34. FileName *string
  35. ContentType *string
  36. FileSizeBytes *int64
  37. ChecksumSHA256 *string
  38. Status string
  39. MetadataJSONB map[string]any
  40. }
  41. func (s *Store) CreateManagedAsset(ctx context.Context, tx pgx.Tx, params CreateManagedAssetParams) (*ManagedAssetRecord, error) {
  42. row := tx.QueryRow(ctx, `
  43. INSERT INTO managed_assets (
  44. asset_public_id, asset_type, asset_code, version, title, source_mode, storage_provider,
  45. object_key, public_url, file_name, content_type, file_size_bytes, checksum_sha256, status, metadata_jsonb
  46. ) VALUES (
  47. $1, $2, $3, $4, $5, $6, $7,
  48. $8, $9, $10, $11, $12, $13, $14, COALESCE($15, '{}'::jsonb)
  49. )
  50. RETURNING id, asset_public_id, asset_type, asset_code, version, title, source_mode, storage_provider,
  51. object_key, public_url, file_name, content_type, file_size_bytes, checksum_sha256, status, metadata_jsonb
  52. `,
  53. params.PublicID, params.AssetType, params.AssetCode, params.Version, params.Title, params.SourceMode, params.StorageProvider,
  54. params.ObjectKey, params.PublicURL, params.FileName, params.ContentType, params.FileSizeBytes, params.ChecksumSHA256, params.Status, params.MetadataJSONB,
  55. )
  56. return scanManagedAsset(row)
  57. }
  58. func (s *Store) ListManagedAssets(ctx context.Context, limit int) ([]ManagedAssetRecord, error) {
  59. if limit <= 0 {
  60. limit = 20
  61. }
  62. rows, err := s.pool.Query(ctx, `
  63. SELECT id, asset_public_id, asset_type, asset_code, version, title, source_mode, storage_provider,
  64. object_key, public_url, file_name, content_type, file_size_bytes, checksum_sha256, status, metadata_jsonb
  65. FROM managed_assets
  66. ORDER BY created_at DESC
  67. LIMIT $1
  68. `, limit)
  69. if err != nil {
  70. return nil, err
  71. }
  72. defer rows.Close()
  73. var items []ManagedAssetRecord
  74. for rows.Next() {
  75. record, err := scanManagedAsset(rows)
  76. if err != nil {
  77. return nil, err
  78. }
  79. items = append(items, *record)
  80. }
  81. return items, rows.Err()
  82. }
  83. func (s *Store) GetManagedAssetByPublicID(ctx context.Context, publicID string) (*ManagedAssetRecord, error) {
  84. row := s.pool.QueryRow(ctx, `
  85. SELECT id, asset_public_id, asset_type, asset_code, version, title, source_mode, storage_provider,
  86. object_key, public_url, file_name, content_type, file_size_bytes, checksum_sha256, status, metadata_jsonb
  87. FROM managed_assets
  88. WHERE asset_public_id = $1
  89. `, publicID)
  90. return scanManagedAsset(row)
  91. }
  92. type managedAssetScanner interface {
  93. Scan(dest ...any) error
  94. }
  95. func scanManagedAsset(scanner managedAssetScanner) (*ManagedAssetRecord, error) {
  96. var record ManagedAssetRecord
  97. err := scanner.Scan(
  98. &record.ID,
  99. &record.PublicID,
  100. &record.AssetType,
  101. &record.AssetCode,
  102. &record.Version,
  103. &record.Title,
  104. &record.SourceMode,
  105. &record.StorageProvider,
  106. &record.ObjectKey,
  107. &record.PublicURL,
  108. &record.FileName,
  109. &record.ContentType,
  110. &record.FileSizeBytes,
  111. &record.ChecksumSHA256,
  112. &record.Status,
  113. &record.MetadataJSONB,
  114. )
  115. if err != nil {
  116. if err == pgx.ErrNoRows {
  117. return nil, nil
  118. }
  119. return nil, err
  120. }
  121. if record.MetadataJSONB == nil {
  122. record.MetadataJSONB = map[string]any{}
  123. }
  124. return &record, nil
  125. }