mirror of
https://github.com/safing/portbase
synced 2025-09-01 18:19:57 +00:00
77 lines
1.5 KiB
Go
77 lines
1.5 KiB
Go
package query
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
// Example:
|
|
// q.New("core:/",
|
|
// q.Where("a", q.GreaterThan, 0),
|
|
// q.Where("b", q.Equals, 0),
|
|
// q.Or(
|
|
// q.Where("c", q.StartsWith, "x"),
|
|
// q.Where("d", q.Contains, "y")
|
|
// )
|
|
// )
|
|
|
|
var (
|
|
prefixExpr = regexp.MustCompile("^[a-z-]+:")
|
|
)
|
|
|
|
// Query contains a compiled query.
|
|
type Query struct {
|
|
prefix string
|
|
condition Condition
|
|
}
|
|
|
|
// New creates a new query.
|
|
func New(prefix string, condition Condition) (*Query, error) {
|
|
// check prefix
|
|
if !prefixExpr.MatchString(prefix) {
|
|
return nil, fmt.Errorf("invalid prefix: %s", prefix)
|
|
}
|
|
|
|
// check condition
|
|
if condition != nil {
|
|
err := condition.check()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
} else {
|
|
condition = &noCond{}
|
|
}
|
|
|
|
// return query
|
|
return &Query{
|
|
prefix: prefix,
|
|
condition: condition,
|
|
}, nil
|
|
}
|
|
|
|
// MustCompile creates a new query and panics on an error.
|
|
func MustCompile(prefix string, condition Condition) *Query {
|
|
q, err := New(prefix, condition)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return q
|
|
}
|
|
|
|
// Matches checks whether the query matches the supplied data object.
|
|
func (q *Query) Matches(f Fetcher) bool {
|
|
return q.condition.complies(f)
|
|
}
|
|
|
|
// String returns the string representation of the query.
|
|
func (q *Query) String() string {
|
|
text := q.condition.string()
|
|
if text == "" {
|
|
return fmt.Sprintf("query %s", q.prefix)
|
|
}
|
|
if strings.HasPrefix(text, "(") {
|
|
text = text[1 : len(text)-1]
|
|
}
|
|
return fmt.Sprintf("query %s where %s", q.prefix, text)
|
|
}
|