2022-09-16 20:33:47 +00:00
|
|
|
package query
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
type QTerm struct {
|
|
|
|
Org string
|
|
|
|
Value string
|
|
|
|
IsKey bool
|
|
|
|
}
|
|
|
|
|
|
|
|
type QueryObject struct {
|
|
|
|
Key string
|
|
|
|
SearchTerms *[] *QTerm
|
|
|
|
Results *[] ISearchable
|
|
|
|
}
|
|
|
|
|
|
|
|
func Parse( line string, entries *[] ISearchable ) ( *QueryObject, error ) {
|
|
|
|
|
|
|
|
var Key string = ""
|
|
|
|
|
|
|
|
// Sanitize and assume properties for each of the keywords
|
|
|
|
terms := [] *QTerm{}
|
|
|
|
for _, val := range strings.Split( line, " " ) {
|
|
|
|
|
|
|
|
if val == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
term := QTerm{
|
|
|
|
Org: val,
|
|
|
|
Value: strings.Trim( val, " " ),
|
|
|
|
}
|
|
|
|
terms = append( terms, &term )
|
|
|
|
}
|
|
|
|
|
|
|
|
lookForKey:
|
|
|
|
for _, term := range terms {
|
|
|
|
for _, entry := range *entries {
|
|
|
|
if term.Value == *entry.GetKey() {
|
|
|
|
Key = term.Value
|
|
|
|
term.IsKey = true
|
|
|
|
break lookForKey
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
matches := [] ISearchable{}
|
|
|
|
|
|
|
|
if Key != "" && len( terms ) == 1 {
|
|
|
|
for _, entry := range *entries {
|
|
|
|
if Key == *entry.GetKey() {
|
|
|
|
matches = append( matches, entry )
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return &QueryObject{ Key: Key, Results: &matches, SearchTerms: &terms }, nil
|
|
|
|
} else if 0 < len( terms ) {
|
|
|
|
for _, entry := range *entries {
|
2022-09-16 22:42:49 +00:00
|
|
|
anyFailed := false
|
2022-09-16 20:33:47 +00:00
|
|
|
for _, term := range terms {
|
|
|
|
if term.IsKey {
|
|
|
|
continue
|
|
|
|
}
|
2022-09-16 22:42:49 +00:00
|
|
|
|
|
|
|
if !( ( Key == "" || Key == *entry.GetKey() ) && entry.Test( term.Value ) ) {
|
|
|
|
anyFailed = true
|
|
|
|
break
|
2022-09-16 20:33:47 +00:00
|
|
|
}
|
|
|
|
}
|
2022-09-16 22:42:49 +00:00
|
|
|
|
|
|
|
if !anyFailed {
|
|
|
|
matches = append( matches, entry )
|
|
|
|
}
|
2022-09-16 20:33:47 +00:00
|
|
|
}
|
|
|
|
return &QueryObject{ Key: Key, Results: &matches, SearchTerms: &terms }, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, fmt.Errorf( "Cannot parse: %s", line )
|
|
|
|
}
|