88 lines
3.3 KiB
Go
88 lines
3.3 KiB
Go
package mailstore
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
|
|
pgtable "galaxy/mail/internal/adapters/postgres/jet/mail/table"
|
|
"galaxy/mail/internal/domain/common"
|
|
deliverydomain "galaxy/mail/internal/domain/delivery"
|
|
"galaxy/mail/internal/domain/idempotency"
|
|
"galaxy/mail/internal/service/acceptgenericdelivery"
|
|
)
|
|
|
|
// GenericAcceptance returns a handle that satisfies
|
|
// acceptgenericdelivery.Store. Generic and auth acceptance share the same
|
|
// idempotency / delivery read paths but the write input types differ — the
|
|
// adapter avoids a method-name conflict on Store.CreateAcceptance.
|
|
func (store *Store) GenericAcceptance() *GenericAcceptanceStore {
|
|
return &GenericAcceptanceStore{store: store}
|
|
}
|
|
|
|
// GenericAcceptanceStore is the acceptgenericdelivery.Store handle returned
|
|
// by Store.GenericAcceptance. It defers to the umbrella store for shared
|
|
// reads.
|
|
type GenericAcceptanceStore struct {
|
|
store *Store
|
|
}
|
|
|
|
var _ acceptgenericdelivery.Store = (*GenericAcceptanceStore)(nil)
|
|
|
|
// CreateAcceptance writes one generic-delivery acceptance write set inside
|
|
// one BEGIN … COMMIT transaction. Idempotency races surface as
|
|
// acceptgenericdelivery.ErrConflict.
|
|
func (handle *GenericAcceptanceStore) CreateAcceptance(ctx context.Context, input acceptgenericdelivery.CreateAcceptanceInput) error {
|
|
if handle == nil || handle.store == nil {
|
|
return errors.New("create generic acceptance: nil store")
|
|
}
|
|
if ctx == nil {
|
|
return errors.New("create generic acceptance: nil context")
|
|
}
|
|
if err := input.Validate(); err != nil {
|
|
return fmt.Errorf("create generic acceptance: %w", err)
|
|
}
|
|
|
|
return handle.store.withTx(ctx, "create generic acceptance", func(ctx context.Context, tx *sql.Tx) error {
|
|
first := input.FirstAttempt
|
|
if err := insertDelivery(ctx, tx, input.Delivery, input.Idempotency, input.Idempotency.ExpiresAt, &first); err != nil {
|
|
if isUniqueViolation(err) {
|
|
return acceptgenericdelivery.ErrConflict
|
|
}
|
|
return fmt.Errorf("create generic acceptance: insert delivery: %w", err)
|
|
}
|
|
if err := insertAttempt(ctx, tx, input.FirstAttempt); err != nil {
|
|
return fmt.Errorf("create generic acceptance: insert first attempt: %w", err)
|
|
}
|
|
if input.DeliveryPayload != nil {
|
|
payload, err := marshalDeliveryPayload(*input.DeliveryPayload)
|
|
if err != nil {
|
|
return fmt.Errorf("create generic acceptance: %w", err)
|
|
}
|
|
payloadStmt := pgtable.DeliveryPayloads.INSERT(
|
|
pgtable.DeliveryPayloads.DeliveryID,
|
|
pgtable.DeliveryPayloads.Payload,
|
|
).VALUES(
|
|
input.Delivery.DeliveryID.String(),
|
|
payload,
|
|
)
|
|
payloadQuery, payloadArgs := payloadStmt.Sql()
|
|
if _, err := tx.ExecContext(ctx, payloadQuery, payloadArgs...); err != nil {
|
|
return fmt.Errorf("create generic acceptance: insert delivery payload: %w", err)
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// GetIdempotency forwards to the umbrella store.
|
|
func (handle *GenericAcceptanceStore) GetIdempotency(ctx context.Context, source deliverydomain.Source, key common.IdempotencyKey) (idempotency.Record, bool, error) {
|
|
return handle.store.GetIdempotency(ctx, source, key)
|
|
}
|
|
|
|
// GetDelivery forwards to the umbrella store.
|
|
func (handle *GenericAcceptanceStore) GetDelivery(ctx context.Context, deliveryID common.DeliveryID) (deliverydomain.Delivery, bool, error) {
|
|
return handle.store.GetDelivery(ctx, deliveryID)
|
|
}
|