Skip to content

Commit

Permalink
change channel and msg id to simple int64s
Browse files Browse the repository at this point in the history
  • Loading branch information
nicpottier committed Jul 12, 2017
1 parent 1e9a3ab commit 6879be2
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 46 deletions.
6 changes: 3 additions & 3 deletions backends/rapidpro/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func (b *backend) WasMsgSent(msg courier.Msg) (bool, error) {
defer rc.Close()

dateKey := fmt.Sprintf(sentSetName, time.Now().In(time.UTC).Format("2006_01_02"))
found, err := redis.Bool(rc.Do("sismember", dateKey, msg.ID().Int64))
found, err := redis.Bool(rc.Do("sismember", dateKey, msg.ID()))
if err != nil {
return false, err
}
Expand All @@ -107,7 +107,7 @@ func (b *backend) WasMsgSent(msg courier.Msg) (bool, error) {
}

dateKey = fmt.Sprintf(sentSetName, time.Now().Add(time.Hour*-24).In(time.UTC).Format("2006_01_02"))
found, err = redis.Bool(rc.Do("sismember", dateKey, msg.ID().Int64))
found, err = redis.Bool(rc.Do("sismember", dateKey, msg.ID()))
return found, err
}

Expand All @@ -122,7 +122,7 @@ func (b *backend) MarkOutgoingMsgComplete(msg courier.Msg, status courier.MsgSta
// mark as sent in redis as well if this was actually wired or sent
if status != nil && (status.Status() == courier.MsgSent || status.Status() == courier.MsgWired) {
dateKey := fmt.Sprintf(sentSetName, time.Now().In(time.UTC).Format("2006_01_02"))
rc.Do("sadd", dateKey, msg.ID().Int64)
rc.Do("sadd", dateKey, msg.ID())
}
}

Expand Down
12 changes: 2 additions & 10 deletions backends/rapidpro/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@ import (
"github.com/nyaruka/courier/utils"
)

// ChannelID is our SQL type for a channel's id
type ChannelID struct {
sql.NullInt64
}

// NilChannelID is our nil value for ChannelIDs
var NilChannelID = ChannelID{sql.NullInt64{Int64: 0, Valid: false}}

// getChannelFromUUID will look up the channel with the passed in UUID and channel type.
// It will return an error if the channel does not exist or is not active.
func getChannel(b *backend, channelType courier.ChannelType, channelUUID courier.ChannelUUID) (courier.Channel, error) {
Expand Down Expand Up @@ -133,7 +125,7 @@ var channelCache = make(map[courier.ChannelUUID]*DBChannel)
// DBChannel is the RapidPro specific concrete type satisfying the courier.Channel interface
type DBChannel struct {
OrgID_ OrgID `db:"org_id"`
ID_ ChannelID `db:"id"`
ID_ courier.ChannelID `db:"id"`
ChannelType_ courier.ChannelType `db:"channel_type"`
Scheme_ string `db:"scheme"`
UUID_ courier.ChannelUUID `db:"uuid"`
Expand All @@ -154,7 +146,7 @@ func (c *DBChannel) ChannelType() courier.ChannelType { return c.ChannelType_ }
func (c *DBChannel) Scheme() string { return c.Scheme_ }

// ID returns the id of this channel
func (c *DBChannel) ID() ChannelID { return c.ID_ }
func (c *DBChannel) ID() courier.ChannelID { return c.ID_ }

// UUID returns the UUID of this channel
func (c *DBChannel) UUID() courier.ChannelUUID { return c.UUID_ }
Expand Down
2 changes: 1 addition & 1 deletion backends/rapidpro/contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ WHERE u.urn = $1 AND u.contact_id = c.id AND u.org_id = $2 AND c.is_active = TRU
`

// contactForURN first tries to look up a contact for the passed in URN, if not finding one then creating one
func contactForURN(db *sqlx.DB, org OrgID, channelID ChannelID, urn courier.URN, name string) (*DBContact, error) {
func contactForURN(db *sqlx.DB, org OrgID, channelID courier.ChannelID, urn courier.URN, name string) (*DBContact, error) {
// try to look up our contact by URN
contact := DBContact{}
err := db.Get(&contact, lookupContactFromURNSQL, urn, org)
Expand Down
6 changes: 3 additions & 3 deletions backends/rapidpro/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,9 @@ type DBMsg struct {
Attachments_ []string `json:"attachments"`
ExternalID_ string `json:"external_id" db:"external_id"`

ChannelID_ ChannelID `json:"channel_id" db:"channel_id"`
ContactID_ ContactID `json:"contact_id" db:"contact_id"`
ContactURNID_ ContactURNID `json:"contact_urn_id" db:"contact_urn_id"`
ChannelID_ courier.ChannelID `json:"channel_id" db:"channel_id"`
ContactID_ ContactID `json:"contact_id" db:"contact_id"`
ContactURNID_ ContactURNID `json:"contact_urn_id" db:"contact_urn_id"`

MessageCount_ int `json:"msg_count" db:"msg_count"`
ErrorCount_ int `json:"error_count" db:"error_count"`
Expand Down
20 changes: 10 additions & 10 deletions backends/rapidpro/urn.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type ContactURNID struct {
var NilContactURNID = ContactURNID{sql.NullInt64{Int64: 0, Valid: false}}

// NewDBContactURN returns a new ContactURN object for the passed in org, contact and string urn, this is not saved to the DB yet
func newDBContactURN(org OrgID, channelID ChannelID, contactID ContactID, urn courier.URN) *DBContactURN {
func newDBContactURN(org OrgID, channelID courier.ChannelID, contactID ContactID, urn courier.URN) *DBContactURN {
offset := strings.Index(string(urn), ":")
scheme := string(urn)[:offset]
path := string(urn)[offset+1:]
Expand All @@ -34,7 +34,7 @@ ORDER BY priority desc LIMIT 1

// contactURNForURN returns the ContactURN for the passed in org and URN, creating and associating
// it with the passed in contact if necessary
func contactURNForURN(db *sqlx.DB, org OrgID, channelID ChannelID, contactID ContactID, urn courier.URN) (*DBContactURN, error) {
func contactURNForURN(db *sqlx.DB, org OrgID, channelID courier.ChannelID, contactID ContactID, urn courier.URN) (*DBContactURN, error) {
contactURN := newDBContactURN(org, channelID, contactID, urn)
err := db.Get(contactURN, selectOrgURN, org, urn)
if err != nil && err != sql.ErrNoRows {
Expand Down Expand Up @@ -98,12 +98,12 @@ func updateContactURN(db *sqlx.DB, urn *DBContactURN) error {

// DBContactURN is our struct to map to database level URNs
type DBContactURN struct {
OrgID OrgID `db:"org_id"`
ID ContactURNID `db:"id"`
URN courier.URN `db:"urn"`
Scheme string `db:"scheme"`
Path string `db:"path"`
Priority int `db:"priority"`
ChannelID ChannelID `db:"channel_id"`
ContactID ContactID `db:"contact_id"`
OrgID OrgID `db:"org_id"`
ID ContactURNID `db:"id"`
URN courier.URN `db:"urn"`
Scheme string `db:"scheme"`
Path string `db:"path"`
Priority int `db:"priority"`
ChannelID courier.ChannelID `db:"channel_id"`
ContactID ContactID `db:"contact_id"`
}
42 changes: 42 additions & 0 deletions channel.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package courier

import (
"encoding/json"
"errors"
"fmt"
"strconv"
"strings"

uuid "github.com/satori/go.uuid"
Expand Down Expand Up @@ -56,6 +59,45 @@ func NewChannelUUID(u string) (ChannelUUID, error) {
return ChannelUUID{channelUUID}, nil
}

// ChannelID is our SQL type for a channel's id
type ChannelID int64

// NewChannelID creates a new ChannelID for the passed in int64
func NewChannelID(id int64) ChannelID {
return ChannelID(id)
}

// UnmarshalText satisfies text unmarshalling so ids can be decoded from forms
func (i *ChannelID) UnmarshalText(text []byte) (err error) {
id, err := strconv.ParseInt(string(text), 10, 64)
*i = ChannelID(id)
if err != nil {
return err
}
return err
}

// UnmarshalJSON satisfies json unmarshalling so ids can be decoded from JSON
func (i *ChannelID) UnmarshalJSON(bytes []byte) (err error) {
var id int64
err = json.Unmarshal(bytes, &id)
*i = ChannelID(id)
return err
}

// MarshalJSON satisfies json marshalling so ids can be encoded to JSON
func (i *ChannelID) MarshalJSON() ([]byte, error) {
return json.Marshal(int64(*i))
}

// String satisfies the Stringer interface
func (i *ChannelID) String() string {
return fmt.Sprintf("%d", i)
}

// NilChannelID is our nil value for ChannelIDs
var NilChannelID = ChannelID(0)

// ErrChannelExpired is returned when our cached channel has outlived it's TTL
var ErrChannelExpired = errors.New("channel expired")

Expand Down
3 changes: 1 addition & 2 deletions handlers/external/external.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"io"
"net/http"
"net/url"
"strconv"
"time"

"strings"
Expand Down Expand Up @@ -184,7 +183,7 @@ func (h *handler) SendMsg(msg courier.Msg) (courier.MsgStatus, error) {

// build our request
form := map[string]string{
"id": strconv.FormatInt(msg.ID().Int64, 10),
"id": fmt.Sprintf("%d", msg.ID()),
"text": courier.GetTextAndAttachments(msg),
"to": msg.URN().Path(),
"to_no_plus": strings.TrimPrefix(msg.URN().Path(), "+"),
Expand Down
2 changes: 1 addition & 1 deletion handlers/kannel/kannel.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func (h *handler) SendMsg(msg courier.Msg) (courier.MsgStatus, error) {
return nil, fmt.Errorf("no send url set for KN channel")
}

dlrURL := fmt.Sprintf("%s%s%s/?id=%d&status=%%d", h.Server().Config().BaseURL, "/c/kn/", msg.Channel().UUID(), msg.ID().Int64)
dlrURL := fmt.Sprintf("%s%s%s/?id=%d&status=%%d", h.Server().Config().BaseURL, "/c/kn/", msg.Channel().UUID(), msg.ID())

// build our request
form := url.Values{
Expand Down
27 changes: 16 additions & 11 deletions msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package courier

import (
"bytes"
"database/sql"
"encoding/json"
"errors"
"fmt"
Expand All @@ -17,37 +16,43 @@ import (
var ErrMsgNotFound = errors.New("message not found")

// MsgID is our typing of the db int type
type MsgID struct {
sql.NullInt64
}
type MsgID int64

// NewMsgID creates a new MsgID for the passed in int64
func NewMsgID(id int64) MsgID {
return MsgID{sql.NullInt64{Int64: id, Valid: true}}
return MsgID(id)
}

// UnmarshalText satisfies text unmarshalling so ids can be decoded from forms
func (i *MsgID) UnmarshalText(text []byte) (err error) {
id, err := strconv.Atoi(string(text))
i.Int64 = int64(id)
id, err := strconv.ParseInt(string(text), 10, 64)
*i = MsgID(id)
if err != nil {
i.Valid = false
return err
}
return err
}

// UnmarshalJSON satisfies json unmarshalling so ids can be decoded from JSON
func (i *MsgID) UnmarshalJSON(bytes []byte) (err error) {
return json.Unmarshal(bytes, &i.NullInt64)
var id int64
err = json.Unmarshal(bytes, &id)
*i = MsgID(id)
return err
}

// MarshalJSON satisfies json marshalling so ids can be encoded to JSON
func (i *MsgID) MarshalJSON() ([]byte, error) {
return json.Marshal(int64(*i))
}

// String satisfies the Stringer interface
func (i *MsgID) String() string {
return fmt.Sprintf("%d", i.Int64)
return fmt.Sprintf("%d", i)
}

// NilMsgID is our nil value for MsgID
var NilMsgID = MsgID{sql.NullInt64{Int64: 0, Valid: false}}
var NilMsgID = MsgID(0)

// MsgUUID is the UUID of a message which has been received
type MsgUUID struct {
Expand Down
10 changes: 5 additions & 5 deletions sender.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,28 +158,28 @@ func (w *Sender) Send() {

// failing on a lookup isn't a halting problem but we should log it
if err != nil {
log.WithField("msgID", msg.ID().Int64).WithError(err).Warning("error looking up msg was sent")
log.WithField("msgID", msg.ID()).WithError(err).Warning("error looking up msg was sent")
}

if sent {
// if this message was already sent, create a wired status for it
status = backend.NewMsgStatusForID(msg.Channel(), msg.ID(), MsgWired)
log.WithField("msgID", msg.ID().Int64).Warning("duplicate send, marking as wired")
log.WithField("msgID", msg.ID()).Warning("duplicate send, marking as wired")
} else {
// send our message
status, err = server.SendMsg(msg)
if err != nil {
log.WithField("msgID", msg.ID().Int64).WithError(err).Info("msg errored")
log.WithField("msgID", msg.ID()).WithError(err).Info("msg errored")
} else {
log.WithField("msgID", msg.ID().Int64).Info("msg sent")
log.WithField("msgID", msg.ID()).Info("msg sent")
}
}

// record our status if we have one
if status != nil {
err = backend.WriteMsgStatus(status)
if err != nil {
log.WithField("msgID", msg.ID().Int64).WithError(err).Info("error writing msg status")
log.WithField("msgID", msg.ID()).WithError(err).Info("error writing msg status")
}
}

Expand Down

0 comments on commit 6879be2

Please sign in to comment.