-
Notifications
You must be signed in to change notification settings - Fork 6
/
query.go
88 lines (73 loc) · 2.09 KB
/
query.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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package main
import (
"database/sql"
"encoding/hex"
"errors"
"fmt"
"strings"
"github.com/fiatjaf/go-nostr/event"
"github.com/fiatjaf/go-nostr/filter"
)
func queryEvents(filter *filter.EventFilter) (events []event.Event, err error) {
var conditions []string
var params []interface{}
if filter == nil {
err = errors.New("filter cannot be null")
return
}
if filter.ID != "" {
conditions = append(conditions, "id = ?")
params = append(params, filter.ID)
}
if filter.Author != "" {
conditions = append(conditions, "pubkey = ?")
params = append(params, filter.Author)
}
if filter.Kind != nil && *filter.Kind != 0 {
conditions = append(conditions, "kind = ?")
params = append(params, filter.Kind)
}
if filter.Authors != nil {
if len(filter.Authors) == 0 {
// authors being [] means you won't get anything
return
} else {
inkeys := make([]string, 0, len(filter.Authors))
for _, key := range filter.Authors {
// to prevent sql attack here we will check if
// these keys are valid 32byte hex
parsed, err := hex.DecodeString(key)
if err != nil || len(parsed) != 32 {
continue
}
inkeys = append(inkeys, fmt.Sprintf("'%x'", parsed))
}
conditions = append(conditions, `pubkey IN (`+strings.Join(inkeys, ",")+`)`)
}
}
if filter.TagEvent != "" {
conditions = append(conditions, relatedEventsCondition)
params = append(params, filter.TagEvent)
}
if filter.TagProfile != "" {
conditions = append(conditions, relatedEventsCondition)
params = append(params, filter.TagProfile)
}
if filter.Since != 0 {
conditions = append(conditions, "created_at > ?")
params = append(params, filter.Since)
}
if len(conditions) == 0 {
// fallback
conditions = append(conditions, "true")
}
query := db.Rebind("SELECT * FROM event WHERE " +
strings.Join(conditions, " AND ") +
" ORDER BY created_at LIMIT 100")
err = db.Select(&events, query, params...)
if err != nil && err != sql.ErrNoRows {
log.Warn().Err(err).Interface("filter", filter).Msg("failed to fetch events")
err = fmt.Errorf("failed to fetch events: %w", err)
}
return
}