Skip to content

Commit 3867f8c

Browse files
author
Tsvetelin Pantev
committed
fixes for code review of rs#274
1 parent 061731c commit 3867f8c

File tree

4 files changed

+25
-53
lines changed

4 files changed

+25
-53
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -998,7 +998,7 @@ The same example with flags:
998998
However, keep in mind that Storers have to support regular expression and depending on the implementation of the storage handler the accepted syntax may vary.
999999
An error of `ErrNotImplemented` will be returned for those storage back-ends which do not support the `$regex` operator.
10001000
1001-
The operator `$not` functions as an opposite operator to `$regex`
1001+
The operator `$not` functions as an opposite operator to `$regex`. Unlike MongoDB, we do not allow `$not` as a general negation operator.
10021002
10031003
The `$elemMatch` operator matches documents that contain an array field with at least one element that matches all the specified query criteria.
10041004
```go

schema/query/predicate.go

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -477,13 +477,14 @@ func (e LowerOrEqual) String() string {
477477

478478
// Regex matches values that match to a specified regular expression.
479479
type Regex struct {
480-
Field string
481-
Value *regexp.Regexp
480+
Field string
481+
Value *regexp.Regexp
482+
Negated bool
482483
}
483484

484485
// Match implements Expression interface.
485486
func (e Regex) Match(payload map[string]interface{}) bool {
486-
return e.Value.MatchString(payload[e.Field].(string))
487+
return e.Value.MatchString(payload[e.Field].(string)) != e.Negated
487488
}
488489

489490
// Prepare implements Expression interface.
@@ -494,7 +495,13 @@ func (e *Regex) Prepare(validator schema.Validator) error {
494495

495496
// String implements Expression interface.
496497
func (e Regex) String() string {
497-
return quoteField(e.Field) + ": {" + opRegex + ": " + valueString(e.Value) + "}"
498+
var regexOperation string
499+
if e.Negated {
500+
regexOperation = opNot
501+
} else {
502+
regexOperation = opRegex
503+
}
504+
return quoteField(e.Field) + ": {" + regexOperation + ": " + valueString(e.Value) + "}"
498505
}
499506

500507
// ElemMatch matches object values specified in an array.
@@ -553,24 +560,3 @@ func (e ElemMatch) String() string {
553560
}
554561
return quoteField(e.Field) + ": {" + opElemMatch + ": {" + strings.Join(s, ", ") + "}}"
555562
}
556-
557-
type Not struct {
558-
Field string
559-
Value *regexp.Regexp
560-
}
561-
562-
// Match implements Expression interface.
563-
func (e Not) Match(payload map[string]interface{}) bool {
564-
return !e.Value.MatchString(payload[e.Field].(string))
565-
}
566-
567-
// Prepare implements Expression interface.
568-
func (e *Not) Prepare(validator schema.Validator) error {
569-
_, err := prepareValue(e.Field, e.Value.String(), validator)
570-
return err
571-
}
572-
573-
// String implements Expression interface.
574-
func (e Not) String() string {
575-
return quoteField(e.Field) + ": {" + opNot + ": \"" + e.Value.String() + "\"}"
576-
}

schema/query/predicate_parser.go

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -234,16 +234,24 @@ func (p *predicateParser) parseCommand(field string) (Expression, error) {
234234
case opGreaterOrEqual:
235235
return &GreaterOrEqual{Field: field, Value: value}, nil
236236
}
237-
case opRegex:
238-
re, err := p.parseRegex(label)
237+
case opRegex, opNot:
238+
str, err := p.parseString()
239239
if err != nil {
240-
return nil, err
240+
return nil, fmt.Errorf("%s: %v", label, err)
241+
}
242+
re, err := regexp.Compile(str)
243+
if err != nil {
244+
return nil, fmt.Errorf("%s: invalid regex: %v", label, err)
241245
}
242246
p.eatWhitespaces()
243247
if !p.expect('}') {
244248
return nil, fmt.Errorf("%s: expected '}' got %q", label, p.peek())
245249
}
246-
return &Regex{Field: field, Value: re}, nil
250+
negated := false
251+
if label == opNot {
252+
negated = true
253+
}
254+
return &Regex{Field: field, Value: re, Negated: negated}, nil
247255
case opElemMatch:
248256
exps, err := p.parseExpressions()
249257
if err != nil {
@@ -254,16 +262,6 @@ func (p *predicateParser) parseCommand(field string) (Expression, error) {
254262
return nil, fmt.Errorf("%s: expected '}' got %q", label, p.peek())
255263
}
256264
return &ElemMatch{Field: field, Exps: exps}, nil
257-
case opNot:
258-
re, err := p.parseRegex(label)
259-
if err != nil {
260-
return nil, err
261-
}
262-
p.eatWhitespaces()
263-
if !p.expect('}') {
264-
return nil, fmt.Errorf("%s: expected '}' got %q", label, p.peek())
265-
}
266-
return &Not{Field: field, Value: re}, nil
267265
}
268266
}
269267
VALUE:
@@ -530,15 +528,3 @@ func (p *predicateParser) eatWhitespaces() {
530528
break
531529
}
532530
}
533-
534-
func (p *predicateParser) parseRegex(label string) (*regexp.Regexp, error) {
535-
str, err := p.parseString()
536-
if err != nil {
537-
return nil, fmt.Errorf("%s: %v", label, err)
538-
}
539-
re, err := regexp.Compile(str)
540-
if err != nil {
541-
return nil, fmt.Errorf("%s: invalid regex: %v", label, err)
542-
}
543-
return re, nil
544-
}

schema/query/predicate_parser_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func TestParse(t *testing.T) {
105105
},
106106
{
107107
`{"foo": {"$not": "regex.+awesome"}}`,
108-
Predicate{&Not{Field: "foo", Value: regexp.MustCompile("regex.+awesome")}},
108+
Predicate{&Regex{Field: "foo", Value: regexp.MustCompile("regex.+awesome"), Negated: true}},
109109
nil,
110110
},
111111
{

0 commit comments

Comments
 (0)