fake-sms/internal/query/get_outbox.go

124 lines
2.3 KiB
Go

package query
import (
"context"
"strings"
"time"
"forge.cadoles.com/Cadoles/fake-sms/internal/model"
"forge.cadoles.com/Cadoles/fake-sms/internal/storm"
stormdb "github.com/asdine/storm/v3"
"github.com/asdine/storm/v3/q"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/cqrs"
"gitlab.com/wpetit/goweb/middleware/container"
)
type OutboxSearch struct {
Recipient string
Body string
After time.Time
Before time.Time
}
type GetOutboxRequest struct {
OrderBy string
Limit int
Skip int
Reverse bool
Search *OutboxSearch
}
type OutboxData struct {
Messages []*model.SMS
}
func HandleGetOutbox(ctx context.Context, qry cqrs.Query) (interface{}, error) {
req, ok := qry.Request().(*GetOutboxRequest)
if !ok {
return nil, cqrs.ErrUnexpectedRequest
}
ctn, err := container.From(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not retrieve service container")
}
db, err := storm.From(ctn)
if err != nil {
return nil, errors.Wrap(err, "could not retrieve storm service")
}
messages := make([]*model.SMS, 0)
var query stormdb.Query
if req.Search != nil {
matchers := make([]q.Matcher, 0)
if req.Search.Body != "" {
matchers = append(matchers, q.Or(
q.Re("Body", req.Search.Body),
))
}
query = db.Select(matchers...)
} else {
query = db.Select()
}
if req.OrderBy != "" {
query = query.OrderBy(req.OrderBy)
} else {
query = query.OrderBy("SentAt").Reverse()
}
if req.Reverse {
query = query.Reverse()
}
if req.Limit != 0 {
query = query.Limit(req.Limit)
}
if req.Skip != 0 {
query = query.Limit(req.Skip)
}
if err := query.Find(&messages); err != nil {
if err == storm.ErrNotFound {
return &OutboxData{messages}, nil
}
return nil, errors.Wrap(err, "could not retrieve emails")
}
if req.Search == nil {
return &OutboxData{messages}, nil
}
filtered := make([]*model.SMS, 0, len(messages))
for _, sms := range messages {
match := true
if req.Search.Recipient != "" {
match = strings.Contains(sms.Recipient, req.Search.Recipient)
}
if !req.Search.After.IsZero() && !sms.SentAt.After(req.Search.After) {
match = false
}
if !req.Search.Before.IsZero() && !sms.SentAt.Before(req.Search.Before) {
match = false
}
if match {
filtered = append(filtered, sms)
}
}
return &OutboxData{filtered}, nil
}