dal/pkg/proto/request.go

68 lines
1.6 KiB
Go
Raw Normal View History

package proto
import (
"fmt"
"reflect"
"slices"
"strings"
"l12.xyz/dal/adapter"
"l12.xyz/dal/builder"
)
//go:generate msgp
type BuilderMethod struct {
Method string `msg:"method"`
Args []interface{} `msg:"args"`
}
type Request struct {
Id uint32 `msg:"id"`
Db string `msg:"db"`
Commands []BuilderMethod `msg:"commands"`
}
var allowedMethods = strings.Split(builder.BUILDER_CLIENT_METHODS, "|")
func (q *Request) Parse(dialect adapter.Dialect) (adapter.Query, error) {
if q.Db == "" {
return adapter.Query{}, fmt.Errorf("Request format: db url is required")
}
if len(q.Commands) == 0 {
return adapter.Query{}, fmt.Errorf("Request format: commands are required")
}
b := builder.New(dialect)
exec := false
for _, cmd := range q.Commands {
if !slices.Contains(allowedMethods, cmd.Method) {
return adapter.Query{}, fmt.Errorf(
"method %s is not allowed, available methods are %v",
cmd.Method,
allowedMethods,
)
}
method := reflect.ValueOf(b).MethodByName(cmd.Method)
if !method.IsValid() {
return adapter.Query{}, fmt.Errorf("method %s not found", cmd.Method)
}
if cmd.Method == "Insert" || cmd.Method == "Set" || cmd.Method == "Delete" {
exec = true
}
args := make([]reflect.Value, len(cmd.Args))
for i, arg := range cmd.Args {
args[i] = reflect.ValueOf(arg)
}
fmt.Print(exec, cmd.Method, args)
method.Call(args)
}
expr, data := b.Sql()
return adapter.Query{
Db: q.Db,
Expression: expr,
Data: data,
Transaction: b.Transaction,
Exec: exec,
}, nil
}