oc-lib/dbs/dbs.go

191 lines
4.7 KiB
Go
Raw Permalink Normal View History

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
NOT
2024-08-01 09:13:10 +02:00
)
var str = [...]string{
"like",
"exists",
"in",
"gte",
"lte",
"lt",
"gt",
"equal",
"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 {
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}
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:
return defaultValue
2024-08-02 13:10:27 +02:00
}
}
func (m Operator) ToMongoOperator(k string, value interface{}) bson.M {
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}
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:
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
}