Skip to content

Commit

Permalink
access 中的req也与hook使用相同的field style + fix hook无法事务内
Browse files Browse the repository at this point in the history
  • Loading branch information
glennliao committed Jul 27, 2023
1 parent 2bbcb25 commit 33fdbd9
Show file tree
Hide file tree
Showing 11 changed files with 173 additions and 152 deletions.
79 changes: 41 additions & 38 deletions action/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ type Action struct {
NewAction func(ctx context.Context, method string, req model.Map) *Action

HooksMap map[string][]*Hook

ret model.Map
}

func New(ctx context.Context, actionConfig *config.ActionConfig, method string, req model.Map) *Action {
Expand Down Expand Up @@ -118,67 +120,68 @@ func (a *Action) parse() error {
return nil
}

func (a *Action) Result() (model.Map, error) {

err := a.parse()
if err != nil {
return nil, err
func (a *Action) hookExecute(i int, inTransaction bool) error {
k := a.tagRequest.ExecQueue[i]
node := a.children[k]
nodeHookReq := &HookReq{
Node: node,
Method: a.method,
ctx: a.ctx,
nextIdx: -1,
isInTransaction: inTransaction,
hooks: getHooksByAccessName(a.HooksMap, k),
}

ret := model.Map{}

for _, k := range a.tagRequest.ExecQueue {
node := a.children[k]
nodeHookReq.handler = func(ctx context.Context, n *Node, method string) error {

actionHookReq := &HookReq{
Node: node,
Method: a.method,
ctx: a.ctx,
nextIdx: -1,
isInTransaction: false,
hooks: getHooksByAccessName(a.HooksMap, k),
if i+1 < len(a.tagRequest.ExecQueue) {
return a.hookExecute(i+1, inTransaction)
}

actionHookReq.handler = func(ctx context.Context, n *Node, method string) error {
// 执行完了普通hook的before,开始执行事务内
if !inTransaction {

transactionHandler := noTransactionHandler

if a.tagRequest.Transaction != nil && *a.tagRequest.Transaction == true {
h := GetTransactionHandler(a.ctx, a)
if h == nil {
err = consts.NewSysErr("transaction handler is nil")
err := consts.NewSysErr("transaction handler is nil")
return err
}

transactionHandler = h

}

err = transactionHandler(a.ctx, func(ctx context.Context) error {
for _, k := range a.tagRequest.ExecQueue {
node := a.children[k]
ret[k], err = node.execute(ctx, a.method)
if err != nil {
return err
}
}
return nil
err := transactionHandler(a.ctx, func(ctx context.Context) error {
return a.hookExecute(0, !inTransaction)
})

return err
}

err = node.reqUpdate()
if err != nil {
return nil, err
}
var err error
a.ret[k], err = node.execute(ctx, a.method)
return err
}

err := actionHookReq.Next()
if err != nil {
return nil, err
}
err := nodeHookReq.Next()
return err
}

func (a *Action) Result() (model.Map, error) {

err := a.parse()
if err != nil {
return nil, err
}

return ret, nil
a.ret = model.Map{}

err = a.hookExecute(0, false)
if err != nil {
a.err = err
}
return a.ret, err
}

func checkTag(req model.Map, method string, requestCfg *config.ActionConfig) (*config.RequestConfig, error) {
Expand Down
72 changes: 10 additions & 62 deletions action/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,6 @@ import (
"net/http"
)

// const (
// BeforeNodeExec = iota
// AfterNodeExec
// BeforeExecutorDo
// AfterExecutorDo
// )

type HookReq struct {
Node *Node
Method string
Expand Down Expand Up @@ -40,17 +33,7 @@ func (r *HookReq) Next() error {

var h *Hook

for r.nextIdx < len(r.hooks) && h == nil {

if r.nextIdx+1 >= len(r.hooks) {
if r.isInTransaction {
// finish all
return r.handler(r.ctx, r.Node, r.Method)
} else {
r.nextIdx = -1
r.isInTransaction = true
}
}
for r.nextIdx+1 < len(r.hooks) && h == nil {

r.nextIdx++

Expand All @@ -70,13 +53,17 @@ func (r *HookReq) Next() error {

}

if r.nextIdx < len(r.hooks) {
if r.isInTransaction {
return h.HandlerInTransaction(r.ctx, r)
}
if h != nil {
if r.nextIdx < len(r.hooks) {
if r.isInTransaction {
return h.HandlerInTransaction(r.ctx, r)
}

return h.Handler(r.ctx, r)
return h.Handler(r.ctx, r)
}
}

return r.handler(r.ctx, r.Node, r.Method)
}

}
Expand All @@ -95,42 +82,3 @@ func getHooksByAccessName(hooksMap map[string][]*Hook, accessName string) []*Hoo
hooks := append(hooksMap["*"], hooksMap[accessName]...)
return hooks
}

//
// type Hook2 struct {
// For []string //
// // Exec 事务外
// BeforeNodeExec func(ctx context.Context, n *Node, method string) error
// AfterNodeExec func(ctx context.Context, n *Node, method string) error
//
// // Do 事务内
// BeforeExecutorDo func(ctx context.Context, n *Node, method string) error
// AfterExecutorDo func(ctx context.Context, n *Node, method string) error
// }
//
// func emitHook(ctx context.Context, hooksMap map[string][]Hook, hookAt int, node *Node, method string) error {
//
// hooks := append(hooksMap["*"], hooksMap[node.Key]...)
// for _, hook := range hooks {
//
// var handler func(ctx context.Context, n *Node, method string) error
// switch hookAt {
// case BeforeNodeExec:
// handler = hook.BeforeNodeExec
// case AfterNodeExec:
// handler = hook.AfterNodeExec
// case BeforeExecutorDo:
// handler = hook.BeforeExecutorDo
// case AfterExecutorDo:
// handler = hook.AfterExecutorDo
// }
//
// if handler != nil {
// err := handler(ctx, node, method)
// if err != nil {
// return err
// }
// }
// }
// return nil
// }
16 changes: 12 additions & 4 deletions action/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/glennliao/apijson-go/consts"
"github.com/glennliao/apijson-go/model"
"github.com/glennliao/apijson-go/util"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/samber/lo"
)

Expand Down Expand Up @@ -190,12 +191,19 @@ func (n *Node) whereUpdate(ctx context.Context, method string, accessRoles []str

condition := config.NewConditionRet()

req := model.Map{}

for k, v := range item {
k := n.Action.DbFieldStyle(ctx, n.RowKey, k)
req[k] = v
}

conditionReq := config.ConditionReq{
AccessName: n.Key,
TableAccessRoleList: accessRoles,
Method: method,
NodeRole: n.Role,
NodeReq: item,
NodeReq: req,
}

err := n.Action.ActionConfig.ConditionFunc(ctx, conditionReq, condition)
Expand All @@ -205,11 +213,11 @@ func (n *Node) whereUpdate(ctx context.Context, method string, accessRoles []str
}

if method == http.MethodPost {
for k, v := range condition.Where() {
for k, v := range condition.AllWhere() {
n.Data[i][k] = v
}
} else {
for k, v := range condition.Where() {
for k, v := range condition.AllWhere() {
n.Where[i][k] = v
}
}
Expand Down Expand Up @@ -343,7 +351,7 @@ func (n *Node) do(ctx context.Context, method string) (ret model.Map, err error)

rowKeyVal, err = n.Action.ActionConfig.RowKeyGen(ctx, access.RowKeyGen, n.Key, n.tableName, n.Data[i])
if err != nil {
return nil, err
return nil, gerror.Wrap(err, "RowKeyGen")
}

for k, v := range rowKeyVal {
Expand Down
9 changes: 9 additions & 0 deletions action/z_hook_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package action

import (
"testing"
)

func TestHook(t *testing.T) {

}
30 changes: 2 additions & 28 deletions config/access.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,6 @@ type ConditionReq struct {
NodeRole string // 节点的角色
}

type ConditionRet struct {
condition map[string]any
rawCondition map[string][]any
}

func NewConditionRet() *ConditionRet {
c := ConditionRet{
condition: map[string]any{},
rawCondition: map[string][]any{},
}
return &c
}

func (c *ConditionRet) Add(k string, v any) {
c.condition[k] = v
}

func (c *ConditionRet) AddRaw(k string, v ...any) {
c.rawCondition[k] = v
}

func (c *ConditionRet) Where() map[string]any {
if len(c.rawCondition) > 0 {
c.condition[consts.Raw] = c.rawCondition
}
return c.condition
}

type AccessCondition func(ctx context.Context, req ConditionReq, condition *ConditionRet) error

type RoleReq struct {
Expand Down Expand Up @@ -79,6 +51,8 @@ type Access struct {

func NewAccess() *Access {

// fixme 统一access字段名大小写问题
// fixme
a := &Access{}
a.ConditionFunc = defaultCondition
a.DefaultRoleFunc = defaultRole
Expand Down
33 changes: 33 additions & 0 deletions config/access_condition.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package config

import (
"github.com/glennliao/apijson-go/consts"
)

type ConditionRet struct {
condition map[string]any
rawCondition map[string][]any
}

func NewConditionRet() *ConditionRet {
c := ConditionRet{
condition: map[string]any{},
rawCondition: map[string][]any{},
}
return &c
}

func (c *ConditionRet) Add(k string, v any) {
c.condition[k] = v
}

func (c *ConditionRet) AddRaw(k string, v ...any) {
c.rawCondition[k] = v
}

func (c *ConditionRet) AllWhere() map[string]any {
if len(c.rawCondition) > 0 {
c.condition[consts.Raw] = c.rawCondition
}
return c.condition
}
15 changes: 10 additions & 5 deletions config/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,25 @@ import (
const (
ParamTypeInt = "int"
ParamTypeString = "string"
FromRes = "res" // 只从响应的数据字段中取, 不从用户传递的数据取
)

type ParamItem struct {
Type string
Name string
Desc string
Default any
From string // 指定参数从何处取值
V string // 参数校验规则
}

type Func struct {
Desc string // 描述
ParamList []ParamItem // 参数列表
Batch bool // 是否为批量处理, 例如在获取列表后一次性将id传入, 然后按照传入的参数数组返回结果数组
Handler func(ctx context.Context, param model.FuncParam) (res any, err error)
Desc string // 描述
// 参数可直接读取函数参数传递过来的, ''括起来
ParamList []ParamItem // 参数列表 // fixme 限制参数来源,强制用户传递的无法覆盖内部的,减免权限的重复判断, 参数校验限制 , v (最大值,最小值,默认值, 自定义校验。 使用gvaild)

Batch bool // 是否为批量处理, 例如在获取列表后一次性将id传入, 然后按照传入的参数数组返回结果数组
Handler func(ctx context.Context, param model.FuncParam) (res any, err error)
}

type functions struct {
Expand All @@ -49,7 +54,7 @@ func (f *functions) Call(ctx context.Context, name string, param g.Map) (any, er
return f.funcMap[name].Handler(ctx, params)
}

// functions 提供的功能
// functions 可能提供的功能
// 1. 增加响应字段 -> 该字段需要与系统中别的数据结合处理,如果只是静态处理(去空格,与常量拼接等可直接前端处理即可) 目前会不受_access_ext 中field_get控制, 需处理. 响应字段修改(脱敏、加密、字典转换) 不提供前端控制, 由_access_ext处理
// 2. 通过func节点获取一些系统信息
// 3. actions 中 自定义校验参数、自定义校验权限, 请求体修改(批量字段替换处理?)
Expand Down
Loading

0 comments on commit 33fdbd9

Please sign in to comment.