2024-07-18 11:51:12 +02:00
|
|
|
package dbs
|
|
|
|
|
|
|
|
import (
|
2024-08-01 09:13:10 +02:00
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
2024-07-18 11:51:12 +02:00
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
|
|
)
|
|
|
|
|
2024-08-01 09:13:10 +02:00
|
|
|
type Operator int
|
|
|
|
|
|
|
|
const (
|
|
|
|
LIKE Operator = iota
|
|
|
|
EXISTS
|
|
|
|
IN
|
|
|
|
GTE
|
|
|
|
LTE
|
|
|
|
LT
|
|
|
|
GT
|
|
|
|
EQUAL
|
2024-08-12 16:11:25 +02:00
|
|
|
NOT
|
2024-08-01 09:13:10 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
var str = [...]string{
|
|
|
|
"like",
|
|
|
|
"exists",
|
|
|
|
"in",
|
|
|
|
"gte",
|
|
|
|
"lte",
|
|
|
|
"lt",
|
|
|
|
"gt",
|
|
|
|
"equal",
|
2024-08-12 16:11:25 +02:00
|
|
|
"not",
|
2024-08-01 09:13:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m Operator) String() string {
|
|
|
|
return str[m]
|
|
|
|
}
|
|
|
|
|
2024-08-02 13:10:27 +02:00
|
|
|
func (m Operator) ToMongoEOperator(k string, value interface{}) bson.E {
|
2024-08-12 16:11:25 +02:00
|
|
|
defer func() {
|
|
|
|
if r := recover(); r != nil {
|
|
|
|
fmt.Println("Recovered. Error:\n", r)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
defaultValue := bson.E{Key: k, Value: bson.M{"$regex": ToValueOperator(StringToOperator(m.String()), value)}}
|
2024-08-01 09:13:10 +02:00
|
|
|
switch m {
|
|
|
|
case LIKE:
|
2024-08-02 13:10:27 +02:00
|
|
|
return bson.E{Key: k, Value: bson.M{"$regex": ToValueOperator(StringToOperator(m.String()), value)}}
|
2024-08-01 09:13:10 +02:00
|
|
|
case EXISTS:
|
2024-08-02 13:10:27 +02:00
|
|
|
return bson.E{Key: k, Value: bson.M{"$exists": ToValueOperator(StringToOperator(m.String()), value)}}
|
2024-08-01 09:13:10 +02:00
|
|
|
case IN:
|
2024-08-02 13:10:27 +02:00
|
|
|
return bson.E{Key: k, Value: bson.M{"$in": ToValueOperator(StringToOperator(m.String()), value)}}
|
2024-08-01 09:13:10 +02:00
|
|
|
case GTE:
|
2024-08-02 13:10:27 +02:00
|
|
|
return bson.E{Key: k, Value: bson.M{"$gte": ToValueOperator(StringToOperator(m.String()), value)}}
|
2024-08-01 09:13:10 +02:00
|
|
|
case GT:
|
2024-08-02 13:10:27 +02:00
|
|
|
return bson.E{Key: k, Value: bson.M{"$gt": ToValueOperator(StringToOperator(m.String()), value)}}
|
2024-08-01 09:13:10 +02:00
|
|
|
case LTE:
|
2024-08-02 13:10:27 +02:00
|
|
|
return bson.E{Key: k, Value: bson.M{"$lte": ToValueOperator(StringToOperator(m.String()), value)}}
|
2024-08-01 09:13:10 +02:00
|
|
|
case LT:
|
2024-08-02 13:10:27 +02:00
|
|
|
return bson.E{Key: k, Value: bson.M{"$lt": ToValueOperator(StringToOperator(m.String()), value)}}
|
2024-08-01 09:13:10 +02:00
|
|
|
case EQUAL:
|
2024-08-02 13:10:27 +02:00
|
|
|
return bson.E{Key: k, Value: value}
|
2024-08-12 16:11:25 +02:00
|
|
|
case NOT:
|
|
|
|
v := value.(Filters)
|
|
|
|
orList := bson.A{}
|
|
|
|
andList := bson.A{}
|
|
|
|
f := bson.D{}
|
|
|
|
for k, filter := range v.Or {
|
|
|
|
for _, ff := range filter {
|
|
|
|
orList = append(orList, StringToOperator(ff.Operator).ToMongoOperator(k, ff.Value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for k, filter := range v.And {
|
|
|
|
for _, ff := range filter {
|
|
|
|
andList = append(andList, StringToOperator(ff.Operator).ToMongoOperator(k, ff.Value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(orList) > 0 && len(andList) == 0 {
|
|
|
|
f = bson.D{{"$or", orList}}
|
|
|
|
} else {
|
|
|
|
if len(orList) > 0 {
|
|
|
|
andList = append(andList, bson.M{"$or": orList})
|
|
|
|
}
|
|
|
|
f = bson.D{{"$and", andList}}
|
|
|
|
}
|
|
|
|
return bson.E{Key: "$not", Value: f}
|
2024-08-01 09:13:10 +02:00
|
|
|
default:
|
2024-08-12 16:11:25 +02:00
|
|
|
return defaultValue
|
2024-08-02 13:10:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m Operator) ToMongoOperator(k string, value interface{}) bson.M {
|
2024-08-12 16:11:25 +02:00
|
|
|
defer func() {
|
|
|
|
if r := recover(); r != nil {
|
|
|
|
fmt.Println("Recovered. Error:\n", r)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
defaultValue := bson.M{k: bson.M{"$regex": ToValueOperator(StringToOperator(m.String()), value)}}
|
2024-08-02 13:10:27 +02:00
|
|
|
switch m {
|
|
|
|
case LIKE:
|
|
|
|
return bson.M{k: bson.M{"$regex": ToValueOperator(StringToOperator(m.String()), value)}}
|
|
|
|
case EXISTS:
|
|
|
|
return bson.M{k: bson.M{"$exists": ToValueOperator(StringToOperator(m.String()), value)}}
|
|
|
|
case IN:
|
|
|
|
return bson.M{k: bson.M{"$in": ToValueOperator(StringToOperator(m.String()), value)}}
|
|
|
|
case GTE:
|
|
|
|
return bson.M{k: bson.M{"$gte": ToValueOperator(StringToOperator(m.String()), value)}}
|
|
|
|
case GT:
|
|
|
|
return bson.M{k: bson.M{"$gt": ToValueOperator(StringToOperator(m.String()), value)}}
|
|
|
|
case LTE:
|
|
|
|
return bson.M{k: bson.M{"$lte": ToValueOperator(StringToOperator(m.String()), value)}}
|
|
|
|
case LT:
|
|
|
|
return bson.M{k: bson.M{"$lt": ToValueOperator(StringToOperator(m.String()), value)}}
|
|
|
|
case EQUAL:
|
|
|
|
return bson.M{k: value}
|
2024-08-12 16:11:25 +02:00
|
|
|
case NOT:
|
|
|
|
v := value.(Filters)
|
|
|
|
orList := bson.A{}
|
|
|
|
andList := bson.A{}
|
|
|
|
f := bson.D{}
|
|
|
|
for k, filter := range v.Or {
|
|
|
|
for _, ff := range filter {
|
|
|
|
orList = append(orList, StringToOperator(ff.Operator).ToMongoOperator(k, ff.Value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for k, filter := range v.And {
|
|
|
|
for _, ff := range filter {
|
|
|
|
andList = append(andList, StringToOperator(ff.Operator).ToMongoOperator(k, ff.Value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(orList) > 0 && len(andList) == 0 {
|
|
|
|
f = bson.D{{"$or", orList}}
|
|
|
|
} else {
|
|
|
|
if len(orList) > 0 {
|
|
|
|
andList = append(andList, bson.M{"$or": orList})
|
|
|
|
}
|
|
|
|
f = bson.D{{"$and", andList}}
|
|
|
|
}
|
|
|
|
return bson.M{"$not": f}
|
2024-08-02 13:10:27 +02:00
|
|
|
default:
|
2024-08-12 16:11:25 +02:00
|
|
|
return defaultValue
|
2024-08-01 09:13:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func StringToOperator(s string) Operator {
|
|
|
|
for i, v := range str {
|
|
|
|
if v == s {
|
|
|
|
return Operator(i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return LIKE
|
|
|
|
}
|
|
|
|
|
|
|
|
func ToValueOperator(operator Operator, value interface{}) interface{} {
|
|
|
|
if strings.TrimSpace(fmt.Sprintf("%v", value)) == "*" {
|
|
|
|
value = ""
|
|
|
|
}
|
|
|
|
if operator == LIKE {
|
|
|
|
return "(?i).*" + strings.TrimSpace(fmt.Sprintf("%v", value)) + ".*"
|
|
|
|
}
|
|
|
|
return value
|
|
|
|
}
|
|
|
|
|
|
|
|
type Filters struct {
|
2024-08-02 14:07:43 +02:00
|
|
|
And map[string][]Filter `json:"and"`
|
|
|
|
Or map[string][]Filter `json:"or"`
|
2024-08-01 09:13:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type Filter struct {
|
|
|
|
Operator string `json:"operator,omitempty"`
|
|
|
|
Value interface{} `json:"value,omitempty"`
|
|
|
|
}
|
|
|
|
|
2024-07-18 11:51:12 +02:00
|
|
|
type Input = map[string]interface{}
|
|
|
|
|
|
|
|
func InputToBson(i Input, isUpdate bool) bson.D {
|
|
|
|
input := bson.D{}
|
|
|
|
for k, v := range i {
|
|
|
|
if k == "id" {
|
|
|
|
input = append(input, bson.E{Key: "_id", Value: v})
|
|
|
|
} else {
|
|
|
|
input = append(input, bson.E{Key: k, Value: v})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if isUpdate {
|
|
|
|
return bson.D{{Key: "$set", Value: input}}
|
|
|
|
}
|
|
|
|
return input
|
|
|
|
}
|