117 lines
2.8 KiB
Go
117 lines
2.8 KiB
Go
package database
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
type SQLOperator string
|
|
type LogicalOperator string
|
|
|
|
func GetLogicFromString(operator string) LogicalOperator {
|
|
switch strings.ToUpper(operator) {
|
|
case "OR":
|
|
return OR
|
|
default:
|
|
return AND
|
|
}
|
|
}
|
|
|
|
const (
|
|
Equal SQLOperator = "="
|
|
GreaterThan SQLOperator = ">"
|
|
LessThan SQLOperator = "<"
|
|
GreaterOrEqual SQLOperator = ">="
|
|
LessOrEqual SQLOperator = "<="
|
|
NotEqual SQLOperator = "<>"
|
|
Like SQLOperator = "LIKE"
|
|
In SQLOperator = "IN"
|
|
|
|
AND LogicalOperator = "AND"
|
|
OR LogicalOperator = "OR"
|
|
)
|
|
|
|
type QueryCondition struct {
|
|
Row string
|
|
Operator SQLOperator
|
|
Value any
|
|
}
|
|
|
|
type WhereGroup struct {
|
|
Conditions []*QueryCondition
|
|
Logic LogicalOperator
|
|
SubGroups WhereGroups
|
|
}
|
|
|
|
type WhereGroups []*WhereGroup
|
|
|
|
func (group *WhereGroup) AddCondition(condition *QueryCondition) {
|
|
group.Conditions = append(group.Conditions, condition)
|
|
}
|
|
|
|
func (group *WhereGroup) AddSubGroup(subGroup *WhereGroup) {
|
|
group.SubGroups = append(group.SubGroups, subGroup)
|
|
}
|
|
|
|
func (groups WhereGroups) Build(prependWhere bool) (string, []any) {
|
|
var whereStatement string
|
|
var queryValues []any
|
|
|
|
groupsLen := len(groups)
|
|
if prependWhere && groupsLen > 0 {
|
|
whereStatement = " WHERE "
|
|
}
|
|
|
|
groupStrings := []string{}
|
|
for _, group := range groups {
|
|
conditionsLen := len(group.Conditions)
|
|
subsLen := len(group.SubGroups)
|
|
if conditionsLen == 0 && subsLen == 0 {
|
|
continue
|
|
}
|
|
|
|
subQuery := strings.Builder{}
|
|
subQuery.WriteString("(")
|
|
|
|
if conditionsLen > 0 {
|
|
groupConditions := make([]string, conditionsLen)
|
|
for i, condition := range group.Conditions {
|
|
switch condition.Operator {
|
|
case In:
|
|
values, ok := condition.Value.([]string)
|
|
if ok {
|
|
placeholders := strings.Repeat("?,", len(values))
|
|
placeholders = placeholders[:len(placeholders)-1] // Remove trailing comma
|
|
groupConditions[i] = fmt.Sprintf("%s %s (%s)", condition.Row, condition.Operator, placeholders)
|
|
for _, v := range values {
|
|
queryValues = append(queryValues, v)
|
|
}
|
|
continue
|
|
}
|
|
fallthrough
|
|
default:
|
|
groupConditions[i] = fmt.Sprintf("%s %s ?", condition.Row, condition.Operator)
|
|
queryValues = append(queryValues, condition.Value)
|
|
}
|
|
}
|
|
|
|
subQuery.WriteString(strings.Join(groupConditions, fmt.Sprintf(" %s ", group.Logic)))
|
|
}
|
|
|
|
if subsLen > 0 {
|
|
if conditionsLen > 0 {
|
|
subQuery.WriteString(fmt.Sprintf(" %s ", group.Logic))
|
|
}
|
|
subGroupStatement, values := group.SubGroups.Build(false)
|
|
subQuery.WriteString(subGroupStatement)
|
|
queryValues = append(queryValues, values...)
|
|
}
|
|
|
|
subQuery.WriteString(")")
|
|
groupStrings = append(groupStrings, subQuery.String())
|
|
}
|
|
whereStatement += strings.Join(groupStrings, fmt.Sprintf(" %s ", AND))
|
|
|
|
return whereStatement, queryValues
|
|
}
|