Skip to content

Commit deff72a

Browse files
Merge pull request #198 from kaleido-io/do-not-mutate-scoped-filter
do not mutate scoped filter
2 parents c6f3114 + 3961443 commit deff72a

2 files changed

Lines changed: 109 additions & 6 deletions

File tree

pkg/dbsql/crud.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,17 +271,19 @@ func (c *CrudBase[T]) idField() string {
271271
}
272272

273273
func (c *CrudBase[T]) idFilter(id string) sq.Eq {
274-
var filter sq.Eq
275-
if c.ScopedFilter != nil {
276-
filter = c.ScopedFilter()
277-
} else {
278-
filter = sq.Eq{}
279-
}
274+
filter := sq.Eq{}
275+
280276
if c.ReadTableAlias != "" {
281277
filter[fmt.Sprintf("%s.%s", c.ReadTableAlias, c.GetIDField())] = id
282278
} else {
283279
filter[c.idField()] = id
284280
}
281+
if c.ScopedFilter != nil {
282+
// copy the fields from the scoped filter without modifying the original
283+
for k, v := range c.ScopedFilter() {
284+
filter[k] = v
285+
}
286+
}
285287
return filter
286288
}
287289

pkg/dbsql/crud_test.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"github.com/hyperledger/firefly-common/pkg/fftypes"
3434
"github.com/hyperledger/firefly-common/pkg/log"
3535
"github.com/stretchr/testify/assert"
36+
"github.com/stretchr/testify/require"
3637
)
3738

3839
type TestCRUDable struct {
@@ -569,6 +570,106 @@ func TestCRUDWithDBEnd2End(t *testing.T) {
569570

570571
}
571572

573+
func TestCRUDScoped(t *testing.T) {
574+
log.SetLevel("trace")
575+
576+
sql, done := newSQLiteTestProvider(t)
577+
defer done()
578+
ctx := context.Background()
579+
580+
collection := newCRUDCollection(sql.db, "ns1")
581+
scopedCollection := collection.Scoped(sq.Eq{"field1": "scope1"})
582+
583+
bobScope1 := &TestCRUDable{
584+
ResourceBase: ResourceBase{
585+
ID: fftypes.NewUUID(),
586+
},
587+
Name: ptrTo("bob"),
588+
NS: ptrTo("ns1"),
589+
Field1: ptrTo("scope1"),
590+
Field2: fftypes.NewFFBigInt(12345),
591+
Field3: fftypes.JSONAnyPtr(`{"some":"stuff"}`),
592+
Field4: ptrTo(int64(12345)),
593+
Field5: ptrTo(true),
594+
}
595+
err := collection.Insert(ctx, bobScope1, collection.postCommit)
596+
assert.NoError(t, err)
597+
598+
bobScope2 := &TestCRUDable{
599+
ResourceBase: ResourceBase{
600+
ID: fftypes.NewUUID(),
601+
},
602+
Name: ptrTo("bob"),
603+
NS: ptrTo("ns1"),
604+
Field1: ptrTo("scope2"),
605+
Field2: fftypes.NewFFBigInt(12345),
606+
Field3: fftypes.JSONAnyPtr(`{"some":"stuff"}`),
607+
Field4: ptrTo(int64(12345)),
608+
Field5: ptrTo(true),
609+
}
610+
err = collection.Insert(ctx, bobScope2, collection.postCommit)
611+
assert.NoError(t, err)
612+
613+
aliceScope1 := &TestCRUDable{
614+
ResourceBase: ResourceBase{
615+
ID: fftypes.NewUUID(),
616+
},
617+
Name: ptrTo("bob"),
618+
NS: ptrTo("ns1"),
619+
Field1: ptrTo("scope1"),
620+
Field2: fftypes.NewFFBigInt(12345),
621+
Field3: fftypes.JSONAnyPtr(`{"some":"stuff"}`),
622+
Field4: ptrTo(int64(12345)),
623+
Field5: ptrTo(true),
624+
}
625+
err = collection.Insert(ctx, aliceScope1, collection.postCommit)
626+
assert.NoError(t, err)
627+
628+
aliceScope2 := &TestCRUDable{
629+
ResourceBase: ResourceBase{
630+
ID: fftypes.NewUUID(),
631+
},
632+
Name: ptrTo("alice"),
633+
NS: ptrTo("ns1"),
634+
Field1: ptrTo("scope2"),
635+
Field2: fftypes.NewFFBigInt(12345),
636+
Field3: fftypes.JSONAnyPtr(`{"some":"stuff"}`),
637+
Field4: ptrTo(int64(12345)),
638+
Field5: ptrTo(true),
639+
}
640+
err = collection.Insert(ctx, aliceScope2, collection.postCommit)
641+
assert.NoError(t, err)
642+
643+
//Get many only returns scope1 rows
644+
cs, _, err := scopedCollection.GetMany(ctx, CRUDableQueryFactory.NewFilter(ctx).And())
645+
assert.NoError(t, err)
646+
assert.Len(t, cs, 2)
647+
assert.Equal(t, bobScope1.ID.String(), cs[1].ID.String())
648+
assert.Equal(t, aliceScope1.ID.String(), cs[0].ID.String())
649+
650+
//Get many on the non scoped collection only returns all rows
651+
cs2, _, err := collection.GetMany(ctx, CRUDableQueryFactory.NewFilter(ctx).And())
652+
assert.NoError(t, err)
653+
assert.Len(t, cs2, 4)
654+
655+
//Get by id fails if the id is not in the scoped collection
656+
_, err = scopedCollection.GetByID(ctx, aliceScope2.ID.String(), FailIfNotFound)
657+
assert.Regexp(t, "FF00164", err)
658+
659+
//Get by id succeeds if the id is in the scoped collection
660+
cs1, err := scopedCollection.GetByID(ctx, aliceScope1.ID.String(), FailIfNotFound)
661+
assert.NoError(t, err)
662+
assert.Equal(t, aliceScope1.ID.String(), cs1.ID.String())
663+
664+
//Get many still returns all scope1 rows
665+
cs, _, err = scopedCollection.GetMany(ctx, CRUDableQueryFactory.NewFilter(ctx).And())
666+
assert.NoError(t, err)
667+
require.Len(t, cs, 2)
668+
assert.Equal(t, bobScope1.ID.String(), cs[1].ID.String())
669+
assert.Equal(t, aliceScope1.ID.String(), cs[0].ID.String())
670+
671+
}
672+
572673
func TestHistoryExampleNoNSOrUpdateColumn(t *testing.T) {
573674
log.SetLevel("trace")
574675

0 commit comments

Comments
 (0)