/
main.go
59 lines (48 loc) · 1.3 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package message
import (
"time"
"github.com/grumblechat/server/internal/helpers"
"github.com/segmentio/ksuid"
bolt "go.etcd.io/bbolt"
)
const BoltBucketName = "messages"
func New(channelID ksuid.KSUID) *Message {
return &Message{
ID: ksuid.New(),
ChannelID: channelID,
TTL: 0,
}
}
func Decode(enc []byte) (*Message, error) {
msg := &Message{}
err := msg.Decode(enc)
return msg, err
}
// NOTE: the BoltDB bucket should have been created as part of saving the Channel
func channelBucket(tx *bolt.Tx, channelID ksuid.KSUID) *bolt.Bucket {
msgBucket := tx.Bucket([]byte(BoltBucketName))
return msgBucket.Bucket(channelID.Bytes())
}
func BatchSave(db *bolt.DB, messages []*Message) error {
return db.Batch(func(tx *bolt.Tx) error {
now := time.Now()
buckets := make(map[ksuid.KSUID]*bolt.Bucket)
// save each channel
for _, msg := range messages {
// update timestamps
msg.CreatedAt = helpers.TouchTimestamp(msg.CreatedAt, now, true)
msg.UpdatedAt = helpers.TouchTimestamp(msg.UpdatedAt, now, false)
// get channel-specific bucket
bkt, ok := buckets[msg.ChannelID]
if !ok {
bkt = channelBucket(tx, msg.ChannelID)
buckets[msg.ChannelID] = bkt
}
// persist the channel
if err := msg.bktSave(bkt); err != nil {
return err
}
}
return nil
})
}