143 lines
2.8 KiB
Go
143 lines
2.8 KiB
Go
package badger
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"encoding/hex"
|
|
|
|
"github.com/dgraph-io/badger/v4"
|
|
"github.com/fiatjaf/eventstore"
|
|
"github.com/nbd-wtf/go-nostr"
|
|
)
|
|
|
|
const (
|
|
rawEventStorePrefix byte = 0
|
|
indexCreatedAtPrefix byte = 1
|
|
indexIdPrefix byte = 2
|
|
indexKindPrefix byte = 3
|
|
indexPubkeyPrefix byte = 4
|
|
indexPubkeyKindPrefix byte = 5
|
|
indexTagPrefix byte = 6
|
|
)
|
|
|
|
var _ eventstore.Store = (*BadgerBackend)(nil)
|
|
|
|
type BadgerBackend struct {
|
|
Path string
|
|
MaxLimit int
|
|
|
|
*badger.DB
|
|
seq *badger.Sequence
|
|
}
|
|
|
|
func (b *BadgerBackend) Init() error {
|
|
db, err := badger.Open(badger.DefaultOptions(b.Path))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
b.DB = db
|
|
b.seq, err = db.GetSequence([]byte("events"), 1000)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if b.MaxLimit == 0 {
|
|
b.MaxLimit = 500
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (b BadgerBackend) Close() {
|
|
b.DB.Close()
|
|
b.seq.Release()
|
|
}
|
|
|
|
func (b BadgerBackend) Serial() []byte {
|
|
v, _ := b.seq.Next()
|
|
vb := make([]byte, 5)
|
|
vb[0] = rawEventStorePrefix
|
|
binary.BigEndian.PutUint32(vb[1:], uint32(v))
|
|
return vb
|
|
}
|
|
|
|
func getIndexKeysForEvent(evt *nostr.Event, idx []byte) [][]byte {
|
|
keys := make([][]byte, 0, 18)
|
|
|
|
// indexes
|
|
{
|
|
// ~ by id
|
|
id, _ := hex.DecodeString(evt.ID)
|
|
k := make([]byte, 1+32+4)
|
|
k[0] = indexIdPrefix
|
|
copy(k[1:], id)
|
|
copy(k[1+32:], idx)
|
|
keys = append(keys, k)
|
|
}
|
|
|
|
{
|
|
// ~ by pubkey+date
|
|
pubkey, _ := hex.DecodeString(evt.PubKey)
|
|
k := make([]byte, 1+32+4+4)
|
|
k[0] = indexPubkeyPrefix
|
|
copy(k[1:], pubkey)
|
|
binary.BigEndian.PutUint32(k[1+32:], uint32(evt.CreatedAt))
|
|
copy(k[1+32+4:], idx)
|
|
keys = append(keys, k)
|
|
}
|
|
|
|
{
|
|
// ~ by kind+date
|
|
k := make([]byte, 1+2+4+4)
|
|
k[0] = indexKindPrefix
|
|
binary.BigEndian.PutUint16(k[1:], uint16(evt.Kind))
|
|
binary.BigEndian.PutUint32(k[1+2:], uint32(evt.CreatedAt))
|
|
copy(k[1+2+4:], idx)
|
|
keys = append(keys, k)
|
|
}
|
|
|
|
{
|
|
// ~ by pubkey+kind+date
|
|
pubkey, _ := hex.DecodeString(evt.PubKey)
|
|
k := make([]byte, 1+32+2+4+4)
|
|
k[0] = indexPubkeyKindPrefix
|
|
copy(k[1:], pubkey)
|
|
binary.BigEndian.PutUint16(k[1+32:], uint16(evt.Kind))
|
|
binary.BigEndian.PutUint32(k[1+32+2:], uint32(evt.CreatedAt))
|
|
copy(k[1+32+2+4:], idx)
|
|
keys = append(keys, k)
|
|
}
|
|
|
|
// ~ by tagvalue+date
|
|
for _, tag := range evt.Tags {
|
|
if len(tag) < 2 || len(tag[0]) != 1 || len(tag[1]) == 0 || len(tag[1]) > 100 {
|
|
continue
|
|
}
|
|
|
|
var v []byte
|
|
if vb, _ := hex.DecodeString(tag[1]); len(vb) == 32 {
|
|
// store value as bytes
|
|
v = vb
|
|
} else {
|
|
v = []byte(tag[1])
|
|
}
|
|
|
|
k := make([]byte, 1+len(v)+4+4)
|
|
k[0] = indexTagPrefix
|
|
copy(k[1:], v)
|
|
binary.BigEndian.PutUint32(k[1+len(v):], uint32(evt.CreatedAt))
|
|
copy(k[1+len(v)+4:], idx)
|
|
keys = append(keys, k)
|
|
}
|
|
|
|
{
|
|
// ~ by date only
|
|
k := make([]byte, 1+4+4)
|
|
k[0] = indexCreatedAtPrefix
|
|
binary.BigEndian.PutUint32(k[1:], uint32(evt.CreatedAt))
|
|
copy(k[1+4:], idx)
|
|
keys = append(keys, k)
|
|
}
|
|
|
|
return keys
|
|
}
|