Skip to content

Commit

Permalink
Added search.Expects and search.AssignUnique methods + tests
Browse files Browse the repository at this point in the history
  • Loading branch information
qjerome committed Apr 12, 2022
1 parent cb91573 commit ecbaf43
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 26 deletions.
2 changes: 1 addition & 1 deletion .github/coverage/badge.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 20 additions & 18 deletions .github/coverage/cover.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,23 +98,25 @@ github.com/0xrawsec/sod/schema.go:197: update 100.0%
github.com/0xrawsec/sod/schema.go:209: mustCache 100.0%
github.com/0xrawsec/sod/schema.go:213: asyncWritesEnabled 100.0%
github.com/0xrawsec/sod/schema.go:220: control 80.0%
github.com/0xrawsec/sod/search.go:15: IsNoObjectFound 100.0%
github.com/0xrawsec/sod/search.go:30: newSearch 100.0%
github.com/0xrawsec/sod/search.go:36: Operation 66.7%
github.com/0xrawsec/sod/search.go:50: And 100.0%
github.com/0xrawsec/sod/search.go:58: Or 100.0%
github.com/0xrawsec/sod/search.go:78: Len 100.0%
github.com/0xrawsec/sod/search.go:84: Iterator 85.7%
github.com/0xrawsec/sod/search.go:102: Delete 75.0%
github.com/0xrawsec/sod/search.go:113: Reverse 100.0%
github.com/0xrawsec/sod/search.go:119: Limit 100.0%
github.com/0xrawsec/sod/search.go:126: One 100.0%
github.com/0xrawsec/sod/search.go:137: AssignOne 100.0%
github.com/0xrawsec/sod/search.go:156: Assign 100.0%
github.com/0xrawsec/sod/search.go:175: Collect 100.0%
github.com/0xrawsec/sod/search.go:183: Err 100.0%
github.com/0xrawsec/sod/search.go:189: one 91.7%
github.com/0xrawsec/sod/search.go:211: collect 93.3%
github.com/0xrawsec/sod/search.go:16: IsNoObjectFound 100.0%
github.com/0xrawsec/sod/search.go:31: newSearch 100.0%
github.com/0xrawsec/sod/search.go:38: Expects 83.3%
github.com/0xrawsec/sod/search.go:54: Operation 62.5%
github.com/0xrawsec/sod/search.go:74: And 100.0%
github.com/0xrawsec/sod/search.go:83: Or 90.0%
github.com/0xrawsec/sod/search.go:105: Len 100.0%
github.com/0xrawsec/sod/search.go:111: Iterator 77.8%
github.com/0xrawsec/sod/search.go:133: Delete 75.0%
github.com/0xrawsec/sod/search.go:144: Reverse 100.0%
github.com/0xrawsec/sod/search.go:150: Limit 100.0%
github.com/0xrawsec/sod/search.go:157: One 100.0%
github.com/0xrawsec/sod/search.go:167: AssignUnique 100.0%
github.com/0xrawsec/sod/search.go:176: AssignOne 100.0%
github.com/0xrawsec/sod/search.go:195: Assign 100.0%
github.com/0xrawsec/sod/search.go:214: Collect 100.0%
github.com/0xrawsec/sod/search.go:222: Err 100.0%
github.com/0xrawsec/sod/search.go:228: one 91.7%
github.com/0xrawsec/sod/search.go:250: collect 93.3%
github.com/0xrawsec/sod/sod.go:31: newObjectMap 100.0%
github.com/0xrawsec/sod/sod.go:35: put 100.0%
github.com/0xrawsec/sod/sod.go:41: get 100.0%
Expand Down Expand Up @@ -198,4 +200,4 @@ github.com/0xrawsec/sod/utils.go:197: dbgLock 0.0%
github.com/0xrawsec/sod/utils.go:206: fieldPath 100.0%
github.com/0xrawsec/sod/utils.go:210: unmarshalJsonFile 80.0%
github.com/0xrawsec/sod/utils.go:238: writeReader 60.0%
total: (statements) 88.7%
total: (statements) 88.4%
51 changes: 45 additions & 6 deletions search.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import (
)

var (
ErrUnknownOperator = errors.New("unknown logical operator")
ErrNoObjectFound = errors.New("no object found")
ErrUnknownOperator = errors.New("unknown logical operator")
ErrNoObjectFound = errors.New("no object found")
ErrUnexpectedNumberOfResults = errors.New("unexpected number of results")
)

func IsNoObjectFound(err error) bool {
Expand All @@ -31,10 +32,33 @@ func newSearch(db *DB, o Object, f []*indexedField, err error) *Search {
return &Search{db: db, object: o, fields: f, limit: math.MaxUint, err: err}
}

// Expects checks that the number of results is the one expected
// if not, next call to s.Err must return an error and any subsbequent
// attempt to collect results must fail
func (s *Search) Expects(n int) *Search {
found := len(s.fields)

if s.err != nil {
return s
}

if found != n {
s.err = fmt.Errorf("%w expected %d, found %d", ErrUnexpectedNumberOfResults, n, found)
}

return s
}

// Operation performs a new Search while ANDing or ORing the results
// operator must be in ["and", "&&", "or", "||"]
func (s *Search) Operation(operator, field, comparator string, value interface{}) *Search {

op := strings.ToLower(operator)

if s.err != nil {
return s
}

switch op {
case "and", "&&":
return s.And(field, comparator, value)
Expand All @@ -48,17 +72,20 @@ func (s *Search) Operation(operator, field, comparator string, value interface{}

// And performs a new Search while "ANDing" search results
func (s *Search) And(field, operator string, value interface{}) *Search {
if s.Err() != nil {
if s.err != nil {
return s
}

return s.db.search(s.object, field, operator, value, s.fields)
}

// Or performs a new Search while "ORing" search results
func (s *Search) Or(field, operator string, value interface{}) *Search {
if s.Err() != nil {

if s.err != nil {
return s
}

new := s.db.search(s.object, field, operator, value, nil)
marked := make(map[uint64]bool)
// we mark the fields of the new search
Expand All @@ -84,6 +111,10 @@ func (s *Search) Len() int {
func (s *Search) Iterator() (it *iterator, err error) {
var sch *Schema

if s.err != nil {
return nil, s.err
}

if sch, err = s.db.schema(s.object); err != nil {
return
}
Expand Down Expand Up @@ -130,6 +161,14 @@ func (s *Search) One() (o Object, err error) {
return s.one()
}

// AssignUnique checks there is only one result in search and assign it
// to target. If search retuns more than one result, ErrUnexpectedNumberOfResults
// is returned
func (s *Search) AssignUnique(target interface{}) (err error) {
s.Expects(1)
return s.AssignOne(target)
}

// AssignOne returns the first result found calling Collect function
// and assign the Object found to target. Target must be a *sod.Object
// otherwise the function panics. If no Object is found, ErrNoObjectFound
Expand Down Expand Up @@ -212,8 +251,8 @@ func (s *Search) collect() (out []Object, err error) {
var it *iterator
var o Object

if s.Err() != nil {
return nil, s.Err()
if s.err != nil {
return nil, s.err
}

if it, err = s.Iterator(); err != nil {
Expand Down
4 changes: 3 additions & 1 deletion sod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,9 @@ func TestUniqueObject(t *testing.T) {
tt.ExpectErr(db.InsertOrUpdate(&testStructUnique{A: 42}), ErrFieldUnique)

tt.ShouldPanic(func() { db.Search(&testStructUnique{}, "A", "=", 42).AssignOne(nil) })
tt.CheckErr(db.Search(&testStructUnique{}, "A", "=", 42).AssignOne(&uninit))
tt.ExpectErr(db.Search(&testStructUnique{}, "A", "=", 42).Expects(2).AssignOne(&uninit), ErrUnexpectedNumberOfResults)
tt.CheckErr(db.Search(&testStructUnique{}, "A", "=", 42).Expects(1).AssignOne(&uninit))
tt.CheckErr(db.Search(&testStructUnique{}, "A", "=", 42).AssignUnique(&uninit))
tt.Assert(uninit.A == 42)

ts := &testStructUnique{}
Expand Down

0 comments on commit ecbaf43

Please sign in to comment.