Add store-agnostic message ID format
Allow to query the network ID and entity from the message ID regardless of the underlying store used.
This commit is contained in:
parent
021a4c9474
commit
83a4590acc
@ -313,13 +313,13 @@ func (dc *downstreamConn) advanceMessageWithID(msg *irc.Message, id string) {
|
|||||||
|
|
||||||
// ackMsgID acknowledges that a message has been received.
|
// ackMsgID acknowledges that a message has been received.
|
||||||
func (dc *downstreamConn) ackMsgID(id string) {
|
func (dc *downstreamConn) ackMsgID(id string) {
|
||||||
netName, entity, _, _, err := parseMsgID(id)
|
netID, entity, _, err := parseMsgID(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dc.logger.Printf("failed to ACK message ID %q: %v", id, err)
|
dc.logger.Printf("failed to ACK message ID %q: %v", id, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
network := dc.user.getNetwork(netName)
|
network := dc.user.getNetworkByID(netID)
|
||||||
if network == nil {
|
if network == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
19
msgstore.go
19
msgstore.go
@ -1,6 +1,9 @@
|
|||||||
package soju
|
package soju
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gopkg.in/irc.v3"
|
"gopkg.in/irc.v3"
|
||||||
@ -18,3 +21,19 @@ type messageStore interface {
|
|||||||
LoadLatestID(network *network, entity, id string, limit int) ([]*irc.Message, error)
|
LoadLatestID(network *network, entity, id string, limit int) ([]*irc.Message, error)
|
||||||
Append(network *network, entity string, msg *irc.Message) (id string, err error)
|
Append(network *network, entity string, msg *irc.Message) (id string, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func formatMsgID(netID int64, entity, extra string) string {
|
||||||
|
return fmt.Sprintf("%v %v %v", netID, entity, extra)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseMsgID(s string) (netID int64, entity, extra string, err error) {
|
||||||
|
l := strings.SplitN(s, " ", 3)
|
||||||
|
if len(l) != 3 {
|
||||||
|
return 0, "", "", fmt.Errorf("invalid message ID %q: expected 3 fields", s)
|
||||||
|
}
|
||||||
|
netID, err = strconv.ParseInt(l[0], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, "", "", fmt.Errorf("invalid message ID %q: %v", s, err)
|
||||||
|
}
|
||||||
|
return netID, l[1], l[2], nil
|
||||||
|
}
|
||||||
|
@ -36,39 +36,45 @@ func (ms *fsMessageStore) logPath(network *network, entity string, t time.Time)
|
|||||||
return filepath.Join(ms.root, escapeFilename.Replace(network.GetName()), escapeFilename.Replace(entity), filename)
|
return filepath.Join(ms.root, escapeFilename.Replace(network.GetName()), escapeFilename.Replace(entity), filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseMsgID(s string) (network, entity string, t time.Time, offset int64, err error) {
|
func parseFSMsgID(s string) (netID int64, entity string, t time.Time, offset int64, err error) {
|
||||||
var year, month, day int
|
netID, entity, extra, err := parseMsgID(s)
|
||||||
_, err = fmt.Sscanf(s, "%s %s %04d-%02d-%02d %d", &network, &entity, &year, &month, &day, &offset)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", time.Time{}, 0, fmt.Errorf("invalid message ID: %v", err)
|
return 0, "", time.Time{}, 0, err
|
||||||
}
|
|
||||||
t = time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.Local)
|
|
||||||
return network, entity, t, offset, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatMsgID(network, entity string, t time.Time, offset int64) string {
|
var year, month, day int
|
||||||
|
_, err = fmt.Sscanf(extra, "%04d-%02d-%02d %d", &year, &month, &day, &offset)
|
||||||
|
if err != nil {
|
||||||
|
return 0, "", time.Time{}, 0, fmt.Errorf("invalid message ID %q: %v", s, err)
|
||||||
|
}
|
||||||
|
t = time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.Local)
|
||||||
|
return netID, entity, t, offset, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatFSMsgID(netID int64, entity string, t time.Time, offset int64) string {
|
||||||
year, month, day := t.Date()
|
year, month, day := t.Date()
|
||||||
return fmt.Sprintf("%s %s %04d-%02d-%02d %d", network, entity, year, month, day, offset)
|
extra := fmt.Sprintf("%04d-%02d-%02d %d", year, month, day, offset)
|
||||||
|
return formatMsgID(netID, entity, extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nextMsgID queries the message ID for the next message to be written to f.
|
// nextMsgID queries the message ID for the next message to be written to f.
|
||||||
func nextMsgID(network *network, entity string, t time.Time, f *os.File) (string, error) {
|
func nextFSMsgID(network *network, entity string, t time.Time, f *os.File) (string, error) {
|
||||||
offset, err := f.Seek(0, io.SeekEnd)
|
offset, err := f.Seek(0, io.SeekEnd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return formatMsgID(network.GetName(), entity, t, offset), nil
|
return formatFSMsgID(network.ID, entity, t, offset), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ms *fsMessageStore) LastMsgID(network *network, entity string, t time.Time) (string, error) {
|
func (ms *fsMessageStore) LastMsgID(network *network, entity string, t time.Time) (string, error) {
|
||||||
p := ms.logPath(network, entity, t)
|
p := ms.logPath(network, entity, t)
|
||||||
fi, err := os.Stat(p)
|
fi, err := os.Stat(p)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return formatMsgID(network.GetName(), entity, t, -1), nil
|
return formatFSMsgID(network.ID, entity, t, -1), nil
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return formatMsgID(network.GetName(), entity, t, fi.Size()-1), nil
|
return formatFSMsgID(network.ID, entity, t, fi.Size()-1), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ms *fsMessageStore) Append(network *network, entity string, msg *irc.Message) (string, error) {
|
func (ms *fsMessageStore) Append(network *network, entity string, msg *irc.Message) (string, error) {
|
||||||
@ -113,7 +119,7 @@ func (ms *fsMessageStore) Append(network *network, entity string, msg *irc.Messa
|
|||||||
ms.files[entity] = f
|
ms.files[entity] = f
|
||||||
}
|
}
|
||||||
|
|
||||||
msgID, err := nextMsgID(network, entity, t, f)
|
msgID, err := nextFSMsgID(network, entity, t, f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to generate message ID: %v", err)
|
return "", fmt.Errorf("failed to generate message ID: %v", err)
|
||||||
}
|
}
|
||||||
@ -373,13 +379,14 @@ func (ms *fsMessageStore) LoadLatestID(network *network, entity, id string, limi
|
|||||||
var afterTime time.Time
|
var afterTime time.Time
|
||||||
var afterOffset int64
|
var afterOffset int64
|
||||||
if id != "" {
|
if id != "" {
|
||||||
var idNet, idEntity string
|
var idNet int64
|
||||||
|
var idEntity string
|
||||||
var err error
|
var err error
|
||||||
idNet, idEntity, afterTime, afterOffset, err = parseMsgID(id)
|
idNet, idEntity, afterTime, afterOffset, err = parseFSMsgID(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if idNet != network.GetName() || idEntity != entity {
|
if idNet != network.ID || idEntity != entity {
|
||||||
return nil, fmt.Errorf("cannot find message ID: message ID doesn't match network/entity")
|
return nil, fmt.Errorf("cannot find message ID: message ID doesn't match network/entity")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user