You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
go-library/vendor/gitee.com/chunanyong/zorm/ICustomDriverValueConver.go

142 lines
5.5 KiB

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package zorm
import (
"context"
"database/sql"
"database/sql/driver"
"errors"
"reflect"
"strings"
)
// customDriverValueMap 用于配置数据库字段类型的处理关系,key是 Dialect.字段类型,例如 dm.TEXT
var customDriverValueMap = make(map[string]ICustomDriverValueConver)
// iscdvm 是否有自定义的DriverValueMap
var iscdvm bool
// ICustomDriverValueConver 自定义类型转化接口,用于解决 类似达梦 text --> dm.DmClob --> string类型接收的问题
type ICustomDriverValueConver interface {
// GetDriverValue 根据数据库列类型,返回driver.Value的实例,struct属性类型
// map接收或者字段不存在,无法获取到structFieldType,会传入nil
GetDriverValue(ctx context.Context, columnType *sql.ColumnType, structFieldType *reflect.Type) (driver.Value, error)
// ConverDriverValue 数据库列类型,GetDriverValue返回的driver.Value的临时接收值,struct属性类型
// map接收或者字段不存在,无法获取到structFieldType,会传入nil
// 返回符合接收类型值的指针,指针,指针!!!!
ConverDriverValue(ctx context.Context, columnType *sql.ColumnType, tempDriverValue driver.Value, structFieldType *reflect.Type) (interface{}, error)
}
// RegisterCustomDriverValueConver 注册自定义的字段处理逻辑,用于驱动无法直接转换的场景,例如达梦的 TEXT 无法直接转化成 string
// dialectColumnType 值是 Dialect.字段类型,例如: dm.TEXT
// 一般是放到init方法里进行注册
func RegisterCustomDriverValueConver(dialectColumnType string, customDriverValueConver ICustomDriverValueConver) error {
if len(dialectColumnType) < 1 {
return errors.New("->RegisterCustomDriverValueConver-->dialectColumnType为空")
}
dialectColumnTypes := strings.Split(dialectColumnType, ".")
if len(dialectColumnTypes) < 2 {
customDriverValueMap[strings.ToUpper(dialectColumnType)] = customDriverValueConver
err := errors.New("->RegisterCustomDriverValueConver-->dialectColumnType 值是 Dialect.字段类型,例如: dm.TEXT ,本次正常运行,请尽快修改")
FuncLogError(nil, err)
} else {
customDriverValueMap[strings.ToLower(dialectColumnTypes[0])+"."+strings.ToUpper(dialectColumnTypes[1])] = customDriverValueConver
}
iscdvm = true
return nil
}
type driverValueInfo struct {
customDriverValueConver ICustomDriverValueConver
columnType *sql.ColumnType
tempDriverValue interface{}
structFieldType *reflect.Type
}
/**
import (
// 00.引入数据库驱动
"gitee.com/chunanyong/dm"
"io"
)
// CustomDMText 实现ICustomDriverValueConver接口,扩展自定义类型,例如 达梦数据库TEXT类型,映射出来的是dm.DmClob类型,无法使用string类型直接接收
type CustomDMText struct{}
// GetDriverValue 根据数据库列类型,返回driver.Value的实例,struct属性类型
// map接收或者字段不存在,无法获取到structFieldType,会传入nil
func (dmtext CustomDMText) GetDriverValue(ctx context.Context, columnType *sql.ColumnType, structFieldType *reflect.Type) (driver.Value, error) {
// 如果需要使用structFieldType,需要先判断是否为nil
// if structFieldType != nil {
// }
return &dm.DmClob{}, nil
}
// ConverDriverValue 数据库列类型,GetDriverValue返回的driver.Value的临时接收值,struct属性类型
// map接收或者字段不存在,无法获取到structFieldType,会传入nil
// 返回符合接收类型值的指针,指针,指针!!!!
func (dmtext CustomDMText) ConverDriverValue(ctx context.Context, columnType *sql.ColumnType, tempDriverValue driver.Value, structFieldType *reflect.Type) (interface{}, error) {
// 如果需要使用structFieldType,需要先判断是否为nil
// if structFieldType != nil {
// }
// 类型转换
dmClob, isok := tempDriverValue.(*dm.DmClob)
if !isok {
return tempDriverValue, errors.New("->ConverDriverValue-->转换至*dm.DmClob类型失败")
}
if dmClob == nil || !dmClob.Valid {
return new(string), nil
}
// 获取长度
dmlen, errLength := dmClob.GetLength()
if errLength != nil {
return dmClob, errLength
}
// int64转成int类型
strInt64 := strconv.FormatInt(dmlen, 10)
dmlenInt, errAtoi := strconv.Atoi(strInt64)
if errAtoi != nil {
return dmClob, errAtoi
}
// 读取字符串
str, errReadString := dmClob.ReadString(1, dmlenInt)
// 处理空字符串或NULL造成的EOF错误
if errReadString == io.EOF {
return new(string), nil
}
return &str, errReadString
}
// RegisterCustomDriverValueConver 注册自定义的字段处理逻辑,用于驱动无法直接转换的场景,例如达梦的 TEXT 无法直接转化成 string
// 一般是放到init方法里进行注册
func init() {
// dialectColumnType 值是 Dialect.字段类型 ,例如 dm.TEXT
zorm.RegisterCustomDriverValueConver("dm.TEXT", CustomDMText{})
}
**/