1 Star 1 Fork 5

夏季的风/数据和文件存储组件

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
ExecuteResult.go 5.97 KB
一键复制 编辑 原始数据 按行查看 历史
lingbinbin 提交于 2022-08-23 18:27 +08:00 . -去除不必要的字段
package TDengineDB
import (
"errors"
"fmt"
"reflect"
"strings"
)
//DataHandFn 数据处理方法
type DataHandFn func(key string,sVal interface{})(tVal interface{})
//ExecuteResult 执行失败结果
//{
// "status":"error",
// "code":897,
// "desc":"Database already exists"
//}
//执行成功结果
//{
// "status":"succ",
// "head":["ts","current","voltage","phase","location","groupdid"],
// "data":[["2020-09-09 17:16:47.332",10.20000,219,0.32000,"Beijing.Chaoyang",2]],
// "rows":1
//}
/*
说明:
status: 告知操作结果是成功还是失败。
head: 表的定义,如果不返回结果集,则仅有一列“affected_rows”。(从 2.0.17 版本开始,建议不要依赖 head 返回值来判断数据列类型,而推荐使用 column_meta。在未来版本中,有可能会从返回值中去掉 head 这一项。)
column_meta: 从 2.0.17 版本开始,返回值中增加这一项来说明 data 里每一列的数据类型。具体每个列会用三个值来说明,分别为:列名、列类型、类型长度。例如["current",6,4]表示列名为“current”;列类型为 6,也即 float 类型;类型长度为 4,也即对应 4 个字节表示的 float。如果列类型为 binary 或 nchar,则类型长度表示该列最多可以保存的内容长度,而不是本次返回值中的具体数据长度。当列类型是 nchar 的时候,其类型长度表示可以保存的 unicode 字符数量,而不是 bytes。
data: 具体返回的数据,一行一行的呈现,如果不返回结果集,那么就仅有[[affected_rows]]。data 中每一行的数据列顺序,与 column_meta 中描述数据列的顺序完全一致。
rows: 表明总共多少行数据。
column_meta 中的列类型说明:
1:BOOL
2:TINYINT
3:SMALLINT
4:INT
5:BIGINT
6:FLOAT
7:DOUBLE
8:BINARY
9:TIMESTAMP
10:NCHAR
*/
type ExecuteResult struct {
ColNames []string //列名
ColTypes []int //列类型
ColLength []int64 //列长度
Data [][]interface{} //数据二维数组切片
Rows int //影响行数
Code int //错误码
Desc string //错误描述
}
//GetAffectedRows 获取受影响行数
func (e *ExecuteResult) GetAffectedRows() (int64,error) {
if len(e.Data) == 0 {
return 0, errors.New("结果集为空")
}
val := e.Data[0][0]
switch val.(type) {
case int64:
return val.(int64), nil
case uint64:
return int64(val.(uint64)), nil
case float64:
return int64(val.(float64)), nil
case float32:
return int64(val.(float32)), nil
case int32:
return int64(val.(int32)), nil
case uint32:
return int64(val.(uint32)), nil
case int:
return int64(val.(int)), nil
}
return 0, errors.New(fmt.Sprint("查询结果转换异常:", val))
}
//ToSliceMap 获取执行结果转切片map
func (e *ExecuteResult) ToSliceMap() ([]map[string]interface{},error) {
// 2.0.17 版本
result := make([]map[string]interface{}, 0, len(e.Data))
for _, rows := range e.Data {
count := len(rows)
row := make(map[string]interface{}, count)
for i := 0; i < count; i++ {
row[e.ColNames[i]] = rows[i]
}
result = append(result, row)
}
return result, nil
}
//ToSlice 转换为切片对象
func (e *ExecuteResult) ToSlice(results interface{}) error {
reflectRawSlice := reflect.TypeOf(results)
rawKind := reflectRawSlice.Kind()
rawElement := reflectRawSlice.Elem()
if (rawKind == reflect.Ptr && rawElement.Kind() != reflect.Slice) ||
(rawKind != reflect.Ptr && rawKind != reflect.Slice) {
return fmt.Errorf("Incompatible Value, Looking For Slice : %v : %v", rawKind, rawElement.Kind())
}
// Create a slice large enough to decode all the values
valSlice := reflect.MakeSlice(rawElement, len(e.Data), len(e.Data))
rowIndex := make(map[string]int, len(e.ColNames))
for key,val := range e.ColNames {
rowIndex[strings.ToLower(val)] = key
}
for key, rows := range e.Data {
//创建新实例
sliceElementType := rawElement.Elem()
var obj reflect.Value //对象的指针对应的reflect.Value
if sliceElementType.Kind() != reflect.Ptr {
// A slice of objects
obj = reflect.New(rawElement.Elem()) //返回对象的指针对应的reflect.Value
} else {
// A slice of pointers
obj = reflect.New(rawElement.Elem().Elem()) //返回对象的指针对应的reflect.Value
}
trueValue:= obj.Elem()
objType := trueValue.Type()
for i:= 0; i < objType.NumField();i++ {
fieldType := objType.Field(i)
name := strings.ToLower(fieldType.Name)
if val,ok := rowIndex[name];ok {
fieldVal := trueValue.Field(i)
typ := e.ColTypes[val]
switch typ {
case 0: //TSDB_DATA_TYPE_NULL
break
case 1: //TSDB_DATA_TYPE_BOOL
fieldVal.SetBool(rows[val].(bool))
break
case 2: //TSDB_DATA_TYPE_TINYINT
fieldVal.SetInt(int64(rows[val].(int8)))
break
case 3: //TSDB_DATA_TYPE_SMALLINT
fieldVal.SetInt(int64(rows[val].(int16)))
break
case 4: //TSDB_DATA_TYPE_INT
fieldVal.SetInt(int64(rows[val].(int32)))
break
case 5: //TSDB_DATA_TYPE_BIGINT
fieldVal.SetInt(rows[val].(int64))
break
case 6://TSDB_DATA_TYPE_FLOAT
fieldVal.SetFloat(float64(rows[val].(float32)))
break
case 7://TSDB_DATA_TYPE_DOUBLE
fieldVal.SetFloat(rows[val].(float64))
break
case 8://TSDB_DATA_TYPE_BINARY
fieldVal.SetString(rows[val].(string))
break
case 9: //TSDB_DATA_TYPE_TIMESTAMP
fieldVal.Set(reflect.ValueOf(rows[val]))
break
case 10://TSDB_DATA_TYPE_NCHAR
fieldVal.SetString(rows[val].(string))
break
case 11://TSDB_DATA_TYPE_UTINYINT
fieldVal.SetUint(uint64(rows[val].(uint8)))
break
case 12://TSDB_DATA_TYPE_USMALLINT
fieldVal.SetUint(uint64(rows[val].(uint16)))
break
case 13://TSDB_DATA_TYPE_UINT
fieldVal.SetUint(uint64(rows[val].(uint32)))
break
case 14://TSDB_DATA_TYPE_UBIGINT
fieldVal.SetUint(rows[val].(uint64))
break
}
}
}
indexVal := valSlice.Index(key)
indexVal.Set(obj)
}
reflect.ValueOf(results).Elem().Set(valSlice)
return nil
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/ling-bin/repository.git
git@gitee.com:ling-bin/repository.git
ling-bin
repository
数据和文件存储组件
v1.6.22

搜索帮助