作者 yangfu

chore:add ExprAST

@@ -162,6 +162,97 @@ @@ -162,6 +162,97 @@
162 - [ ] 10W .. 162 - [ ] 10W ..
163 - [ ] 保存单个文件、压缩 | 保存多个文件、压缩 163 - [ ] 保存单个文件、压缩 | 保存多个文件、压缩
164 164
  165 +## 表达式解析
  166 +
  167 +### 表达式类型说明
  168 +- ValueExprAST: 值表达式(数值,字符串) e.g. 1 、 2011-1-1 、字符串
  169 +```json
  170 +{
  171 + "exprType":"ValueExprAST",
  172 + "val":"",
  173 + "str":"业绩2"
  174 +}
  175 +```
  176 +- FieldExprAST: 字段表达式(处理的字段) e.g. 生产明细.业绩
  177 +```json
  178 +{
  179 + "exprType":"FieldExprAST",
  180 + "str":"业绩1",
  181 + "field":{
  182 + "tableId":1,
  183 + "tableName":"测试ABC",
  184 + "tableSqlName":"table_abc_test",
  185 + "fieldName":"业绩",
  186 + "fieldSqlName":"ye_ji_1",
  187 + "fieldSqlType":"Float"
  188 + }
  189 +}
  190 +```
  191 +- BinaryExprAST: 二元表达式 e.g. 1 + 2 、 100 * 生产明细.业绩
  192 +```json
  193 +{
  194 + "exprType":"BinaryExprAST",
  195 + "op":"/",
  196 + "lhs":{},
  197 + "rhs":{}
  198 +}
  199 +```
  200 +
  201 +- FunCallerExprAST:函数表达式 e.g. sum(arg1,arg2,arg3)
  202 +```json
  203 +{
  204 + "arrayFlag": false,
  205 + "exprType": "FunCallerExprAST",
  206 + "name": "sum",
  207 + "args": []
  208 +}
  209 +```
  210 +
  211 +### 用例
  212 +- 输入表达式 `SUM(1/COUNTIFS(【业绩】,【业绩】))`
  213 +```json
  214 +{
  215 + "arrayFlag":false,
  216 + "exprType":"FunCallerExprAST",
  217 + "name":"sum",
  218 + "args":[
  219 + {
  220 + "exprType":"BinaryExprAST",
  221 + "op":"/",
  222 + "lhs":{
  223 + "exprType":"ValueExprAST",
  224 + "val":"",
  225 + "str":"1"
  226 + },
  227 + "rhs":{
  228 + "arrayFlag":false,
  229 + "exprType":"FunCallerExprAST",
  230 + "name":"countifs",
  231 + "args":[
  232 + {
  233 + "exprType":"FieldExprAST",
  234 + "str":"业绩1",
  235 + "field":{
  236 + "tableId":1,
  237 + "tableName":"测试ABC",
  238 + "tableSqlName":"table_abc_test",
  239 + "fieldName":"业绩",
  240 + "fieldSqlName":"ye_ji_1",
  241 + "fieldSqlType":"Float"
  242 + }
  243 + },
  244 + {
  245 + "exprType":"ValueExprAST",
  246 + "val":"",
  247 + "str":"业绩2"
  248 + }
  249 + ]
  250 + }
  251 + }
  252 + ]
  253 +}
  254 +```
  255 +
165 ## 讨论事项 256 ## 讨论事项
166 257
167 - [ ] 校验动作,参数模型讨论 258 - [ ] 校验动作,参数模型讨论
@@ -19,7 +19,14 @@ type AppendDataToTableCommand struct { @@ -19,7 +19,14 @@ type AppendDataToTableCommand struct {
19 } 19 }
20 20
21 func (cmd *AppendDataToTableCommand) Valid(validation *validation.Validation) { 21 func (cmd *AppendDataToTableCommand) Valid(validation *validation.Validation) {
22 - 22 + newMappingFields := make([]*domain.MappingField, 0)
  23 + for i := range cmd.MappingFields {
  24 + if len(cmd.MappingFields[i].VerifiedFileFieldName) == 0 {
  25 + continue
  26 + }
  27 + newMappingFields = append(newMappingFields, cmd.MappingFields[i])
  28 + }
  29 + cmd.MappingFields = newMappingFields
23 } 30 }
24 31
25 func (cmd *AppendDataToTableCommand) ValidateCommand() error { 32 func (cmd *AppendDataToTableCommand) ValidateCommand() error {
@@ -190,6 +190,9 @@ func (fileService *FileService) AppendDataToTable(ctx *domain.Context, cmd *comm @@ -190,6 +190,9 @@ func (fileService *FileService) AppendDataToTable(ctx *domain.Context, cmd *comm
190 if err := cmd.ValidateCommand(); err != nil { 190 if err := cmd.ValidateCommand(); err != nil {
191 return nil, application.ThrowError(application.ARG_ERROR, err.Error()) 191 return nil, application.ThrowError(application.ARG_ERROR, err.Error())
192 } 192 }
  193 + if len(cmd.MappingFields) == 0 {
  194 + return nil, factory.FastError(fmt.Errorf("请选择对应字段"))
  195 + }
193 transactionContext, err := factory.CreateTransactionContext(nil) 196 transactionContext, err := factory.CreateTransactionContext(nil)
194 if err != nil { 197 if err != nil {
195 return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) 198 return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  1 +package domain
  2 +
  3 +import (
  4 + "encoding/json"
  5 + "fmt"
  6 +)
  7 +
  8 +const (
  9 + TypeFunCallerExprAST = "FunCallerExprAST"
  10 + TypeBinaryExprAST = "BinaryExprAST"
  11 + TypeFieldExprAST = "FieldExprAST"
  12 + TypeValueExprAST = "ValueExprAST"
  13 +)
  14 +
  15 +type ExprAST interface {
  16 + toStr() string
  17 +}
  18 +
  19 +type ValueExprAST struct {
  20 + ExprType string `json:"exprType"`
  21 + Val string `json:"val"`
  22 + Str string `json:"str"`
  23 +}
  24 +
  25 +type FieldExprAST struct {
  26 + ExprType string `json:"exprType"`
  27 + Str string `json:"str"`
  28 + Field *TableField `json:"field"`
  29 +}
  30 +
  31 +type BinaryExprAST struct {
  32 + ExprType string `json:"exprType"`
  33 + Op string `json:"op"`
  34 + Lhs ExprAST `json:"lhs"`
  35 + Rhs ExprAST `json:"rhs"`
  36 +}
  37 +
  38 +type FunCallerExprAST struct {
  39 + ArrayFlag bool `json:"arrayFlag"`
  40 + ExprType string `json:"exprType"`
  41 + Name string `json:"name"`
  42 + Args []ExprAST `json:"args"`
  43 +}
  44 +
  45 +func (n ValueExprAST) toStr() string {
  46 + return fmt.Sprintf(
  47 + "ValueExprAST:%s",
  48 + n.Str,
  49 + )
  50 +}
  51 +
  52 +func (n FieldExprAST) toStr() string {
  53 + return fmt.Sprintf(
  54 + "FieldExprAST:%s",
  55 + n.Str,
  56 + )
  57 +}
  58 +
  59 +func (b BinaryExprAST) toStr() string {
  60 + return fmt.Sprintf(
  61 + "BinaryExprAST: (%s %s %s)",
  62 + b.Op,
  63 + b.Lhs.toStr(),
  64 + b.Rhs.toStr(),
  65 + )
  66 +}
  67 +
  68 +func (n FunCallerExprAST) toStr() string {
  69 + return fmt.Sprintf(
  70 + "FunCallerExprAST:%s",
  71 + n.Name,
  72 + )
  73 +}
  74 +
  75 +type CloneFunCallerExprAST struct {
  76 + ArrayFlag bool `json:"arrayFlag"`
  77 + Name string `json:"name"`
  78 + Arg []json.RawMessage `json:"args"`
  79 +}
  80 +
  81 +type CloneBinaryExprAST struct {
  82 + Op string `json:"op"`
  83 + Lhs json.RawMessage `json:"lhs"`
  84 + Rhs json.RawMessage `json:"rhs"`
  85 +}
  86 +
  87 +func AstExprUnmarshalJSON(data []byte) (interface{}, error) {
  88 + var m = make(map[string]interface{})
  89 + if err := json.Unmarshal(data, &m); err != nil {
  90 + return nil, err
  91 + }
  92 + value, err := unmarshalMapInterface(m, data)
  93 + if err != nil {
  94 + return data, err
  95 + }
  96 + return value, nil
  97 +}
  98 +
  99 +func unmarshalMapInterface(m map[string]interface{}, rawData []byte) (interface{}, error) {
  100 + t, ok := m["exprType"]
  101 + if !ok {
  102 + return nil, nil
  103 + }
  104 + if t == TypeFunCallerExprAST {
  105 + expr := &CloneFunCallerExprAST{}
  106 + if err := json.Unmarshal(rawData, expr); err != nil {
  107 + return nil, err
  108 + }
  109 + exprReturn := &FunCallerExprAST{Name: expr.Name, ExprType: TypeFunCallerExprAST}
  110 + for i := range expr.Arg {
  111 + subExpr, err := AstExprUnmarshalJSON(expr.Arg[i])
  112 + if err != nil {
  113 + return nil, err
  114 + }
  115 + if subExpr == nil {
  116 + continue
  117 + }
  118 + exprReturn.Args = append(exprReturn.Args, subExpr.(ExprAST))
  119 + }
  120 + return exprReturn, nil
  121 + }
  122 + if t == TypeBinaryExprAST {
  123 + expr := &CloneBinaryExprAST{}
  124 + if err := json.Unmarshal(rawData, expr); err != nil {
  125 + return nil, err
  126 + }
  127 + exprReturn := &BinaryExprAST{Op: expr.Op, ExprType: TypeBinaryExprAST}
  128 + if len(expr.Lhs) > 0 {
  129 + subExpr, err := AstExprUnmarshalJSON(expr.Lhs)
  130 + if err != nil {
  131 + return nil, err
  132 + }
  133 + if subExpr != nil {
  134 + exprReturn.Lhs = subExpr.(ExprAST)
  135 + }
  136 + }
  137 + if len(expr.Rhs) > 0 {
  138 + subExpr, err := AstExprUnmarshalJSON(expr.Rhs)
  139 + if err != nil {
  140 + return nil, err
  141 + }
  142 + if subExpr != nil {
  143 + exprReturn.Rhs = subExpr.(ExprAST)
  144 + }
  145 + }
  146 + return exprReturn, nil
  147 + }
  148 + if t == TypeFieldExprAST {
  149 + expr := &FieldExprAST{ExprType: TypeFieldExprAST}
  150 + if err := json.Unmarshal(rawData, expr); err != nil {
  151 + return nil, err
  152 + }
  153 + return expr, nil
  154 + }
  155 + if t == TypeValueExprAST {
  156 + expr := &ValueExprAST{ExprType: TypeValueExprAST}
  157 + if err := json.Unmarshal(rawData, expr); err != nil {
  158 + return nil, err
  159 + }
  160 + return expr, nil
  161 + }
  162 + return nil, fmt.Errorf("unkonw expr type '%v'", t)
  163 +}
  1 +package domain
  2 +
  3 +import (
  4 + "github.com/linmadan/egglib-go/utils/json"
  5 + "github.com/stretchr/testify/assert"
  6 + "testing"
  7 +)
  8 +
  9 +func TestAstExprUnmarshalJSON(t *testing.T) {
  10 + inputs := []struct {
  11 + data ExprAST
  12 + }{
  13 + {
  14 + data: &FunCallerExprAST{
  15 + Name: "if",
  16 + ExprType: TypeFunCallerExprAST,
  17 + Args: []ExprAST{
  18 + &BinaryExprAST{
  19 + ExprType: TypeBinaryExprAST,
  20 + Op: "<",
  21 + Lhs: &FieldExprAST{
  22 + ExprType: TypeFieldExprAST,
  23 + Str: "table.count",
  24 + },
  25 + Rhs: &FieldExprAST{
  26 + ExprType: TypeFieldExprAST,
  27 + Str: "100",
  28 + },
  29 + },
  30 + &FieldExprAST{
  31 + ExprType: TypeFieldExprAST,
  32 + Str: "200",
  33 + },
  34 + &FieldExprAST{
  35 + ExprType: TypeFieldExprAST,
  36 + Str: "300",
  37 + },
  38 + },
  39 + },
  40 + },
  41 + {
  42 + data: &FunCallerExprAST{
  43 + Name: "sum",
  44 + ExprType: TypeFunCallerExprAST,
  45 + Args: []ExprAST{
  46 + &BinaryExprAST{
  47 + ExprType: TypeBinaryExprAST,
  48 + Op: "/",
  49 + Lhs: &ValueExprAST{
  50 + ExprType: TypeValueExprAST,
  51 + Str: "1",
  52 + },
  53 + Rhs: &FunCallerExprAST{
  54 + ExprType: TypeFunCallerExprAST,
  55 + Name: "countifs",
  56 + Args: []ExprAST{
  57 + &FieldExprAST{
  58 + ExprType: TypeFieldExprAST,
  59 + Str: "业绩1",
  60 + Field: &TableField{
  61 + TableId: 1,
  62 + TableName: "测试ABC",
  63 + TableSqlName: "table_abc_test",
  64 + FieldName: "业绩",
  65 + FieldSqlName: "ye_ji_1",
  66 + FieldSQLType: "Float",
  67 + },
  68 + },
  69 + &ValueExprAST{
  70 + ExprType: TypeValueExprAST,
  71 + Str: "业绩2",
  72 + },
  73 + },
  74 + },
  75 + },
  76 + },
  77 + },
  78 + },
  79 + }
  80 +
  81 + for _, input := range inputs {
  82 + data, err := json.Marshal(input.data)
  83 + if err != nil {
  84 + t.Fatal(err)
  85 + }
  86 + v, err := AstExprUnmarshalJSON(data)
  87 + if err != nil {
  88 + t.Fatal(err)
  89 + }
  90 + if v != nil {
  91 +
  92 + }
  93 + assert.Equal(t, input.data, v)
  94 + }
  95 +}