mirror of
https://github.com/fiatjaf/khatru.git
synced 2025-03-18 05:42:19 +01:00
feat(postgres): configurable query limit
Adds a QueryLimit to `type PostgresBackend` and retains the current default value of 100. Closes #60
This commit is contained in:
parent
47b8ee106f
commit
03ecbb9e6c
@ -46,5 +46,9 @@ CREATE INDEX IF NOT EXISTS timeidx ON event (created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS kindidx ON event (kind);
|
||||
CREATE INDEX IF NOT EXISTS arbitrarytagvalues ON event USING gin (tagvalues);
|
||||
`)
|
||||
|
||||
if b.QueryLimit < 1 {
|
||||
b.QueryLimit = 100
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -7,4 +7,5 @@ import (
|
||||
type PostgresBackend struct {
|
||||
*sqlx.DB
|
||||
DatabaseURL string
|
||||
QueryLimit int
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import (
|
||||
func (b PostgresBackend) QueryEvents(ctx context.Context, filter *nostr.Filter) (ch chan *nostr.Event, err error) {
|
||||
ch = make(chan *nostr.Event)
|
||||
|
||||
query, params, err := queryEventsSql(filter, false)
|
||||
query, params, err := b.queryEventsSql(filter, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -45,7 +45,7 @@ func (b PostgresBackend) QueryEvents(ctx context.Context, filter *nostr.Filter)
|
||||
}
|
||||
|
||||
func (b PostgresBackend) CountEvents(ctx context.Context, filter *nostr.Filter) (int64, error) {
|
||||
query, params, err := queryEventsSql(filter, true)
|
||||
query, params, err := b.queryEventsSql(filter, true)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -57,7 +57,7 @@ func (b PostgresBackend) CountEvents(ctx context.Context, filter *nostr.Filter)
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func queryEventsSql(filter *nostr.Filter, doCount bool) (string, []any, error) {
|
||||
func (b PostgresBackend) queryEventsSql(filter *nostr.Filter, doCount bool) (string, []any, error) {
|
||||
var conditions []string
|
||||
var params []any
|
||||
|
||||
@ -172,8 +172,8 @@ func queryEventsSql(filter *nostr.Filter, doCount bool) (string, []any, error) {
|
||||
conditions = append(conditions, "true")
|
||||
}
|
||||
|
||||
if filter.Limit < 1 || filter.Limit > 100 {
|
||||
params = append(params, 100)
|
||||
if filter.Limit < 1 || filter.Limit > b.QueryLimit {
|
||||
params = append(params, b.QueryLimit)
|
||||
} else {
|
||||
params = append(params, filter.Limit)
|
||||
}
|
||||
|
@ -12,21 +12,52 @@ import (
|
||||
|
||||
func TestQueryEventsSql(t *testing.T) {
|
||||
var tests = []struct {
|
||||
name string
|
||||
filter *nostr.Filter
|
||||
query string
|
||||
params []any
|
||||
err error
|
||||
name string
|
||||
backend PostgresBackend
|
||||
filter *nostr.Filter
|
||||
query string
|
||||
params []any
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "empty filter",
|
||||
filter: &nostr.Filter{},
|
||||
name: "empty filter",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{},
|
||||
query: "SELECT id, pubkey, created_at, kind, tags, content, sig FROM event WHERE true ORDER BY created_at DESC LIMIT $1",
|
||||
params: []any{100},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "large query limit",
|
||||
backend: PostgresBackend{QueryLimit: 1000},
|
||||
filter: &nostr.Filter{},
|
||||
query: "SELECT id, pubkey, created_at, kind, tags, content, sig FROM event WHERE true ORDER BY created_at DESC LIMIT $1",
|
||||
params: []any{1000},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "valid filter limit",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Limit: 50,
|
||||
},
|
||||
query: "SELECT id, pubkey, created_at, kind, tags, content, sig FROM event WHERE true ORDER BY created_at DESC LIMIT $1",
|
||||
params: []any{50},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "too large filter limit",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Limit: 2000,
|
||||
},
|
||||
query: "SELECT id, pubkey, created_at, kind, tags, content, sig FROM event WHERE true ORDER BY created_at DESC LIMIT $1",
|
||||
params: []any{100},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "ids filter",
|
||||
name: "ids filter",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
IDs: []string{"083ec57f36a7b39ab98a57bedab4f85355b2ee89e4b205bed58d7c3ef9edd294"},
|
||||
},
|
||||
@ -38,7 +69,8 @@ func TestQueryEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "kind filter",
|
||||
name: "kind filter",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Kinds: []int{1, 2, 3},
|
||||
},
|
||||
@ -50,7 +82,8 @@ func TestQueryEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "authors filter",
|
||||
name: "authors filter",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Authors: []string{"7bdef7bdebb8721f77927d0e77c66059360fa62371fdf15f3add93923a613229"},
|
||||
},
|
||||
@ -63,14 +96,16 @@ func TestQueryEventsSql(t *testing.T) {
|
||||
},
|
||||
// errors
|
||||
{
|
||||
name: "nil filter",
|
||||
filter: nil,
|
||||
query: "",
|
||||
params: nil,
|
||||
err: fmt.Errorf("filter cannot be null"),
|
||||
name: "nil filter",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: nil,
|
||||
query: "",
|
||||
params: nil,
|
||||
err: fmt.Errorf("filter cannot be null"),
|
||||
},
|
||||
{
|
||||
name: "too many ids",
|
||||
name: "too many ids",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
IDs: strSlice(501),
|
||||
},
|
||||
@ -80,7 +115,8 @@ func TestQueryEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "invalid ids",
|
||||
name: "invalid ids",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
IDs: []string{"stuff"},
|
||||
},
|
||||
@ -90,7 +126,8 @@ func TestQueryEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "too many authors",
|
||||
name: "too many authors",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Authors: strSlice(501),
|
||||
},
|
||||
@ -100,7 +137,8 @@ func TestQueryEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "invalid authors",
|
||||
name: "invalid authors",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Authors: []string{"stuff"},
|
||||
},
|
||||
@ -110,7 +148,8 @@ func TestQueryEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "too many kinds",
|
||||
name: "too many kinds",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Kinds: intSlice(11),
|
||||
},
|
||||
@ -120,7 +159,8 @@ func TestQueryEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "no kinds",
|
||||
name: "no kinds",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Kinds: []int{},
|
||||
},
|
||||
@ -130,7 +170,8 @@ func TestQueryEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "tags of empty array",
|
||||
name: "tags of empty array",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Tags: nostr.TagMap{
|
||||
"#e": []string{},
|
||||
@ -142,7 +183,8 @@ func TestQueryEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "too many tag values",
|
||||
name: "too many tag values",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Tags: nostr.TagMap{
|
||||
"#e": strSlice(11),
|
||||
@ -157,7 +199,7 @@ func TestQueryEventsSql(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
query, params, err := queryEventsSql(tt.filter, false)
|
||||
query, params, err := tt.backend.queryEventsSql(tt.filter, false)
|
||||
assert.Equal(t, tt.err, err)
|
||||
if err != nil {
|
||||
return
|
||||
@ -191,21 +233,24 @@ func strSlice(n int) []string {
|
||||
|
||||
func TestCountEventsSql(t *testing.T) {
|
||||
var tests = []struct {
|
||||
name string
|
||||
filter *nostr.Filter
|
||||
query string
|
||||
params []any
|
||||
err error
|
||||
name string
|
||||
backend PostgresBackend
|
||||
filter *nostr.Filter
|
||||
query string
|
||||
params []any
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "empty filter",
|
||||
filter: &nostr.Filter{},
|
||||
query: "SELECT COUNT(*) FROM event WHERE true ORDER BY created_at DESC LIMIT $1",
|
||||
params: []any{100},
|
||||
err: nil,
|
||||
name: "empty filter",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{},
|
||||
query: "SELECT COUNT(*) FROM event WHERE true ORDER BY created_at DESC LIMIT $1",
|
||||
params: []any{100},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "ids filter",
|
||||
name: "ids filter",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
IDs: []string{"083ec57f36a7b39ab98a57bedab4f85355b2ee89e4b205bed58d7c3ef9edd294"},
|
||||
},
|
||||
@ -217,7 +262,8 @@ func TestCountEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "kind filter",
|
||||
name: "kind filter",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Kinds: []int{1, 2, 3},
|
||||
},
|
||||
@ -229,7 +275,8 @@ func TestCountEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "authors filter",
|
||||
name: "authors filter",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Authors: []string{"7bdef7bdebb8721f77927d0e77c66059360fa62371fdf15f3add93923a613229"},
|
||||
},
|
||||
@ -242,14 +289,16 @@ func TestCountEventsSql(t *testing.T) {
|
||||
},
|
||||
// errors
|
||||
{
|
||||
name: "nil filter",
|
||||
filter: nil,
|
||||
query: "",
|
||||
params: nil,
|
||||
err: fmt.Errorf("filter cannot be null"),
|
||||
name: "nil filter",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: nil,
|
||||
query: "",
|
||||
params: nil,
|
||||
err: fmt.Errorf("filter cannot be null"),
|
||||
},
|
||||
{
|
||||
name: "too many ids",
|
||||
name: "too many ids",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
IDs: strSlice(501),
|
||||
},
|
||||
@ -259,7 +308,8 @@ func TestCountEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "invalid ids",
|
||||
name: "invalid ids",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
IDs: []string{"stuff"},
|
||||
},
|
||||
@ -269,7 +319,8 @@ func TestCountEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "too many authors",
|
||||
name: "too many authors",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Authors: strSlice(501),
|
||||
},
|
||||
@ -279,7 +330,8 @@ func TestCountEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "invalid authors",
|
||||
name: "invalid authors",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Authors: []string{"stuff"},
|
||||
},
|
||||
@ -289,7 +341,8 @@ func TestCountEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "too many kinds",
|
||||
name: "too many kinds",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Kinds: intSlice(11),
|
||||
},
|
||||
@ -299,7 +352,8 @@ func TestCountEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "no kinds",
|
||||
name: "no kinds",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Kinds: []int{},
|
||||
},
|
||||
@ -309,7 +363,8 @@ func TestCountEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "tags of empty array",
|
||||
name: "tags of empty array",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Tags: nostr.TagMap{
|
||||
"#e": []string{},
|
||||
@ -321,7 +376,8 @@ func TestCountEventsSql(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "too many tag values",
|
||||
name: "too many tag values",
|
||||
backend: PostgresBackend{QueryLimit: 100},
|
||||
filter: &nostr.Filter{
|
||||
Tags: nostr.TagMap{
|
||||
"#e": strSlice(11),
|
||||
@ -336,7 +392,7 @@ func TestCountEventsSql(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
query, params, err := queryEventsSql(tt.filter, true)
|
||||
query, params, err := tt.backend.queryEventsSql(tt.filter, true)
|
||||
assert.Equal(t, tt.err, err)
|
||||
if err != nil {
|
||||
return
|
||||
|
Loading…
x
Reference in New Issue
Block a user