Skip to content

Commit

Permalink
Mongodb support (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
danhhuynh25029 authored Jan 5, 2025
1 parent d944046 commit 64a0a38
Show file tree
Hide file tree
Showing 7 changed files with 309 additions and 0 deletions.
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ require (
github.com/opensearch-project/opensearch-go/v4 v4.3.0
github.com/rs/zerolog v1.33.0
github.com/stretchr/testify v1.10.0
go.mongodb.org/mongo-driver/v2 v2.0.0-beta2
golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d
golang.org/x/text v0.21.0
)
Expand Down Expand Up @@ -80,9 +81,13 @@ require (
github.com/tidwall/gjson v1.18.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/xdg/scram v1.0.5 // indirect
github.com/xdg/stringprep v1.0.3 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel v1.32.0 // indirect
go.opentelemetry.io/otel/metric v1.32.0 // indirect
Expand Down
27 changes: 27 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,24 @@ github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/wI2L/jsondiff v0.6.0 h1:zrsH3FbfVa3JO9llxrcDy/XLkYPLgoMX6Mz3T2PP2AI=
github.com/wI2L/jsondiff v0.6.0/go.mod h1:D6aQ5gKgPF9g17j+E9N7aasmU1O+XvfmWm1y8UMmNpw=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/xdg/scram v1.0.5 h1:TuS0RFmt5Is5qm9Tm2SoD89OPqe4IRiFtyFY4iwWXsw=
github.com/xdg/scram v1.0.5/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v1.0.3 h1:cmL5Enob4W83ti/ZHuZLuKD/xqJfus4fVPwE+/BDm+4=
github.com/xdg/stringprep v1.0.3/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mongodb.org/mongo-driver/v2 v2.0.0-beta2 h1:PRtbRKwblE8ZfI8qOhofcjn9y8CmKZI7trS5vDMeJX0=
go.mongodb.org/mongo-driver/v2 v2.0.0-beta2/go.mod h1:UGLb3ZgEzaY0cCbJpH9UFt9B6gEXiTPzsnJS38nBeoU=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U=
Expand All @@ -270,6 +281,7 @@ go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY=
golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
Expand All @@ -282,20 +294,25 @@ golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86h
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand All @@ -305,14 +322,21 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Expand All @@ -322,8 +346,11 @@ golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/gonum v0.7.0 h1:Hdks0L0hgznZLG9nzXb8vZ0rRvqNvAcgAp84y7Mwkgw=
Expand Down
14 changes: 14 additions & 0 deletions mongo/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package mongo

import (
"context"
"github.com/nbd-wtf/go-nostr"
"go.mongodb.org/mongo-driver/v2/bson"
)

func (m *MongoDBBackend) DeleteEvent(ctx context.Context, event *nostr.Event) error {
_, err := m.Client.Database("events").Collection("events").DeleteOne(ctx, bson.M{
"id": event.ID,
})
return err
}
72 changes: 72 additions & 0 deletions mongo/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package mongo

import (
"context"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
"log"
)

const (
queryLimit = 100
queryIDsLimit = 500
queryAuthorsLimit = 500
queryKindsLimit = 10
queryTagsLimit = 10
)

var indexs = []mongo.IndexModel{
{
Keys: bson.M{"id": 1},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.M{"pubkey": 1},
Options: options.Index(),
},
{
Keys: bson.M{"createdat": -1},
Options: options.Index(),
},
{
Keys: bson.M{"kind": 1},
Options: options.Index(),
},
{
Keys: bson.D{{"kind", 1}, {"createdat", -1}},
Options: options.Index(),
},
}

func (m *MongoDBBackend) Init() error {
m.ctx = context.Background()
client, err := mongo.Connect(options.Client().ApplyURI(m.DatabaseURL))
if err != nil {
return err
}
collection := client.Database("events").Collection("events")
for _, index := range indexs {
_, err = collection.Indexes().CreateOne(context.TODO(), index)
if err != nil {
log.Fatal(err)
}
}
m.Client = client
if m.QueryAuthorsLimit == 0 {
m.QueryAuthorsLimit = queryAuthorsLimit
}
if m.QueryLimit == 0 {
m.QueryLimit = queryLimit
}
if m.QueryIDsLimit == 0 {
m.QueryIDsLimit = queryIDsLimit
}
if m.QueryKindsLimit == 0 {
m.QueryKindsLimit = queryKindsLimit
}
if m.QueryTagsLimit == 0 {
m.QueryTagsLimit = queryTagsLimit
}
return nil
}
21 changes: 21 additions & 0 deletions mongo/mongo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package mongo

import (
"context"
"go.mongodb.org/mongo-driver/v2/mongo"
)

type MongoDBBackend struct {
*mongo.Client
ctx context.Context
DatabaseURL string
QueryLimit int
QueryIDsLimit int
QueryAuthorsLimit int
QueryKindsLimit int
QueryTagsLimit int
}

func (m *MongoDBBackend) Close() {
m.Client.Disconnect(m.ctx)
}
152 changes: 152 additions & 0 deletions mongo/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package mongo

import (
"context"
"encoding/json"
"errors"
"github.com/nbd-wtf/go-nostr"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo/options"
"log"
)

var (
ErrTooManyIDs = errors.New("too many ids")
ErrTooManyAuthors = errors.New("too many authors")
ErrTooManyKinds = errors.New("too many kinds")
ErrEmptyTagSet = errors.New("empty tag set")
ErrTooManyTagValues = errors.New("too many tag values")
)

func (m *MongoDBBackend) QueryEvents(ctx context.Context, filter nostr.Filter) (chan *nostr.Event, error) {

conditions, projections, err := m.queryEvents(filter, false)
if err != nil {
return nil, err
}
limit := filter.Limit
if filter.Limit < 1 || filter.Limit > m.QueryLimit {
limit = m.QueryLimit
}
cursor, err := m.Client.Database("events").Collection("events").Find(ctx, conditions, options.Find().SetProjection(projections).SetLimit(int64(limit)))
if err != nil {
return nil, err
}

ch := make(chan *nostr.Event)
go func() {
defer cursor.Close(ctx)
defer close(ch)
for cursor.Next(ctx) {
var evt nostr.Event
var raw bson.M
if err := cursor.Decode(&raw); err != nil {
log.Printf("Error decoding event: %v", err)
return
}
evt.ID = raw["id"].(string)
evt.Kind = int(raw["kind"].(int32))
evt.Content = raw["content"].(string)
evt.Sig = raw["sig"].(string)
evt.PubKey = raw["pubkey"].(string)
jsonData, err := json.Marshal(raw["tags"])
if err != nil {
log.Printf("Error encoding tags: %v", err)
return
}
if err := evt.Tags.Scan(jsonData); err != nil {
log.Printf("Error parsing tags: %v", err)
return
}
evt.CreatedAt = nostr.Timestamp(raw["createdat"].(int64))
select {
case ch <- &evt:
case <-ctx.Done():
return
}
}
}()
return ch, nil
}

func (m *MongoDBBackend) CountEvents(ctx context.Context, filter nostr.Filter) (int64, error) {
var count int64
conditions, projection, err := m.queryEvents(filter, true)
if err != nil {
return 0, err
}
if projection == nil {
count, err = m.Client.Database("events").Collection("events").CountDocuments(ctx, conditions)
if err != nil {
return 0, err
}
}
return count, nil
}

func (m *MongoDBBackend) queryEvents(filter nostr.Filter, doCount bool) (bson.D, bson.D, error) {
var conditions bson.D
if len(filter.IDs) > 0 {
if len(filter.IDs) > m.QueryIDsLimit {
// too many ids, fail everything
return nil, nil, ErrTooManyIDs
}
conditions = append(conditions, bson.E{Key: "id", Value: bson.M{"$in": filter.IDs}})
}
if len(filter.Authors) > 0 {
if len(filter.Authors) > m.QueryAuthorsLimit {
// too many authors, fail everything
return nil, nil, ErrTooManyAuthors
}
conditions = append(conditions, bson.E{Key: "pubkey", Value: bson.M{"$in": filter.Authors}})
}

if len(filter.Kinds) > 0 {
if len(filter.Kinds) > m.QueryKindsLimit {
// too many kinds, fail everything
return nil, nil, ErrTooManyKinds
}
conditions = append(conditions, bson.E{Key: "kind", Value: bson.M{"$in": filter.Kinds}})
}

totalTags := 0
for _, values := range filter.Tags {
if len(values) == 0 {
// any tag set to [] is wrong
return nil, nil, ErrEmptyTagSet
}
var tags bson.A
for _, tagValue := range values {
tags = append(tags, tagValue)
}

conditions = append(conditions, bson.E{Key: "colors", Value: bson.M{"$in": tags}})

totalTags += len(values)
if totalTags > m.QueryTagsLimit {
// too many tags, fail everything
return nil, nil, ErrTooManyTagValues
}
}
if filter.Since != nil {
conditions = append(conditions, bson.E{Key: "since", Value: bson.M{"$gte": filter.Since}})
}
if filter.Until != nil {
conditions = append(conditions, bson.E{Key: "until", Value: bson.M{"$lte": filter.Until}})
}
if filter.Search != "" {
conditions = append(conditions, bson.E{Key: "search", Value: bson.M{"$regex": filter.Search}})
}

if len(conditions) == 0 {
conditions = append(conditions, bson.E{})
}

var projections bson.D
if doCount {
projections = nil
} else {
projections = bson.D{{"id", 1}, {"pubkey", 1}, {"createdat", 1}, {"kind", 1}, {"tags", 1}, {"content", 1}, {"sig", 1}}
}
return conditions, projections, nil
}
18 changes: 18 additions & 0 deletions mongo/save.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package mongo

import (
"context"
"github.com/fiatjaf/eventstore"
"github.com/nbd-wtf/go-nostr"
)

func (m *MongoDBBackend) SaveEvent(ctx context.Context, event *nostr.Event) error {
result, err := m.Client.Database("events").Collection("events").InsertOne(ctx, event)
if err != nil {
return err
}
if result.InsertedID == nil {
return eventstore.ErrDupEvent
}
return err
}

0 comments on commit 64a0a38

Please sign in to comment.