From 1b5bb1de8b5fdd00278d36accbb7f54f176f43bd Mon Sep 17 00:00:00 2001 From: zongyangleo Date: Fri, 31 May 2024 21:02:31 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20mysql=E5=AF=BC=E5=87=BA=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/internal/db/application/db_transfer.go | 11 +++++++++++ server/internal/db/dbm/dbi/conn.go | 3 +++ server/internal/db/dbm/dbi/metadata.go | 9 +++++++++ server/internal/db/dbm/mysql/helper.go | 10 ++++++++++ 4 files changed, 33 insertions(+) diff --git a/server/internal/db/application/db_transfer.go b/server/internal/db/application/db_transfer.go index 1c06b65b..aea27c82 100644 --- a/server/internal/db/application/db_transfer.go +++ b/server/internal/db/application/db_transfer.go @@ -2,6 +2,7 @@ package application import ( "context" + "encoding/hex" "fmt" "mayfly-go/internal/db/dbm/dbi" "mayfly-go/internal/db/domain/entity" @@ -326,6 +327,8 @@ func (app *dbTransferAppImpl) transfer2Target(taskId uint64, targetConn *dbi.DbC columnNames = append(columnNames, targetMeta.QuoteIdentifier(col.ColumnName)) } + dataHelper := targetMeta.GetDataHelper() + // 从目标库数据中取出源库字段对应的值 values := make([][]any, 0) for _, record := range result { @@ -342,6 +345,14 @@ func (app *dbTransferAppImpl) transfer2Target(taskId uint64, targetConn *dbi.DbC } } } + + if dataHelper.GetDataType(string(tc.DataType)) == dbi.DataTypeBlob { + decodeBytes, err := hex.DecodeString(val.(string)) + if err == nil { + val = decodeBytes + } + } + rawValue = append(rawValue, val) } values = append(values, rawValue) diff --git a/server/internal/db/dbm/dbi/conn.go b/server/internal/db/dbm/dbi/conn.go index fa386922..9d512179 100644 --- a/server/internal/db/dbm/dbi/conn.go +++ b/server/internal/db/dbm/dbi/conn.go @@ -214,6 +214,9 @@ func valueConvert(data []byte, colType *sql.ColumnType) any { if strings.Contains(colDatabaseTypeName, "bit") { return data[0] } + if colDatabaseTypeName == "blob" { + return fmt.Sprintf("%x", data) + } // 这里把[]byte数据转成string stringV := string(data) diff --git a/server/internal/db/dbm/dbi/metadata.go b/server/internal/db/dbm/dbi/metadata.go index 7afe2c26..35017e5b 100644 --- a/server/internal/db/dbm/dbi/metadata.go +++ b/server/internal/db/dbm/dbi/metadata.go @@ -84,6 +84,13 @@ type Column struct { // 拼接数据类型与长度等。如varchar(2000),decimal(20,2) func (c *Column) GetColumnType() string { + // 哪些mysql数据类型不需要添加字段长度 + if collx.ArrayAnyMatches([]string{"int", "blob", "float", "double", "date", "year", "json"}, string(c.DataType)) { + return string(c.DataType) + } + if c.DataType == "timestamp" { + return "timestamp(6)" + } if c.CharMaxLength > 0 { return fmt.Sprintf("%s(%d)", c.DataType, c.CharMaxLength) } @@ -124,6 +131,7 @@ const ( CommonTypeVarbinary ColumnDataType = "varbinary" CommonTypeInt ColumnDataType = "int" + CommonTypeBit ColumnDataType = "bit" CommonTypeSmallint ColumnDataType = "smallint" CommonTypeTinyint ColumnDataType = "tinyint" CommonTypeNumber ColumnDataType = "number" @@ -146,6 +154,7 @@ const ( DataTypeDate DataType = "date" DataTypeTime DataType = "time" DataTypeDateTime DataType = "datetime" + DataTypeBlob DataType = "blob" ) // 列数据处理帮助方法 diff --git a/server/internal/db/dbm/mysql/helper.go b/server/internal/db/dbm/mysql/helper.go index 96affc3c..6bafff16 100644 --- a/server/internal/db/dbm/mysql/helper.go +++ b/server/internal/db/dbm/mysql/helper.go @@ -19,6 +19,8 @@ var ( // 时间类型 timeRegexp = regexp.MustCompile(`(?i)time`) + blobRegexp = regexp.MustCompile(`(?i)blob`) + // mysql数据类型 映射 公共数据类型 commonColumnTypeMap = map[string]dbi.ColumnDataType{ "bigint": dbi.CommonTypeBigint, @@ -37,6 +39,7 @@ var ( "longtext": dbi.CommonTypeLongtext, "mediumblob": dbi.CommonTypeBlob, "mediumtext": dbi.CommonTypeText, + "bit": dbi.CommonTypeBit, "set": dbi.CommonTypeVarchar, "smallint": dbi.CommonTypeSmallint, "text": dbi.CommonTypeText, @@ -60,6 +63,7 @@ var ( dbi.CommonTypeMediumtext: "text", dbi.CommonTypeVarbinary: "varbinary", dbi.CommonTypeInt: "int", + dbi.CommonTypeBit: "bit", dbi.CommonTypeSmallint: "smallint", dbi.CommonTypeTinyint: "tinyint", dbi.CommonTypeNumber: "decimal", @@ -92,6 +96,10 @@ func (dc *DataHelper) GetDataType(dbColumnType string) dbi.DataType { if timeRegexp.MatchString(dbColumnType) { return dbi.DataTypeTime } + // blob类型 + if blobRegexp.MatchString(dbColumnType) { + return dbi.DataTypeBlob + } return dbi.DataTypeString } @@ -157,6 +165,8 @@ func (dc *DataHelper) WrapValue(dbColumnValue any, dataType dbi.DataType) string case dbi.DataTypeDate, dbi.DataTypeDateTime, dbi.DataTypeTime: // mysql时间类型无需格式化 return fmt.Sprintf("'%s'", dbColumnValue) + case dbi.DataTypeBlob: + return fmt.Sprintf("unhex('%s')", dbColumnValue) } return fmt.Sprintf("'%s'", dbColumnValue) }