Skip to content

Commit

Permalink
Merge pull request #94 from hyperledger/dynamic-scoping
Browse files Browse the repository at this point in the history
Convenience function for dynamic scoping, and fix to filtering in StringFieldLower
  • Loading branch information
nguyer authored Sep 11, 2023
2 parents a98a227 + 9ce8e9e commit 22d184c
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 5 deletions.
7 changes: 7 additions & 0 deletions pkg/dbsql/crud.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ type CRUD[T Resource] interface {
UpdateMany(ctx context.Context, filter ffapi.Filter, update ffapi.Update, hooks ...PostCompletionHook) (err error)
Delete(ctx context.Context, id string, hooks ...PostCompletionHook) (err error)
DeleteMany(ctx context.Context, filter ffapi.Filter, hooks ...PostCompletionHook) (err error) // no events
Scoped(scope sq.Eq) *CrudBase[T] // allows dynamic scoping to a collection
}

type CrudBase[T Resource] struct {
Expand All @@ -135,6 +136,12 @@ type CrudBase[T Resource] struct {
ReadQueryModifier func(sq.SelectBuilder) sq.SelectBuilder
}

func (c *CrudBase[T]) Scoped(scope sq.Eq) *CrudBase[T] {
cScoped := *c
cScoped.ScopedFilter = func() sq.Eq { return scope }
return &cScoped
}

func UUIDValidator(ctx context.Context, idStr string) error {
_, err := fftypes.ParseUUID(ctx, idStr)
return err
Expand Down
5 changes: 5 additions & 0 deletions pkg/dbsql/crud_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,11 @@ func TestCRUDWithDBEnd2End(t *testing.T) {
assert.NoError(t, err)
checkEqualExceptTimes(t, *c1, *c1copy)

// Check we don't get it back by name if we scope to a different ns
c1NotFound, err := iCrud.Scoped(sq.Eq{"ns": "ns2"}).GetByName(ctx, *c1.Name)
assert.NoError(t, err)
assert.Nil(t, c1NotFound)

// Check we get it back by name, in name or UUID
c1copy, err = iCrud.GetByUUIDOrName(ctx, *c1.Name)
assert.NoError(t, err)
Expand Down
11 changes: 10 additions & 1 deletion pkg/ffapi/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,16 @@ func (f *baseFilter) Finalize() (fi *FilterInfo, err error) {
case string:
switch {
case field.FilterAsString():
value = &stringField{}
// We need to have a stringField for the filter serialization, but in the case of StringFieldLower
// (or other modified stringField types) we might still need to run transformations. So...
normalFilter := field.GetSerialization()
switch normalFilter.(type) {
case *stringField:
value = normalFilter
default:
// ... only switch to a default &stringField{} if the Serialization is not already a string
value = &stringField{}
}
case filterOpIsStringMatch(f.op):
return nil, i18n.NewError(f.fb.ctx, i18n.MsgFieldTypeNoStringMatching, name, field.Description())
default:
Expand Down
2 changes: 1 addition & 1 deletion pkg/ffapi/filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func TestLowerField(t *testing.T) {
fb.In("address", []driver.Value{addr1, addr2}),
).Finalize()
assert.NoError(t, err)
assert.Equal(t, "( lower(address) == '0xf698D78272a0bCD63A3feb097B24a866f6b8a5a0' ) && ( lower(address) IN ['0xf698D78272a0bCD63A3feb097B24a866f6b8a5a0','0xb9B919763dBC54D4D634150446Bf3991A9ef5eD7'] )", f.String())
assert.Equal(t, "( lower(address) == '0xf698d78272a0bcd63a3feb097b24a866f6b8a5a0' ) && ( lower(address) IN ['0xf698d78272a0bcd63a3feb097b24a866f6b8a5a0','0xb9b919763dbc54d4d634150446bf3991a9ef5ed7'] )", f.String())
}

func TestBuildMessageStringConvert(t *testing.T) {
Expand Down
15 changes: 12 additions & 3 deletions pkg/ffapi/query_fields.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@ func (f *nullField) Value() (driver.Value, error) { return nil, nil }
func (f *nullField) String() string { return fftypes.NullString }

type StringField struct{}
type stringField struct{ s string }
type stringField struct {
s string
lower bool
}

func (f *stringField) Scan(src interface{}) error {
switch tv := src.(type) {
Expand Down Expand Up @@ -136,7 +139,12 @@ func (f *stringField) Scan(src interface{}) error {
}
return nil
}
func (f *stringField) Value() (driver.Value, error) { return f.s, nil }
func (f *stringField) Value() (driver.Value, error) {
if f.lower {
return strings.ToLower(f.s), nil
}
return f.s, nil
}
func (f *stringField) String() string { return f.s }
func (f *StringField) GetSerialization() FieldSerialization { return &stringField{} }
func (f *StringField) FilterAsString() bool { return true }
Expand All @@ -146,7 +154,8 @@ type StringFieldLower struct {
StringField
}

func (f *StringFieldLower) GetSerialization() FieldSerialization { return &stringField{} }
func (f *StringFieldLower) GetSerialization() FieldSerialization { return &stringField{lower: true} }
func (f *StringFieldLower) FilterAsString() bool { return true }
func (f *StringFieldLower) FieldMods() []FieldMod { return []FieldMod{FieldModLower} }

type UUIDField struct{}
Expand Down

0 comments on commit 22d184c

Please sign in to comment.