!126 feat: 解析达梦特殊字段

* feat: 解析达梦特殊字段
This commit is contained in:
zongyangleo
2024-11-26 04:04:09 +00:00
committed by Coder慌
parent cda2963e1c
commit 2b712cd548
18 changed files with 173 additions and 62 deletions

View File

@@ -3,10 +3,13 @@ package dbi
import (
"context"
"database/sql"
"encoding/hex"
"fmt"
"gitee.com/chunanyong/dm"
"mayfly-go/internal/machine/mcm"
"mayfly-go/pkg/errorx"
"mayfly-go/pkg/logx"
"mayfly-go/pkg/utils/anyx"
"reflect"
"strconv"
"strings"
@@ -173,7 +176,6 @@ func walkQueryRows(ctx context.Context, db *sql.DB, selectSql string, walkFn Wal
// 这里表示一行填充数据
scans := make([]any, lenCols)
// 这里表示一行所有列的值,用[]byte表示
values := make([][]byte, lenCols)
for k, colType := range colTypes {
// 处理字段名,如果为空,则命名为匿名列
colName := colType.Name()
@@ -182,7 +184,13 @@ func walkQueryRows(ctx context.Context, db *sql.DB, selectSql string, walkFn Wal
}
cols[k] = &QueryColumn{Name: colName, Type: colType.DatabaseTypeName()}
// 这里scans引用values把数据填充到[]byte里
scans[k] = &values[k]
if cols[k].Type == "st_point" { // 达梦的空间坐标数据
var point dm.DmStruct
scans[k] = &point
} else {
var s = make([]byte, 0)
scans[k] = &s
}
}
for rows.Next() {
@@ -193,7 +201,7 @@ func walkQueryRows(ctx context.Context, db *sql.DB, selectSql string, walkFn Wal
// 每行数据
rowData := make(map[string]any, lenCols)
// 把values中的数据复制到row中
for i, v := range values {
for i, v := range scans {
rowData[cols[i].Name] = valueConvert(v, colTypes[i])
}
if err = walkFn(rowData, cols); err != nil {
@@ -206,27 +214,67 @@ func walkQueryRows(ctx context.Context, db *sql.DB, selectSql string, walkFn Wal
return cols, nil
}
func ParseDmStruct(dmStruct *dm.DmStruct) string {
if !dmStruct.Valid {
return ""
}
name, _ := dmStruct.GetSQLTypeName()
attributes, _ := dmStruct.GetAttributes()
arr := make([]string, len(attributes))
arr = append(arr, name, "(")
for i, v := range attributes {
if blb, ok1 := v.(*dm.DmBlob); ok1 {
if blb.Valid {
length, _ := blb.GetLength()
var dest = make([]byte, length)
_, _ = blb.Read(dest)
// 2进制转16进制字符串
hexStr := hex.EncodeToString(dest)
arr = append(arr, "0x", strings.ToUpper(hexStr))
}
} else {
arr = append(arr, anyx.ToString(v))
}
if i < len(attributes)-1 {
arr = append(arr, ",")
}
}
arr = append(arr, ")")
return strings.Join(arr, "")
}
// 将查询的值转为对应列类型的实际值,不全部转为字符串
func valueConvert(data []byte, colType *sql.ColumnType) any {
func valueConvert(data interface{}, colType *sql.ColumnType) any {
if data == nil {
return nil
}
// 达梦特殊数据类型
if dmStruct, ok := data.(*dm.DmStruct); ok {
return ParseDmStruct(dmStruct)
}
// 列的数据库类型名
colDatabaseTypeName := strings.ToLower(colType.DatabaseTypeName())
// 如果类型是bit则直接返回第一个字节即可
if strings.Contains(colDatabaseTypeName, "bit") {
return data[0]
}
if colDatabaseTypeName == "blob" {
return fmt.Sprintf("%x", data)
// 这里把[]byte数据转成string
stringV := ""
if slicePtr, ok := data.(*[]uint8); ok {
stringV = string(*slicePtr)
// 如果类型是bit则直接返回第一个字节即可
if strings.Contains(colDatabaseTypeName, "bit") {
return (*slicePtr)[0]
}
if colDatabaseTypeName == "blob" {
return hex.EncodeToString(*slicePtr)
}
}
// 这里把[]byte数据转成string
stringV := string(data)
if stringV == "" {
return ""
}
if colType == nil || colType.ScanType() == nil {
return stringV
}

View File

@@ -56,7 +56,7 @@ select a.owner,
a.table_name as TABLE_NAME,
a.column_name as COLUMN_NAME,
case when a.NULLABLE = 'Y' then 'YES' when a.NULLABLE = 'N' then 'NO' else 'NO' end as NULLABLE,
a.data_type as DATA_TYPE,
case when t3.TYPE_NAME != '' then 'SYSGEO.' || UPPER(t3.TYPE_NAME) else a.DATA_TYPE end as DATA_TYPE,
a.char_col_decl_length as CHAR_MAX_LENGTH,
a.data_precision as NUM_PRECISION,
a.data_scale as NUM_SCALE,
@@ -77,6 +77,7 @@ from all_tab_columns a
from all_ind_columns uic
left join all_constraints uc on uic.index_name = uc.index_name) t2
on t2.table_name = t.object_name and a.column_name = t2.column_name and t2.OWNER = a.owner
left join USER_TYPES t3 ON ('CLASS' || t3.TYPEID) = a.DATA_TYPE
where a.owner = (SELECT SF_GET_SCHEMA_NAME_BY_ID(CURRENT_SCHID))
and a.table_name in (%s)
order by a.table_name,

View File

@@ -230,11 +230,11 @@ func (dd *DMDialect) GenerateIndexDDL(indexs []dbi.Index, tableInfo dbi.Table) [
}
func (dd *DMDialect) GetDataHelper() dbi.DataHelper {
return new(DataHelper)
return dataHelper
}
func (dd *DMDialect) GetColumnHelper() dbi.ColumnHelper {
return new(ColumnHelper)
return columnHelper
}
func (dd *DMDialect) GetDumpHelper() dbi.DumpHelper {

View File

@@ -74,8 +74,14 @@ var (
dbi.CommonTypeEnum: "TEXT",
dbi.CommonTypeJSON: "TEXT",
}
dataHelper = &DataHelper{}
columnHelper = &ColumnHelper{}
)
func GetDataHelper() *DataHelper {
return dataHelper
}
type DataHelper struct {
}

View File

@@ -371,11 +371,11 @@ func (dx *MssqlDialect) RemoveQuote(name string) string {
}
func (md *MssqlDialect) GetDataHelper() dbi.DataHelper {
return new(DataHelper)
return dataHelper
}
func (md *MssqlDialect) GetColumnHelper() dbi.ColumnHelper {
return new(ColumnHelper)
return columnHelper
}
func (md *MssqlDialect) GetDumpHelper() dbi.DumpHelper {

View File

@@ -84,8 +84,14 @@ var (
dbi.CommonTypeEnum: "nvarchar",
dbi.CommonTypeJSON: "nvarchar",
}
dataHelper = &DataHelper{}
columnHelper = &ColumnHelper{}
)
func GetDataHelper() *DataHelper {
return dataHelper
}
type DataHelper struct {
}

View File

@@ -209,11 +209,11 @@ func (md *MysqlDialect) QuoteLiteral(literal string) string {
}
func (md *MysqlDialect) GetDataHelper() dbi.DataHelper {
return new(DataHelper)
return dataHelper
}
func (md *MysqlDialect) GetColumnHelper() dbi.ColumnHelper {
return new(ColumnHelper)
return columnHelper
}
func (pd *MysqlDialect) GetSQLParser() sqlparser.SqlParser {

View File

@@ -75,8 +75,14 @@ var (
dbi.CommonTypeEnum: "enum",
dbi.CommonTypeJSON: "json",
}
dataHelper = &DataHelper{}
columnHelper = &ColumnHelper{}
)
func GetDataHelper() *DataHelper {
return dataHelper
}
type DataHelper struct {
}

View File

@@ -256,11 +256,11 @@ func (od *OracleDialect) GenerateTableOtherDDL(tableInfo dbi.Table, quoteTableNa
}
func (od *OracleDialect) GetDataHelper() dbi.DataHelper {
return new(DataHelper)
return dataHelper
}
func (od *OracleDialect) GetColumnHelper() dbi.ColumnHelper {
return new(ColumnHelper)
return columnHelper
}
func (od *OracleDialect) genColumnBasicSql(column dbi.Column) string {

View File

@@ -68,8 +68,15 @@ var (
dbi.CommonTypeEnum: "CLOB",
dbi.CommonTypeJSON: "CLOB",
}
dataHelper = &DataHelper{}
columnHelper = &ColumnHelper{}
)
func GetDataHelper() *DataHelper {
return dataHelper
}
type DataHelper struct {
}

View File

@@ -282,11 +282,11 @@ func (pd *PgsqlDialect) UpdateSequence(tableName string, columns []dbi.Column) {
}
func (pd *PgsqlDialect) GetDataHelper() dbi.DataHelper {
return new(DataHelper)
return dataHelper
}
func (pd *PgsqlDialect) GetColumnHelper() dbi.ColumnHelper {
return new(ColumnHelper)
return columnHelper
}
func (pd *PgsqlDialect) GetDumpHelper() dbi.DumpHelper {

View File

@@ -73,8 +73,14 @@ var (
dbi.CommonTypeEnum: "varchar(2000)",
dbi.CommonTypeJSON: "varchar(2000)",
}
dataHelper = &DataHelper{}
columnHelper = &ColumnHelper{}
)
func GetDataHelper() *DataHelper {
return dataHelper
}
type DataHelper struct {
}

View File

@@ -171,11 +171,11 @@ func (sd *SqliteDialect) GenerateIndexDDL(indexs []dbi.Index, tableInfo dbi.Tabl
}
func (sd *SqliteDialect) GetDataHelper() dbi.DataHelper {
return new(DataHelper)
return dataHelper
}
func (sd *SqliteDialect) GetColumnHelper() dbi.ColumnHelper {
return new(ColumnHelper)
return columnHelper
}
func (sd *SqliteDialect) GetDumpHelper() dbi.DumpHelper {

View File

@@ -74,8 +74,14 @@ var (
dbi.CommonTypeEnum: "nvarchar(2000)",
dbi.CommonTypeJSON: "nvarchar(2000)",
}
dataHelper = &DataHelper{}
columnHelper = &ColumnHelper{}
)
func GetDataHelper() *DataHelper {
return dataHelper
}
type DataHelper struct {
}