From 55f0f5a225a016f9d14ec0738e81ee8b3dfececa Mon Sep 17 00:00:00 2001 From: bndw Date: Sun, 4 Jun 2023 17:00:43 -0700 Subject: [PATCH] feat(postgres): configurable limits Makes all hardcoded limits configurable for `type PostgresBackend` and retains the current default values. Related to #60 --- storage/postgresql/init.go | 24 ++++++++++- storage/postgresql/postgresql.go | 8 +++- storage/postgresql/query.go | 8 ++-- storage/postgresql/query_test.go | 72 ++++++++++++++++---------------- 4 files changed, 68 insertions(+), 44 deletions(-) diff --git a/storage/postgresql/init.go b/storage/postgresql/init.go index 1bd6cdc..5100d5a 100644 --- a/storage/postgresql/init.go +++ b/storage/postgresql/init.go @@ -7,6 +7,14 @@ import ( _ "github.com/lib/pq" ) +const ( + queryLimit = 100 + queryIDsLimit = 500 + queryAuthorsLimit = 500 + queryKindsLimit = 10 + queryTagsLimit = 10 +) + var _ relayer.Storage = (*PostgresBackend)(nil) func (b *PostgresBackend) Init() error { @@ -47,8 +55,20 @@ 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 + if b.QueryLimit == 0 { + b.QueryLimit = queryLimit + } + if b.QueryIDsLimit == 0 { + b.QueryIDsLimit = queryIDsLimit + } + if b.QueryAuthorsLimit == 0 { + b.QueryAuthorsLimit = queryAuthorsLimit + } + if b.QueryKindsLimit == 0 { + b.QueryKindsLimit = queryKindsLimit + } + if b.QueryTagsLimit == 0 { + b.QueryTagsLimit = queryTagsLimit } return err } diff --git a/storage/postgresql/postgresql.go b/storage/postgresql/postgresql.go index 9329b45..a8ba1c8 100644 --- a/storage/postgresql/postgresql.go +++ b/storage/postgresql/postgresql.go @@ -6,6 +6,10 @@ import ( type PostgresBackend struct { *sqlx.DB - DatabaseURL string - QueryLimit int + DatabaseURL string + QueryLimit int + QueryIDsLimit int + QueryAuthorsLimit int + QueryKindsLimit int + QueryTagsLimit int } diff --git a/storage/postgresql/query.go b/storage/postgresql/query.go index b949d2f..2b615b0 100644 --- a/storage/postgresql/query.go +++ b/storage/postgresql/query.go @@ -66,7 +66,7 @@ func (b PostgresBackend) queryEventsSql(filter *nostr.Filter, doCount bool) (str } if filter.IDs != nil { - if len(filter.IDs) > 500 { + if len(filter.IDs) > b.QueryIDsLimit { // too many ids, fail everything return "", nil, nil } @@ -89,7 +89,7 @@ func (b PostgresBackend) queryEventsSql(filter *nostr.Filter, doCount bool) (str } if filter.Authors != nil { - if len(filter.Authors) > 500 { + if len(filter.Authors) > b.QueryAuthorsLimit { // too many authors, fail everything return "", nil, nil } @@ -112,7 +112,7 @@ func (b PostgresBackend) queryEventsSql(filter *nostr.Filter, doCount bool) (str } if filter.Kinds != nil { - if len(filter.Kinds) > 10 { + if len(filter.Kinds) > b.QueryKindsLimit { // too many kinds, fail everything return "", nil, nil } @@ -139,7 +139,7 @@ func (b PostgresBackend) queryEventsSql(filter *nostr.Filter, doCount bool) (str // add these tags to the query tagQuery = append(tagQuery, values...) - if len(tagQuery) > 10 { + if len(tagQuery) > b.QueryTagsLimit { // too many tags, fail everything return "", nil, nil } diff --git a/storage/postgresql/query_test.go b/storage/postgresql/query_test.go index 9c8c08d..eda8cb7 100644 --- a/storage/postgresql/query_test.go +++ b/storage/postgresql/query_test.go @@ -10,6 +10,14 @@ import ( "github.com/stretchr/testify/assert" ) +var defaultBackend = PostgresBackend{ + QueryLimit: queryLimit, + QueryIDsLimit: queryIDsLimit, + QueryAuthorsLimit: queryAuthorsLimit, + QueryKindsLimit: queryKindsLimit, + QueryTagsLimit: queryTagsLimit, +} + func TestQueryEventsSql(t *testing.T) { var tests = []struct { name string @@ -21,23 +29,15 @@ func TestQueryEventsSql(t *testing.T) { }{ { name: "empty filter", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, 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}, + backend: defaultBackend, filter: &nostr.Filter{ Limit: 50, }, @@ -47,7 +47,7 @@ func TestQueryEventsSql(t *testing.T) { }, { name: "too large filter limit", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ Limit: 2000, }, @@ -57,7 +57,7 @@ func TestQueryEventsSql(t *testing.T) { }, { name: "ids filter", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ IDs: []string{"083ec57f36a7b39ab98a57bedab4f85355b2ee89e4b205bed58d7c3ef9edd294"}, }, @@ -70,7 +70,7 @@ func TestQueryEventsSql(t *testing.T) { }, { name: "kind filter", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ Kinds: []int{1, 2, 3}, }, @@ -83,7 +83,7 @@ func TestQueryEventsSql(t *testing.T) { }, { name: "authors filter", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ Authors: []string{"7bdef7bdebb8721f77927d0e77c66059360fa62371fdf15f3add93923a613229"}, }, @@ -97,7 +97,7 @@ func TestQueryEventsSql(t *testing.T) { // errors { name: "nil filter", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: nil, query: "", params: nil, @@ -105,7 +105,7 @@ func TestQueryEventsSql(t *testing.T) { }, { name: "too many ids", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ IDs: strSlice(501), }, @@ -116,7 +116,7 @@ func TestQueryEventsSql(t *testing.T) { }, { name: "invalid ids", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ IDs: []string{"stuff"}, }, @@ -127,7 +127,7 @@ func TestQueryEventsSql(t *testing.T) { }, { name: "too many authors", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ Authors: strSlice(501), }, @@ -138,7 +138,7 @@ func TestQueryEventsSql(t *testing.T) { }, { name: "invalid authors", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ Authors: []string{"stuff"}, }, @@ -149,7 +149,7 @@ func TestQueryEventsSql(t *testing.T) { }, { name: "too many kinds", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ Kinds: intSlice(11), }, @@ -160,7 +160,7 @@ func TestQueryEventsSql(t *testing.T) { }, { name: "no kinds", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ Kinds: []int{}, }, @@ -171,7 +171,7 @@ func TestQueryEventsSql(t *testing.T) { }, { name: "tags of empty array", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ Tags: nostr.TagMap{ "#e": []string{}, @@ -184,7 +184,7 @@ func TestQueryEventsSql(t *testing.T) { }, { name: "too many tag values", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ Tags: nostr.TagMap{ "#e": strSlice(11), @@ -242,7 +242,7 @@ func TestCountEventsSql(t *testing.T) { }{ { name: "empty filter", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{}, query: "SELECT COUNT(*) FROM event WHERE true ORDER BY created_at DESC LIMIT $1", params: []any{100}, @@ -250,7 +250,7 @@ func TestCountEventsSql(t *testing.T) { }, { name: "ids filter", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ IDs: []string{"083ec57f36a7b39ab98a57bedab4f85355b2ee89e4b205bed58d7c3ef9edd294"}, }, @@ -263,7 +263,7 @@ func TestCountEventsSql(t *testing.T) { }, { name: "kind filter", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ Kinds: []int{1, 2, 3}, }, @@ -276,7 +276,7 @@ func TestCountEventsSql(t *testing.T) { }, { name: "authors filter", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ Authors: []string{"7bdef7bdebb8721f77927d0e77c66059360fa62371fdf15f3add93923a613229"}, }, @@ -290,7 +290,7 @@ func TestCountEventsSql(t *testing.T) { // errors { name: "nil filter", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: nil, query: "", params: nil, @@ -298,7 +298,7 @@ func TestCountEventsSql(t *testing.T) { }, { name: "too many ids", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ IDs: strSlice(501), }, @@ -309,7 +309,7 @@ func TestCountEventsSql(t *testing.T) { }, { name: "invalid ids", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ IDs: []string{"stuff"}, }, @@ -320,7 +320,7 @@ func TestCountEventsSql(t *testing.T) { }, { name: "too many authors", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ Authors: strSlice(501), }, @@ -331,7 +331,7 @@ func TestCountEventsSql(t *testing.T) { }, { name: "invalid authors", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ Authors: []string{"stuff"}, }, @@ -342,7 +342,7 @@ func TestCountEventsSql(t *testing.T) { }, { name: "too many kinds", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ Kinds: intSlice(11), }, @@ -353,7 +353,7 @@ func TestCountEventsSql(t *testing.T) { }, { name: "no kinds", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ Kinds: []int{}, }, @@ -364,7 +364,7 @@ func TestCountEventsSql(t *testing.T) { }, { name: "tags of empty array", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ Tags: nostr.TagMap{ "#e": []string{}, @@ -377,7 +377,7 @@ func TestCountEventsSql(t *testing.T) { }, { name: "too many tag values", - backend: PostgresBackend{QueryLimit: 100}, + backend: defaultBackend, filter: &nostr.Filter{ Tags: nostr.TagMap{ "#e": strSlice(11),