mirror of https://github.com/perkeep/perkeep.git
search: empty string values for attr and tag predicates
Fixes issue_461 Change-Id: I94cba8be70f30eca456d990ba4f4db2618b24553
This commit is contained in:
parent
d59ce13665
commit
3fc2669025
|
@ -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,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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"},
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue