Skip to content

Commit

Permalink
feat: Add context on repository calls (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
allisson committed Mar 3, 2021
1 parent 8660882 commit b1460d2
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 101 deletions.
30 changes: 16 additions & 14 deletions repository.go
@@ -1,5 +1,7 @@
package postmand

import "context"

// RepositoryGetOptions contains options used in the Get methods.
type RepositoryGetOptions struct {
Filters map[string]interface{}
Expand All @@ -16,26 +18,26 @@ type RepositoryListOptions struct {

// WebhookRepository is the interface that will be used to iterate with the Webhook data.
type WebhookRepository interface {
Get(getOptions RepositoryGetOptions) (*Webhook, error)
List(listOptions RepositoryListOptions) ([]*Webhook, error)
Create(webhook *Webhook) error
Update(webhook *Webhook) error
Delete(id ID) error
Get(ctx context.Context, getOptions RepositoryGetOptions) (*Webhook, error)
List(ctx context.Context, listOptions RepositoryListOptions) ([]*Webhook, error)
Create(ctx context.Context, webhook *Webhook) error
Update(ctx context.Context, webhook *Webhook) error
Delete(ctx context.Context, id ID) error
}

// DeliveryRepository is the interface that will be used to iterate with the Delivery data.
type DeliveryRepository interface {
Get(getOptions RepositoryGetOptions) (*Delivery, error)
List(listOptions RepositoryListOptions) ([]*Delivery, error)
Create(delivery *Delivery) error
Update(delivery *Delivery) error
Delete(id ID) error
Dispatch() error
Get(ctx context.Context, getOptions RepositoryGetOptions) (*Delivery, error)
List(ctx context.Context, listOptions RepositoryListOptions) ([]*Delivery, error)
Create(ctx context.Context, delivery *Delivery) error
Update(ctx context.Context, delivery *Delivery) error
Delete(ctx context.Context, id ID) error
Dispatch(ctx context.Context) error
}

// DeliveryAttemptRepository is the interface that will be used to iterate with the DeliveryAttempt data.
type DeliveryAttemptRepository interface {
Get(getOptions RepositoryGetOptions) (*DeliveryAttempt, error)
List(listOptions RepositoryListOptions) ([]*DeliveryAttempt, error)
Create(deliveryAttempt *DeliveryAttempt) error
Get(ctx context.Context, getOptions RepositoryGetOptions) (*DeliveryAttempt, error)
List(ctx context.Context, listOptions RepositoryListOptions) ([]*DeliveryAttempt, error)
Create(ctx context.Context, deliveryAttempt *DeliveryAttempt) error
}
31 changes: 16 additions & 15 deletions repository/delivery.go
Expand Up @@ -2,6 +2,7 @@ package repository

import (
"bytes"
"context"
"database/sql"
"net/http"
"net/http/httputil"
Expand Down Expand Up @@ -75,46 +76,46 @@ type Delivery struct {
}

// Get returns postmand.Delivery by options filter.
func (d Delivery) Get(getOptions postmand.RepositoryGetOptions) (*postmand.Delivery, error) {
func (d Delivery) Get(ctx context.Context, getOptions postmand.RepositoryGetOptions) (*postmand.Delivery, error) {
delivery := postmand.Delivery{}
sql, args := getQuery("deliveries", getOptions)
err := d.db.Get(&delivery, sql, args...)
err := d.db.GetContext(ctx, &delivery, sql, args...)
return &delivery, err
}

// List returns a slice of postmand.Delivery by options filter.
func (d Delivery) List(listOptions postmand.RepositoryListOptions) ([]*postmand.Delivery, error) {
func (d Delivery) List(ctx context.Context, listOptions postmand.RepositoryListOptions) ([]*postmand.Delivery, error) {
deliveries := []*postmand.Delivery{}
sql, args := listQuery("deliveries", listOptions)
err := d.db.Select(&deliveries, sql, args...)
err := d.db.SelectContext(ctx, &deliveries, sql, args...)
return deliveries, err
}

// Create postmand.Delivery on database.
func (d Delivery) Create(delivery *postmand.Delivery) error {
func (d Delivery) Create(ctx context.Context, delivery *postmand.Delivery) error {
sql, args := insertQuery("deliveries", delivery)
_, err := d.db.Exec(sql, args...)
_, err := d.db.ExecContext(ctx, sql, args...)
return err
}

// Update postmand.Delivery on database.
func (d Delivery) Update(delivery *postmand.Delivery) error {
func (d Delivery) Update(ctx context.Context, delivery *postmand.Delivery) error {
sql, args := updateQuery("deliveries", delivery.ID, delivery)
_, err := d.db.Exec(sql, args...)
_, err := d.db.ExecContext(ctx, sql, args...)
return err
}

// Delete postmand.Delivery on database.
func (d Delivery) Delete(id postmand.ID) error {
func (d Delivery) Delete(ctx context.Context, id postmand.ID) error {
sqlStatement := `
DELETE FROM deliveries WHERE id = $1
`
_, err := d.db.Exec(sqlStatement, id)
_, err := d.db.ExecContext(ctx, sqlStatement, id)
return err
}

// Dispatch fetchs a delivery and send to url destination.
func (d Delivery) Dispatch() error {
func (d Delivery) Dispatch(ctx context.Context) error {
sqlStatement := `
SELECT
deliveries.*
Expand All @@ -139,7 +140,7 @@ func (d Delivery) Dispatch() error {

// Get delivery
delivery := postmand.Delivery{}
err = tx.Get(&delivery, sqlStatement, postmand.DeliveryStatusPending, time.Now().UTC())
err = tx.GetContext(ctx, &delivery, sqlStatement, postmand.DeliveryStatusPending, time.Now().UTC())
if err != nil {
// Skip if no result
if err == sql.ErrNoRows {
Expand All @@ -154,7 +155,7 @@ func (d Delivery) Dispatch() error {
webhook := postmand.Webhook{}
getOptions := postmand.RepositoryGetOptions{Filters: map[string]interface{}{"id": delivery.WebhookID}}
sql, args := getQuery("webhooks", getOptions)
err = tx.Get(&webhook, sql, args...)
err = tx.GetContext(ctx, &webhook, sql, args...)
if err != nil {
rollback("get webhook", tx)
return err
Expand Down Expand Up @@ -187,7 +188,7 @@ func (d Delivery) Dispatch() error {
delivery.ScheduledAt = newScheduledAt
delivery.UpdatedAt = time.Now().UTC()
sql, args = updateQuery("deliveries", delivery.ID, delivery)
_, err = tx.Exec(sql, args...)
_, err = tx.ExecContext(ctx, sql, args...)
if err != nil {
rollback("update delivery", tx)
return err
Expand All @@ -206,7 +207,7 @@ func (d Delivery) Dispatch() error {
CreatedAt: time.Now().UTC(),
}
sql, args = insertQuery("delivery_attempts", deliveryAttempt)
_, err = tx.Exec(sql, args...)
_, err = tx.ExecContext(ctx, sql, args...)
if err != nil {
rollback("create delivery attempt", tx)
return err
Expand Down
14 changes: 8 additions & 6 deletions repository/delivery_attempt.go
@@ -1,6 +1,8 @@
package repository

import (
"context"

"github.com/allisson/postmand"
"github.com/jmoiron/sqlx"
)
Expand All @@ -11,25 +13,25 @@ type DeliveryAttempt struct {
}

// Get returns postmand.DeliveryAttempt by options filter.
func (d DeliveryAttempt) Get(getOptions postmand.RepositoryGetOptions) (*postmand.DeliveryAttempt, error) {
func (d DeliveryAttempt) Get(ctx context.Context, getOptions postmand.RepositoryGetOptions) (*postmand.DeliveryAttempt, error) {
deliveryAttempt := postmand.DeliveryAttempt{}
sql, args := getQuery("delivery_attempts", getOptions)
err := d.db.Get(&deliveryAttempt, sql, args...)
err := d.db.GetContext(ctx, &deliveryAttempt, sql, args...)
return &deliveryAttempt, err
}

// List returns a slice of postmand.DeliveryAttempt by options filter.
func (d DeliveryAttempt) List(listOptions postmand.RepositoryListOptions) ([]*postmand.DeliveryAttempt, error) {
func (d DeliveryAttempt) List(ctx context.Context, listOptions postmand.RepositoryListOptions) ([]*postmand.DeliveryAttempt, error) {
deliveryAttempts := []*postmand.DeliveryAttempt{}
sql, args := listQuery("delivery_attempts", listOptions)
err := d.db.Select(&deliveryAttempts, sql, args...)
err := d.db.SelectContext(ctx, &deliveryAttempts, sql, args...)
return deliveryAttempts, err
}

// Create postmand.DeliveryAttempt on database.
func (d DeliveryAttempt) Create(deliveryAttempt *postmand.DeliveryAttempt) error {
func (d DeliveryAttempt) Create(ctx context.Context, deliveryAttempt *postmand.DeliveryAttempt) error {
sql, args := insertQuery("delivery_attempts", deliveryAttempt)
_, err := d.db.Exec(sql, args...)
_, err := d.db.ExecContext(ctx, sql, args...)
return err
}

Expand Down
27 changes: 15 additions & 12 deletions repository/delivery_attempt_test.go
@@ -1,6 +1,7 @@
package repository

import (
"context"
"testing"
"time"

Expand All @@ -21,23 +22,25 @@ func makeDeliveryAttempt() postmand.DeliveryAttempt {
}

func TestDeliveryAttempt(t *testing.T) {
ctx := context.Background()

t.Run("Create delivery attempt", func(t *testing.T) {
th := newTestHelper()
defer th.db.Close()

webhook := makeWebhook()
err := th.webhookRepository.Create(&webhook)
err := th.webhookRepository.Create(ctx, &webhook)
assert.Nil(t, err)

delivery := makeDelivery()
delivery.WebhookID = webhook.ID
err = th.deliveryRepository.Create(&delivery)
err = th.deliveryRepository.Create(ctx, &delivery)
assert.Nil(t, err)

deliveryAttempt := makeDeliveryAttempt()
deliveryAttempt.WebhookID = webhook.ID
deliveryAttempt.DeliveryID = delivery.ID
err = th.deliveryAttemptRepository.Create(&deliveryAttempt)
err = th.deliveryAttemptRepository.Create(ctx, &deliveryAttempt)
assert.Nil(t, err)
})

Expand All @@ -46,22 +49,22 @@ func TestDeliveryAttempt(t *testing.T) {
defer th.db.Close()

webhook := makeWebhook()
err := th.webhookRepository.Create(&webhook)
err := th.webhookRepository.Create(ctx, &webhook)
assert.Nil(t, err)

delivery := makeDelivery()
delivery.WebhookID = webhook.ID
err = th.deliveryRepository.Create(&delivery)
err = th.deliveryRepository.Create(ctx, &delivery)
assert.Nil(t, err)

deliveryAttempt := makeDeliveryAttempt()
deliveryAttempt.WebhookID = webhook.ID
deliveryAttempt.DeliveryID = delivery.ID
err = th.deliveryAttemptRepository.Create(&deliveryAttempt)
err = th.deliveryAttemptRepository.Create(ctx, &deliveryAttempt)
assert.Nil(t, err)

options := postmand.RepositoryGetOptions{Filters: map[string]interface{}{"id": deliveryAttempt.ID}}
deliveryAttemptFromRepository, err := th.deliveryAttemptRepository.Get(options)
deliveryAttemptFromRepository, err := th.deliveryAttemptRepository.Get(ctx, options)
assert.Nil(t, err)
assert.Equal(t, deliveryAttempt.ID, deliveryAttemptFromRepository.ID)
})
Expand All @@ -71,28 +74,28 @@ func TestDeliveryAttempt(t *testing.T) {
defer th.db.Close()

webhook := makeWebhook()
err := th.webhookRepository.Create(&webhook)
err := th.webhookRepository.Create(ctx, &webhook)
assert.Nil(t, err)

delivery := makeDelivery()
delivery.WebhookID = webhook.ID
err = th.deliveryRepository.Create(&delivery)
err = th.deliveryRepository.Create(ctx, &delivery)
assert.Nil(t, err)

deliveryAttempt1 := makeDeliveryAttempt()
deliveryAttempt1.WebhookID = webhook.ID
deliveryAttempt1.DeliveryID = delivery.ID
err = th.deliveryAttemptRepository.Create(&deliveryAttempt1)
err = th.deliveryAttemptRepository.Create(ctx, &deliveryAttempt1)
assert.Nil(t, err)

deliveryAttempt2 := makeDeliveryAttempt()
deliveryAttempt2.WebhookID = webhook.ID
deliveryAttempt2.DeliveryID = delivery.ID
err = th.deliveryAttemptRepository.Create(&deliveryAttempt2)
err = th.deliveryAttemptRepository.Create(ctx, &deliveryAttempt2)
assert.Nil(t, err)

options := postmand.RepositoryListOptions{Limit: 1, Offset: 0, OrderBy: "created_at", Order: "DESC"}
deliveryAttempts, err := th.deliveryAttemptRepository.List(options)
deliveryAttempts, err := th.deliveryAttemptRepository.List(ctx, options)
assert.Nil(t, err)
assert.Len(t, deliveryAttempts, 1)
assert.Equal(t, deliveryAttempt2.ID, deliveryAttempts[0].ID)
Expand Down

0 comments on commit b1460d2

Please sign in to comment.