search: empty string values for attr and tag predicates

Fixes issue_461

Change-Id: I94cba8be70f30eca456d990ba4f4db2618b24553
This commit is contained in:
Steven L. Speek 2014-06-20 22:55:43 +02:00
parent d59ce13665
commit 3fc2669025
4 changed files with 58 additions and 19 deletions

View File

@ -572,9 +572,9 @@ var parseExpTests = []parserTestCase{
in: "attr:foo:",
want: &Constraint{
Permanode: &PermanodeConstraint{
Attr: "foo",
Value: "",
SkipHidden: true,
Attr: "foo",
ValueMatches: &StringConstraint{Empty: true},
SkipHidden: true,
},
},
},

View File

@ -238,13 +238,7 @@ func (a attribute) Description() string {
}
func (a attribute) Predicate(ctx *context.Context, args []string) (*Constraint, error) {
c := &Constraint{
Permanode: &PermanodeConstraint{
Attr: args[0],
SkipHidden: true,
Value: args[1],
},
}
c := attrConst(args[0], args[1])
if strings.HasPrefix(args[1], "~") {
// Substring. Hack. Figure out better way to do this.
c.Permanode.Value = ""
@ -321,14 +315,7 @@ func (t tag) Description() string {
}
func (t tag) Predicate(ctx *context.Context, args []string) (*Constraint, error) {
c := &Constraint{
Permanode: &PermanodeConstraint{
Attr: "tag",
SkipHidden: true,
Value: args[0],
},
}
return c, nil
return attrConst("tag", args[0]), nil
}
type title struct {
@ -571,6 +558,21 @@ func (h hasLocation) Predicate(ctx *context.Context, args []string) (*Constraint
// Helpers
func attrConst(attr, val string) *Constraint {
c := &Constraint{
Permanode: &PermanodeConstraint{
Attr: attr,
SkipHidden: true,
},
}
if val == "" {
c.Permanode.ValueMatches = &StringConstraint{Empty: true}
} else {
c.Permanode.Value = val
}
return c
}
func permOfFile(fc *FileConstraint) *Constraint {
return &Constraint{
Permanode: &PermanodeConstraint{

View File

@ -190,6 +190,18 @@ var keywordTests = []keywordTestcase{
want: attrfoobarC,
},
{
object: newAttribute(),
args: []string{"foo", ""},
want: &Constraint{
Permanode: &PermanodeConstraint{
Attr: "foo",
ValueMatches: &StringConstraint{Empty: true},
SkipHidden: true,
},
},
},
{
object: newAttribute(),
args: []string{"foo", "~bar"},
@ -255,6 +267,31 @@ var keywordTests = []keywordTestcase{
},
},
{
object: newTag(),
args: []string{""},
want: &Constraint{
Permanode: &PermanodeConstraint{
Attr: "tag",
ValueMatches: &StringConstraint{Empty: true},
SkipHidden: true,
},
},
},
{
object: newTitle(),
args: []string{""},
want: &Constraint{
Permanode: &PermanodeConstraint{
Attr: "title",
SkipHidden: true,
ValueMatches: &StringConstraint{
CaseInsensitive: true,
},
}},
},
{
object: newTitle(),
args: []string{"foo"},

View File

@ -225,7 +225,7 @@ func (q *SearchQuery) checkValid(ctx *context.Context) (sq *SearchQuery, err err
return nil, fmt.Errorf("Error parsing search expression %q: %v", expr, err)
}
if err := sq.Constraint.checkValid(); err != nil {
log.Fatalf("Internal error: parseExpression(%q) returned invalid constraint: %v", expr, err)
return nil, fmt.Errorf("Internal error: parseExpression(%q) returned invalid constraint: %v", expr, err)
}
return sq, nil
}