a big bundle of conversions and other changes.

This commit is contained in:
fiatjaf
2025-04-15 17:13:57 -03:00
parent f493293be2
commit 2b5b646a62
92 changed files with 852 additions and 2136 deletions

View File

@@ -1,11 +1,9 @@
package bluge
import (
"context"
"fiatjaf.com/nostr"
)
func (b *BlugeBackend) DeleteEvent(ctx context.Context, evt *nostr.Event) error {
return b.writer.Delete(eventIdentifier(evt.ID))
func (b *BlugeBackend) DeleteEvent(id nostr.ID) error {
return b.writer.Delete(eventIdentifier(id))
}

View File

@@ -1,6 +1,8 @@
package bluge
import "encoding/hex"
import (
"fiatjaf.com/nostr"
)
const (
contentField = "c"
@@ -9,7 +11,7 @@ const (
pubkeyField = "p"
)
type eventIdentifier string
type eventIdentifier nostr.ID
const idField = "i"
@@ -18,6 +20,5 @@ func (id eventIdentifier) Field() string {
}
func (id eventIdentifier) Term() []byte {
v, _ := hex.DecodeString(string(id))
return v
return id[:]
}

View File

@@ -2,108 +2,96 @@ package bluge
import (
"context"
"encoding/hex"
"fmt"
"iter"
"strconv"
"fiatjaf.com/nostr"
"github.com/blugelabs/bluge"
"github.com/blugelabs/bluge/search"
"fiatjaf.com/nostr"
)
func (b *BlugeBackend) QueryEvents(ctx context.Context, filter nostr.Filter) (chan *nostr.Event, error) {
ch := make(chan *nostr.Event)
if len(filter.Search) < 2 {
close(ch)
return ch, nil
}
reader, err := b.writer.Reader()
if err != nil {
close(ch)
return nil, fmt.Errorf("unable to open reader: %w", err)
}
searchQ := bluge.NewMatchQuery(filter.Search)
searchQ.SetField(contentField)
var q bluge.Query = searchQ
complicatedQuery := bluge.NewBooleanQuery().AddMust(searchQ)
if len(filter.Kinds) > 0 {
eitherKind := bluge.NewBooleanQuery()
eitherKind.SetMinShould(1)
for _, kind := range filter.Kinds {
kindQ := bluge.NewTermQuery(strconv.Itoa(kind))
kindQ.SetField(kindField)
eitherKind.AddShould(kindQ)
func (b *BlugeBackend) QueryEvents(filter nostr.Filter) iter.Seq[nostr.Event] {
return func(yield func(nostr.Event) bool) {
if len(filter.Search) < 2 {
return
}
complicatedQuery.AddMust(eitherKind)
q = complicatedQuery
}
if len(filter.Authors) > 0 {
eitherPubkey := bluge.NewBooleanQuery()
eitherPubkey.SetMinShould(1)
for _, pubkey := range filter.Authors {
if len(pubkey) != 64 {
continue
reader, err := b.writer.Reader()
if err != nil {
return
}
searchQ := bluge.NewMatchQuery(filter.Search)
searchQ.SetField(contentField)
var q bluge.Query = searchQ
complicatedQuery := bluge.NewBooleanQuery().AddMust(searchQ)
if len(filter.Kinds) > 0 {
eitherKind := bluge.NewBooleanQuery()
eitherKind.SetMinShould(1)
for _, kind := range filter.Kinds {
kindQ := bluge.NewTermQuery(strconv.Itoa(int(kind)))
kindQ.SetField(kindField)
eitherKind.AddShould(kindQ)
}
pubkeyQ := bluge.NewTermQuery(pubkey[56:])
pubkeyQ.SetField(pubkeyField)
eitherPubkey.AddShould(pubkeyQ)
complicatedQuery.AddMust(eitherKind)
q = complicatedQuery
}
complicatedQuery.AddMust(eitherPubkey)
q = complicatedQuery
}
if filter.Since != nil || filter.Until != nil {
min := 0.0
if filter.Since != nil {
min = float64(*filter.Since)
if len(filter.Authors) > 0 {
eitherPubkey := bluge.NewBooleanQuery()
eitherPubkey.SetMinShould(1)
for _, pubkey := range filter.Authors {
if len(pubkey) != 64 {
continue
}
pubkeyQ := bluge.NewTermQuery(pubkey.Hex()[56:])
pubkeyQ.SetField(pubkeyField)
eitherPubkey.AddShould(pubkeyQ)
}
complicatedQuery.AddMust(eitherPubkey)
q = complicatedQuery
}
max := float64(nostr.Now())
if filter.Until != nil {
max = float64(*filter.Until)
if filter.Since != nil || filter.Until != nil {
min := 0.0
if filter.Since != nil {
min = float64(*filter.Since)
}
max := float64(nostr.Now())
if filter.Until != nil {
max = float64(*filter.Until)
}
dateRangeQ := bluge.NewNumericRangeInclusiveQuery(min, max, true, true)
dateRangeQ.SetField(createdAtField)
complicatedQuery.AddMust(dateRangeQ)
q = complicatedQuery
}
dateRangeQ := bluge.NewNumericRangeInclusiveQuery(min, max, true, true)
dateRangeQ.SetField(createdAtField)
complicatedQuery.AddMust(dateRangeQ)
q = complicatedQuery
}
limit := 40
if filter.Limit != 0 {
limit = filter.Limit
if filter.Limit > 150 {
limit = 150
limit := 40
if filter.Limit != 0 {
limit = filter.Limit
if filter.Limit > 150 {
limit = 150
}
}
}
req := bluge.NewTopNSearch(limit, q)
req := bluge.NewTopNSearch(limit, q)
dmi, err := reader.Search(context.Background(), req)
if err != nil {
close(ch)
reader.Close()
return ch, fmt.Errorf("error executing search: %w", err)
}
dmi, err := reader.Search(context.Background(), req)
if err != nil {
reader.Close()
return
}
go func() {
defer reader.Close()
defer close(ch)
var next *search.DocumentMatch
for next, err = dmi.Next(); next != nil; next, err = dmi.Next() {
next.VisitStoredFields(func(field string, value []byte) bool {
id := hex.EncodeToString(value)
rawch, err := b.RawEventStore.QueryEvents(ctx, nostr.Filter{IDs: []string{id}})
if err != nil {
return false
}
for evt := range rawch {
ch <- evt
for evt := range b.RawEventStore.QueryEvents(nostr.Filter{IDs: []nostr.ID{nostr.ID(value)}}) {
yield(evt)
}
return false
})
@@ -111,7 +99,5 @@ func (b *BlugeBackend) QueryEvents(ctx context.Context, filter nostr.Filter) (ch
if err != nil {
return
}
}()
return ch, nil
}
}

View File

@@ -4,29 +4,24 @@ import (
"context"
"fmt"
"fiatjaf.com/nostr"
"fiatjaf.com/nostr/eventstore"
"fiatjaf.com/nostr/eventstore/internal"
"fiatjaf.com/nostr"
)
func (b *BlugeBackend) ReplaceEvent(ctx context.Context, evt *nostr.Event) error {
func (b *BlugeBackend) ReplaceEvent(ctx context.Context, evt nostr.Event) error {
b.Lock()
defer b.Unlock()
filter := nostr.Filter{Limit: 1, Kinds: []int{evt.Kind}, Authors: []string{evt.PubKey}}
filter := nostr.Filter{Limit: 1, Kinds: []uint16{evt.Kind}, Authors: []nostr.PubKey{evt.PubKey}}
if nostr.IsAddressableKind(evt.Kind) {
filter.Tags = nostr.TagMap{"d": []string{evt.Tags.GetD()}}
}
ch, err := b.QueryEvents(ctx, filter)
if err != nil {
return fmt.Errorf("failed to query before replacing: %w", err)
}
shouldStore := true
for previous := range ch {
for previous := range b.QueryEvents(filter) {
if internal.IsOlder(previous, evt) {
if err := b.DeleteEvent(ctx, previous); err != nil {
if err := b.DeleteEvent(previous.ID); err != nil {
return fmt.Errorf("failed to delete event for replacing: %w", err)
}
} else {

View File

@@ -1,23 +1,22 @@
package bluge
import (
"context"
"fmt"
"strconv"
"github.com/blugelabs/bluge"
"fiatjaf.com/nostr"
"github.com/blugelabs/bluge"
)
func (b *BlugeBackend) SaveEvent(ctx context.Context, evt *nostr.Event) error {
func (b *BlugeBackend) SaveEvent(evt nostr.Event) error {
id := eventIdentifier(evt.ID)
doc := &bluge.Document{
bluge.NewKeywordFieldBytes(id.Field(), id.Term()).Sortable().StoreValue(),
}
doc.AddField(bluge.NewTextField(contentField, evt.Content))
doc.AddField(bluge.NewTextField(kindField, strconv.Itoa(evt.Kind)))
doc.AddField(bluge.NewTextField(pubkeyField, evt.PubKey[56:]))
doc.AddField(bluge.NewTextField(kindField, strconv.Itoa(int(evt.Kind))))
doc.AddField(bluge.NewTextField(pubkeyField, evt.PubKey.Hex()[56:]))
doc.AddField(bluge.NewNumericField(createdAtField, float64(evt.CreatedAt)))
if err := b.writer.Update(doc.ID(), doc); err != nil {