116 lines
2.3 KiB
Go
116 lines
2.3 KiB
Go
/**
|
|
* file: types/productSearch.go
|
|
* author: Theo Technicguy
|
|
* license: Apache 2.0
|
|
*
|
|
* product searching type and functions
|
|
*/
|
|
|
|
package types
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
ErrInvalidSearch = errors.New("invalid search")
|
|
)
|
|
|
|
type ProductSearch struct {
|
|
Ean string
|
|
Names []string
|
|
TagIds []uint
|
|
Oprators ProductSearchOperators
|
|
}
|
|
|
|
type ProductSearchOperators struct {
|
|
Master string
|
|
Names string
|
|
TagIds string
|
|
}
|
|
|
|
/* *** Validators *** */
|
|
|
|
func (pso *ProductSearchOperators) ValidOperators() bool {
|
|
return ((pso.Master == "AND" || pso.Master == "OR") &&
|
|
(pso.Names == "AND" || pso.Names == "OR") &&
|
|
(pso.TagIds == "AND" || pso.TagIds == "OR"))
|
|
}
|
|
|
|
func (pso *ProductSearchOperators) Valid() bool {
|
|
return pso.ValidOperators()
|
|
}
|
|
|
|
func (ps *ProductSearch) Valid() bool {
|
|
return ps.Oprators.Valid()
|
|
}
|
|
|
|
/* *** Type functions *** */
|
|
|
|
func (pso *ProductSearchOperators) FillDefaults() {
|
|
if pso.Master == "" {
|
|
pso.Master = "AND"
|
|
}
|
|
if pso.Names == "" {
|
|
pso.Names = "AND"
|
|
}
|
|
if pso.TagIds == "" {
|
|
pso.TagIds = "AND"
|
|
}
|
|
}
|
|
|
|
func (ps *ProductSearch) BuildNamesSearch() string {
|
|
nameSearch := []string{}
|
|
for _, name := range ps.Names {
|
|
nameSearch = append(nameSearch, fmt.Sprintf("p.name LIKE '%%%s%%'", name))
|
|
}
|
|
|
|
return "(" + strings.Join(nameSearch, " "+ps.Oprators.Names+" ") + ")"
|
|
}
|
|
|
|
func (ps *ProductSearch) BuildTagSearch() string {
|
|
tagSearch := []string{}
|
|
for _, tag := range ps.TagIds {
|
|
tagSearch = append(tagSearch, fmt.Sprintf("%d", tag))
|
|
}
|
|
|
|
return "ptg.tid IN (" + strings.Join(tagSearch, ", ") + ")"
|
|
}
|
|
|
|
func (ps *ProductSearch) BuildSearch() string {
|
|
sql := `SELECT DISTINCT p.*
|
|
FROM Product p
|
|
LEFT OUTER JOIN ProductTagging ptg ON p.ProductID = ptg.ProductID
|
|
LEFT OUTER JOIN ProductTag pt ON ptg.TagID = pt.TagID
|
|
`
|
|
|
|
filters := []string{}
|
|
|
|
if ps.Ean != "" {
|
|
filters = append(filters, fmt.Sprintf("p.ean LIKE '%%%s%%'", ps.Ean))
|
|
}
|
|
if len(ps.Names) > 0 {
|
|
filters = append(filters, ps.BuildNamesSearch())
|
|
}
|
|
if len(ps.TagIds) > 0 {
|
|
filters = append(filters, ps.BuildTagSearch())
|
|
}
|
|
|
|
if len(filters) > 0 {
|
|
sql = sql + "WHERE (" + strings.Join(filters, " "+ps.Oprators.Master+" ") + ")\n"
|
|
}
|
|
|
|
if len(ps.TagIds) > 0 {
|
|
sql = sql + "GROUP BY p.id"
|
|
if ps.Oprators.TagIds == "AND" {
|
|
sql = sql + fmt.Sprintf("\nHAVING COUNT(p.id) = %d", len(ps.TagIds))
|
|
}
|
|
}
|
|
|
|
sql = sql + ";"
|
|
|
|
return sql
|
|
}
|