api2sql基础的能力 #8
@ -13,6 +13,7 @@ import (
 | 
				
			|||||||
	"git.zhangdeman.cn/zhangdeman/consts"
 | 
						"git.zhangdeman.cn/zhangdeman/consts"
 | 
				
			||||||
	"git.zhangdeman.cn/zhangdeman/database/abstract"
 | 
						"git.zhangdeman.cn/zhangdeman/database/abstract"
 | 
				
			||||||
	"git.zhangdeman.cn/zhangdeman/database/define"
 | 
						"git.zhangdeman.cn/zhangdeman/database/define"
 | 
				
			||||||
 | 
						"git.zhangdeman.cn/zhangdeman/wrapper"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
@ -121,5 +122,69 @@ func (e *execute) Delete(ctx context.Context, inputParam *define.Api2SqlParam) (
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
// Date : 20:51 2024/8/21
 | 
					// Date : 20:51 2024/8/21
 | 
				
			||||||
func (e *execute) Express(ctx context.Context, inputParam *define.Api2SqlParam) (any, error) {
 | 
					func (e *execute) Express(ctx context.Context, inputParam *define.Api2SqlParam) (any, error) {
 | 
				
			||||||
 | 
						if nil == e.databaseClientManager {
 | 
				
			||||||
 | 
							return nil, errors.New("database client is nil, please use `SetDatabaseClientManager` set instance")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// 格式化 inputParam
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// formatAndValidateInputParam 格式化并校验输入参数
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Author : go_developer@163.com<白茶清欢>
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Date : 10:38 2024/8/22
 | 
				
			||||||
 | 
					func (e *execute) formatAndValidateInputParam(inputParam *define.Api2SqlParam) error {
 | 
				
			||||||
 | 
						if nil == inputParam {
 | 
				
			||||||
 | 
							return errors.New("inputParam is nil")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(inputParam.DatabaseFlag) == 0 {
 | 
				
			||||||
 | 
							return errors.New("databaseFlag is empty")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(inputParam.Table) == 0 {
 | 
				
			||||||
 | 
							return errors.New("table is empty")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(inputParam.SqlType) == 0 {
 | 
				
			||||||
 | 
							return errors.New("sqlType is empty")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						databaseClient, err := e.databaseClientManager.GetDBClient(inputParam.DatabaseFlag)
 | 
				
			||||||
 | 
						if nil != err {
 | 
				
			||||||
 | 
							return errors.New(inputParam.DatabaseFlag + " : database client get fail -> " + err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// 尝试获取表结构, api 转 sql 要求必须开启表结构缓存, 否则无法确定相关数据如何解析
 | 
				
			||||||
 | 
						if inputParam.TableColumnConfig, err = databaseClient.GetTableFieldList(inputParam.Table); nil != err {
 | 
				
			||||||
 | 
							return errors.New(inputParam.DatabaseFlag + " : get table field list fail -> " + err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(inputParam.TableColumnConfig) == 0 {
 | 
				
			||||||
 | 
							return errors.New(inputParam.DatabaseFlag + " : table field list is empty, please enable `CacheDataTableStructureConfig` or `SetTableColumnConfig`")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// 操作字段列表为空
 | 
				
			||||||
 | 
						if len(inputParam.ColumnList) == 0 && wrapper.ArrayType[string]([]string{
 | 
				
			||||||
 | 
							consts.SqlTypeList, consts.SqlTypeDetail,
 | 
				
			||||||
 | 
						}).Has(inputParam.SqlType) >= 0 {
 | 
				
			||||||
 | 
							for _, itemParam := range inputParam.TableColumnConfig {
 | 
				
			||||||
 | 
								inputParam.ColumnList = append(inputParam.ColumnList, itemParam.ColumnName)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// 验证字段是否都正确
 | 
				
			||||||
 | 
						tableColumnTable := make(map[string]bool)
 | 
				
			||||||
 | 
						for _, itemColumn := range inputParam.TableColumnConfig {
 | 
				
			||||||
 | 
							tableColumnTable[itemColumn.ColumnName] = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, item := range inputParam.ColumnList {
 | 
				
			||||||
 | 
							if !tableColumnTable[item] {
 | 
				
			||||||
 | 
								return errors.New(item + " : input column not found in table column list")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, item := range inputParam.ValueList {
 | 
				
			||||||
 | 
							if !tableColumnTable[item.Column] {
 | 
				
			||||||
 | 
								return errors.New(item.Column + " : input column in `ValueList` is not found in table column list")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// 验证 force no limit
 | 
				
			||||||
 | 
						if inputParam.ForceNoLimit {
 | 
				
			||||||
 | 
							inputParam.Limit = 0
 | 
				
			||||||
 | 
							inputParam.WithCount = false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -12,18 +12,35 @@ package define
 | 
				
			|||||||
// Author : go_developer@163.com<白茶清欢>
 | 
					// Author : go_developer@163.com<白茶清欢>
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Date : 16:06 2024/8/21
 | 
					// Date : 16:06 2024/8/21
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 一个合法的 sql 配置格式 :
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// select 语句 : SELECT {FIELD_LIST} FROM {TABLE} WHERE {WHERE} ORDER BY {ORDER_FIELD} {ORDER_RULE} LIMIT {LIMIT} OFFSET {OFFSET}
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// insert 语句 : INSERT INTO {TABLE} ({FIELD_LIST}) VALUES ({VALUE_LIST})
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// update 语句 : UPDATE {TABLE} SET {SET} WHERE {WHERE} LIMIT {LIMIT} OFFSET {OFFSET} ORDER BY {ORDER_FIELD} {ORDER_RULE}
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// delete 语句 : DELETE FROM {TABLE} WHERE {WHERE} LIMIT {LIMIT} OFFSET {OFFSET} ORDER BY {ORDER_FIELD} {ORDER_RULE}
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// count 语句 : SELECT COUNT(*) FROM {TABLE} WHERE {WHERE}
 | 
				
			||||||
type Api2SqlParam struct {
 | 
					type Api2SqlParam struct {
 | 
				
			||||||
	DatabaseFlag  string               `json:"database_flag"`  // 数据库标识
 | 
						DatabaseFlag      string               `json:"database_flag"`       // 数据库标识
 | 
				
			||||||
	InputSql      string               `json:"input_sql"`      // 输入的sql模板, 仅依赖 ValueList 解析字段值, 依赖 split 相关解析分表配置
 | 
						Table             string               `json:"table"`               // 操作的数据表
 | 
				
			||||||
	TableSplit    bool                 `json:"table_split"`    // 是否分表
 | 
						InputSql          string               `json:"input_sql"`           // 输入的sql模板, 仅依赖 ValueList 解析字段值, 依赖 split 相关解析分表配置
 | 
				
			||||||
	SplitField    string               `json:"split_field"`    // 分表字段, 仅分表时有效, 分表字段要求在 ValueList 必须存在
 | 
						TableSplit        bool                 `json:"table_split"`         // 是否分表
 | 
				
			||||||
	SplitStrategy string               `json:"split_strategy"` // 分表策略, 仅分表时有效, 支持注册自动以策略
 | 
						SplitField        string               `json:"split_field"`         // 分表字段, 仅分表时有效, 分表字段要求在 ValueList 必须存在
 | 
				
			||||||
	SqlType       string               `json:"sql_type"`       // sql语句类型 : detail - 查询详情 list - 查询列表  count - 查询数量 update - 更新 insert - 插入 delete - 删除
 | 
						SplitStrategy     string               `json:"split_strategy"`      // 分表策略, 仅分表时有效, 支持注册自动以策略
 | 
				
			||||||
	FieldList     []string             `json:"field_list"`     // 仅针对 select / detail 有效, 查询的字段列表
 | 
						SqlType           string               `json:"sql_type"`            // sql语句类型 : detail - 查询详情 list - 查询列表  count - 查询数量 update - 更新 insert - 插入 delete - 删除
 | 
				
			||||||
	OrderField    string               `json:"order_field"`    // 排序字段, 仅 sqlType = list 生效
 | 
						ColumnList        []string             `json:"column_list"`         // 仅针对 select / detail 有效, 查询的字段列表
 | 
				
			||||||
	OrderRule     string               `json:"order_rule"`     // 排序规则, Asc / Desc
 | 
						Limit             int64                `json:"limit"`               // 操作数据量
 | 
				
			||||||
	WithCount     bool                 `json:"with_count"`     // 是否返回数据总量, 仅 sqlType = list 生效
 | 
						Offset            int64                `json:"offset"`              // 操作偏移量
 | 
				
			||||||
	ValueList     []*Api2SqlParamValue `json:"value_list"`     // 字段列表
 | 
						ForceNoLimit      bool                 `json:"force_no_limit"`      // 强制允许不限制 : 正常操作 select / delete / update 均需要指定本次操作数据量, 如果确定不限制, 此参数设置为 `true` , sqlType = list , 且 ForceNoLimit = true 时,  WithCount 参数无效
 | 
				
			||||||
 | 
						OrderField        string               `json:"order_field"`         // 排序字段, 仅 sqlType = list 生效
 | 
				
			||||||
 | 
						OrderRule         string               `json:"order_rule"`          // 排序规则, Asc / Desc
 | 
				
			||||||
 | 
						WithCount         bool                 `json:"with_count"`          // 是否返回数据总量, 仅 sqlType = list 生效
 | 
				
			||||||
 | 
						ValueList         []*Api2SqlParamValue `json:"value_list"`          // 字段列表
 | 
				
			||||||
 | 
						TableColumnConfig []*ColumnInfo        `json:"table_column_config"` // 表字段配置
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Api2SqlParamValue ...
 | 
					// Api2SqlParamValue ...
 | 
				
			||||||
@ -32,9 +49,9 @@ type Api2SqlParam struct {
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
// Date : 16:11 2024/8/21
 | 
					// Date : 16:11 2024/8/21
 | 
				
			||||||
type Api2SqlParamValue struct {
 | 
					type Api2SqlParamValue struct {
 | 
				
			||||||
	Field      string `json:"field"`       // 表字段
 | 
						Column   string `json:"column"` // 表字段
 | 
				
			||||||
	Value      any    `json:"value"`       // 数据字段的值
 | 
						Value    any    `json:"value"`  // 数据字段的值
 | 
				
			||||||
	OutputName string `json:"output_name"` // 字段对外输出的名字, 不配置, 默认 与 Field 一致
 | 
						Alias    string `json:"alias"`  // 字段对外输出的名字, 不配置, 默认 与 Field 一致, 仅查询语句生效
 | 
				
			||||||
	Default    any    `json:"-"`           // 默认值 TODO : 配置默认值生成策略
 | 
						Default  any    `json:"-"`      // 默认值 TODO : 配置默认值生成策略
 | 
				
			||||||
	DataMask   any    `json:"-"`           // 数据脱敏策略
 | 
						DataMask any    `json:"-"`      // 数据脱敏策略
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user