attribute search

Change-Id: I9638ca9ef325076122721c601aade05ce99c0c24
This commit is contained in:
Steven L. Speek 2014-03-07 22:27:40 +01:00
parent bfa8efc1b9
commit b326c2db11
2 changed files with 87 additions and 2 deletions

View File

@ -32,8 +32,9 @@ import (
)
var (
tagExpr = regexp.MustCompile(`^tag:(\w+)$`)
titleExpr = regexp.MustCompile(`^title:(\S+)$`) // TODO: proper expr parser supporting quoting
tagExpr = regexp.MustCompile(`^tag:(.+)$`)
titleExpr = regexp.MustCompile(`^title:(.+)$`) // TODO: proper expr parser supporting quoting
attrExpr = regexp.MustCompile(`^attr:(\w+):(.+)$`)
// used for width/height ranges. 10 is max length of 32-bit
// int (strconv.Atoi on 32-bit platforms), even though a max
@ -259,6 +260,16 @@ func parseExpression(ctx *context.Context, exp string) (*SearchQuery, error) {
and(locConstraint)
continue
}
if m := attrExpr.FindStringSubmatch(word); m != nil {
and(&Constraint{
Permanode: &PermanodeConstraint{
Attr: m[1],
SkipHidden: true,
Value: m[2],
},
})
continue
}
log.Printf("Unknown search expression word %q", word)
// TODO: finish. better tokenization. non-operator tokens
// are text searches, etc.

View File

@ -103,6 +103,78 @@ var parseExprTests = []struct {
},
},
{
name: "tag with spaces",
in: `tag:"Foo Bar"`,
want: &SearchQuery{
Constraint: &Constraint{
Logical: &LogicalConstraint{
Op: "and",
A: &Constraint{
Permanode: &PermanodeConstraint{
SkipHidden: true,
},
},
B: &Constraint{
Permanode: &PermanodeConstraint{
Attr: "tag",
Value: "Foo Bar",
SkipHidden: true,
},
},
},
},
},
},
{
name: "attribute search",
in: "attr:foo:bar",
want: &SearchQuery{
Constraint: &Constraint{
Logical: &LogicalConstraint{
Op: "and",
A: &Constraint{
Permanode: &PermanodeConstraint{
SkipHidden: true,
},
},
B: &Constraint{
Permanode: &PermanodeConstraint{
Attr: "foo",
Value: "bar",
SkipHidden: true,
},
},
},
},
},
},
{
name: "attribute search with space in value",
in: `attr:foo:"fun bar"`,
want: &SearchQuery{
Constraint: &Constraint{
Logical: &LogicalConstraint{
Op: "and",
A: &Constraint{
Permanode: &PermanodeConstraint{
SkipHidden: true,
},
},
B: &Constraint{
Permanode: &PermanodeConstraint{
Attr: "foo",
Value: "fun bar",
SkipHidden: true,
},
},
},
},
},
},
{
in: "tag:funny",
want: &SearchQuery{
@ -204,6 +276,7 @@ func TestSplitExpr(t *testing.T) {
{"foo bar", []string{"foo", "bar"}},
{" foo bar ", []string{"foo", "bar"}},
{`foo:"quoted string" bar`, []string{`foo:quoted string`, "bar"}},
{`foo:"quoted \"-containing"`, []string{`foo:quoted "-containing`}},
}
for _, tt := range tests {
got := splitExpr(tt.in)
@ -225,6 +298,7 @@ func TestTokenizeExpr(t *testing.T) {
{" -foo bar", []string{" ", "-", "foo", " ", "bar"}},
{`-"quote"foo`, []string{"-", `"quote"`, "foo"}},
{`foo:"quoted string" bar`, []string{"foo:", `"quoted string"`, " ", "bar"}},
{`"quoted \"-containing"`, []string{`"quoted \"-containing"`}},
}
for _, tt := range tests {
got := tokenizeExpr(tt.in)