50 lines
1.5 KiB
Go
50 lines
1.5 KiB
Go
package store
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
type UploadRecord struct {
|
|
UploadID string
|
|
Binding []byte
|
|
Asset []byte
|
|
Grant []byte
|
|
ObjectKey string
|
|
Bucket string
|
|
State string
|
|
CreatedAt time.Time
|
|
CompletedAt *time.Time
|
|
}
|
|
|
|
func (s *Store) LoadUpload(uploadID string) (UploadRecord, error) {
|
|
if uploadID == "" {
|
|
return UploadRecord{}, errors.New("upload ID is required")
|
|
}
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
var record UploadRecord
|
|
var createdAt string
|
|
var completedAt sql.NullString
|
|
err := s.db.QueryRow(`SELECT uploads.upload_id,binding,asset,grant,object_key,d.bucket,
|
|
CASE WHEN state='granted' AND EXISTS(SELECT 1 FROM upload_notifications n WHERE n.upload_id=uploads.upload_id) THEN 'uploaded' ELSE state END,
|
|
created_at,completed_at FROM uploads JOIN upload_destinations d ON d.upload_id=uploads.upload_id WHERE uploads.upload_id=?`, uploadID).Scan(&record.UploadID, &record.Binding, &record.Asset, &record.Grant, &record.ObjectKey, &record.Bucket, &record.State, &createdAt, &completedAt)
|
|
if err != nil {
|
|
return UploadRecord{}, fmt.Errorf("load upload: %w", err)
|
|
}
|
|
record.CreatedAt, err = time.Parse(time.RFC3339Nano, createdAt)
|
|
if err != nil {
|
|
return UploadRecord{}, fmt.Errorf("parse upload created_at: %w", err)
|
|
}
|
|
if completedAt.Valid {
|
|
parsed, err := time.Parse(time.RFC3339Nano, completedAt.String)
|
|
if err != nil {
|
|
return UploadRecord{}, fmt.Errorf("parse upload completed_at: %w", err)
|
|
}
|
|
record.CompletedAt = &parsed
|
|
}
|
|
return record, nil
|
|
}
|