2021-01-19 12:26:26 +00:00
|
|
|
package mongo
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2021-05-03 07:12:58 +00:00
|
|
|
"sort"
|
2021-01-19 12:26:26 +00:00
|
|
|
|
2023-05-24 11:04:29 +00:00
|
|
|
"git.kmsign.ru/royalcat/repogen/internal/code"
|
|
|
|
"git.kmsign.ru/royalcat/repogen/internal/codegen"
|
|
|
|
"git.kmsign.ru/royalcat/repogen/internal/spec"
|
2021-01-19 12:26:26 +00:00
|
|
|
)
|
|
|
|
|
2021-01-27 12:15:25 +00:00
|
|
|
type updateField struct {
|
|
|
|
BsonTag string
|
|
|
|
ParamIndex int
|
|
|
|
}
|
|
|
|
|
2021-02-24 12:02:57 +00:00
|
|
|
type update interface {
|
2023-04-18 13:21:46 +00:00
|
|
|
Code() codegen.Statement
|
2021-02-24 12:02:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type updateModel struct {
|
|
|
|
}
|
|
|
|
|
2023-04-18 13:21:46 +00:00
|
|
|
func (u updateModel) Code() codegen.Statement {
|
|
|
|
return codegen.MapStatement{
|
|
|
|
Type: "bson.M",
|
|
|
|
Pairs: []codegen.MapPair{
|
|
|
|
{
|
|
|
|
Key: "$set",
|
|
|
|
Value: codegen.Identifier("arg1"),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2021-02-24 12:02:57 +00:00
|
|
|
}
|
|
|
|
|
2021-03-31 11:44:31 +00:00
|
|
|
type updateFields map[string][]updateField
|
2021-02-24 12:02:57 +00:00
|
|
|
|
2023-04-18 13:21:46 +00:00
|
|
|
func (u updateFields) Code() codegen.Statement {
|
2021-05-03 07:12:58 +00:00
|
|
|
var keys []string
|
|
|
|
for k := range u {
|
|
|
|
keys = append(keys, k)
|
|
|
|
}
|
|
|
|
sort.Strings(keys)
|
|
|
|
|
2023-04-18 13:21:46 +00:00
|
|
|
stmt := codegen.MapStatement{
|
|
|
|
Type: "bson.M",
|
|
|
|
}
|
2021-05-03 07:12:58 +00:00
|
|
|
for _, key := range keys {
|
2023-04-18 13:21:46 +00:00
|
|
|
applicationMap := codegen.MapStatement{
|
|
|
|
Type: "bson.M",
|
|
|
|
}
|
2021-03-31 11:44:31 +00:00
|
|
|
|
2021-05-03 07:12:58 +00:00
|
|
|
for _, field := range u[key] {
|
2023-04-18 13:21:46 +00:00
|
|
|
applicationMap.Pairs = append(applicationMap.Pairs, codegen.MapPair{
|
|
|
|
Key: field.BsonTag,
|
|
|
|
Value: codegen.Identifier(fmt.Sprintf("arg%d", field.ParamIndex)),
|
|
|
|
})
|
2021-03-31 11:44:31 +00:00
|
|
|
}
|
|
|
|
|
2023-04-18 13:21:46 +00:00
|
|
|
stmt.Pairs = append(stmt.Pairs, codegen.MapPair{
|
|
|
|
Key: key,
|
|
|
|
Value: applicationMap,
|
|
|
|
})
|
2021-02-24 12:02:57 +00:00
|
|
|
}
|
2023-04-18 13:21:46 +00:00
|
|
|
return stmt
|
2021-02-24 12:02:57 +00:00
|
|
|
}
|
|
|
|
|
2021-01-19 12:35:54 +00:00
|
|
|
type querySpec struct {
|
|
|
|
Operator spec.Operator
|
|
|
|
Predicates []predicate
|
|
|
|
}
|
|
|
|
|
2023-04-18 13:21:46 +00:00
|
|
|
func (q querySpec) Code() codegen.Statement {
|
|
|
|
var predicatePairs []codegen.MapPair
|
2021-01-24 08:31:21 +00:00
|
|
|
for _, predicate := range q.Predicates {
|
2023-04-18 13:21:46 +00:00
|
|
|
predicatePairs = append(predicatePairs, predicate.Code())
|
|
|
|
}
|
|
|
|
var predicateMaps []codegen.Statement
|
|
|
|
for _, pair := range predicatePairs {
|
|
|
|
predicateMaps = append(predicateMaps, codegen.MapStatement{
|
|
|
|
Pairs: []codegen.MapPair{pair},
|
|
|
|
})
|
2021-01-19 12:35:54 +00:00
|
|
|
}
|
|
|
|
|
2023-04-18 13:21:46 +00:00
|
|
|
stmt := codegen.MapStatement{
|
|
|
|
Type: "bson.M",
|
|
|
|
}
|
2021-01-19 12:35:54 +00:00
|
|
|
switch q.Operator {
|
|
|
|
case spec.OperatorOr:
|
2023-04-18 13:21:46 +00:00
|
|
|
stmt.Pairs = append(stmt.Pairs, codegen.MapPair{
|
|
|
|
Key: "$or",
|
|
|
|
Value: codegen.SliceStatement{
|
|
|
|
Type: code.ArrayType{
|
|
|
|
ContainedType: code.ExternalType{
|
|
|
|
PackageAlias: "bson",
|
|
|
|
Name: "M",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Values: predicateMaps,
|
|
|
|
},
|
|
|
|
})
|
2021-02-12 15:19:31 +00:00
|
|
|
case spec.OperatorAnd:
|
2023-04-18 13:21:46 +00:00
|
|
|
stmt.Pairs = append(stmt.Pairs, codegen.MapPair{
|
|
|
|
Key: "$and",
|
|
|
|
Value: codegen.SliceStatement{
|
|
|
|
Type: code.ArrayType{
|
|
|
|
ContainedType: code.ExternalType{
|
|
|
|
PackageAlias: "bson",
|
|
|
|
Name: "M",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Values: predicateMaps,
|
|
|
|
},
|
|
|
|
})
|
2021-01-19 12:35:54 +00:00
|
|
|
default:
|
2023-04-18 13:21:46 +00:00
|
|
|
stmt.Pairs = predicatePairs
|
2021-01-19 12:35:54 +00:00
|
|
|
}
|
2023-04-18 13:21:46 +00:00
|
|
|
return stmt
|
2021-01-19 12:35:54 +00:00
|
|
|
}
|
|
|
|
|
2021-01-19 12:26:26 +00:00
|
|
|
type predicate struct {
|
2021-01-19 12:35:54 +00:00
|
|
|
Field string
|
|
|
|
Comparator spec.Comparator
|
2021-01-27 12:15:25 +00:00
|
|
|
ParamIndex int
|
2021-01-19 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
2023-04-18 13:21:46 +00:00
|
|
|
func (p predicate) Code() codegen.MapPair {
|
|
|
|
argStmt := codegen.Identifier(fmt.Sprintf("arg%d", p.ParamIndex))
|
|
|
|
|
2021-01-19 12:35:54 +00:00
|
|
|
switch p.Comparator {
|
|
|
|
case spec.ComparatorEqual:
|
2023-04-18 13:21:46 +00:00
|
|
|
return p.createValueMapPair(argStmt)
|
2021-01-19 12:35:54 +00:00
|
|
|
case spec.ComparatorNot:
|
2023-04-18 13:21:46 +00:00
|
|
|
return p.createSingleComparisonMapPair("$ne", argStmt)
|
2021-01-19 12:35:54 +00:00
|
|
|
case spec.ComparatorLessThan:
|
2023-04-18 13:21:46 +00:00
|
|
|
return p.createSingleComparisonMapPair("$lt", argStmt)
|
2021-01-19 12:35:54 +00:00
|
|
|
case spec.ComparatorLessThanEqual:
|
2023-04-18 13:21:46 +00:00
|
|
|
return p.createSingleComparisonMapPair("$lte", argStmt)
|
2021-01-19 12:35:54 +00:00
|
|
|
case spec.ComparatorGreaterThan:
|
2023-04-18 13:21:46 +00:00
|
|
|
return p.createSingleComparisonMapPair("$gt", argStmt)
|
2021-01-19 12:35:54 +00:00
|
|
|
case spec.ComparatorGreaterThanEqual:
|
2023-04-18 13:21:46 +00:00
|
|
|
return p.createSingleComparisonMapPair("$gte", argStmt)
|
2021-01-24 08:31:21 +00:00
|
|
|
case spec.ComparatorBetween:
|
2023-04-18 13:21:46 +00:00
|
|
|
argStmt2 := codegen.Identifier(fmt.Sprintf("arg%d", p.ParamIndex+1))
|
|
|
|
return p.createBetweenMapPair(argStmt, argStmt2)
|
2021-01-22 02:56:30 +00:00
|
|
|
case spec.ComparatorIn:
|
2023-04-18 13:21:46 +00:00
|
|
|
return p.createSingleComparisonMapPair("$in", argStmt)
|
2021-02-23 12:10:25 +00:00
|
|
|
case spec.ComparatorNotIn:
|
2023-04-18 13:21:46 +00:00
|
|
|
return p.createSingleComparisonMapPair("$nin", argStmt)
|
2021-02-23 12:10:25 +00:00
|
|
|
case spec.ComparatorTrue:
|
2023-04-18 13:21:46 +00:00
|
|
|
return p.createValueMapPair(codegen.Identifier("true"))
|
2021-02-23 12:10:25 +00:00
|
|
|
case spec.ComparatorFalse:
|
2023-04-18 13:21:46 +00:00
|
|
|
return p.createValueMapPair(codegen.Identifier("false"))
|
2022-11-12 09:09:59 +00:00
|
|
|
case spec.ComparatorExists:
|
2023-04-18 13:21:46 +00:00
|
|
|
return p.createExistsMapPair("1")
|
2022-11-12 09:09:59 +00:00
|
|
|
case spec.ComparatorNotExists:
|
2023-04-18 13:21:46 +00:00
|
|
|
return p.createExistsMapPair("0")
|
|
|
|
}
|
|
|
|
return codegen.MapPair{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p predicate) createValueMapPair(
|
|
|
|
argStmt codegen.Statement) codegen.MapPair {
|
|
|
|
|
|
|
|
return codegen.MapPair{
|
|
|
|
Key: p.Field,
|
|
|
|
Value: argStmt,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p predicate) createSingleComparisonMapPair(comparatorKey string,
|
|
|
|
argStmt codegen.Statement) codegen.MapPair {
|
|
|
|
|
|
|
|
return codegen.MapPair{
|
|
|
|
Key: p.Field,
|
|
|
|
Value: codegen.MapStatement{
|
|
|
|
Type: "bson.M",
|
|
|
|
Pairs: []codegen.MapPair{{Key: comparatorKey, Value: argStmt}},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p predicate) createBetweenMapPair(argStmt codegen.Statement,
|
|
|
|
argStmt2 codegen.Statement) codegen.MapPair {
|
|
|
|
|
|
|
|
return codegen.MapPair{
|
|
|
|
Key: p.Field,
|
|
|
|
Value: codegen.MapStatement{
|
|
|
|
Type: "bson.M",
|
|
|
|
Pairs: []codegen.MapPair{
|
|
|
|
{Key: "$gte", Value: argStmt},
|
|
|
|
{Key: "$lte", Value: argStmt2},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p predicate) createExistsMapPair(existsValue string) codegen.MapPair {
|
|
|
|
return codegen.MapPair{
|
|
|
|
Key: p.Field,
|
|
|
|
Value: codegen.MapStatement{
|
|
|
|
Type: "bson.M",
|
|
|
|
Pairs: []codegen.MapPair{{
|
|
|
|
Key: "$exists",
|
|
|
|
Value: codegen.Identifier(existsValue),
|
|
|
|
}},
|
|
|
|
},
|
2021-01-19 12:26:26 +00:00
|
|
|
}
|
|
|
|
}
|