234 lines
4.7 KiB
Go
234 lines
4.7 KiB
Go
package f5
|
|
|
|
import (
|
|
"database/sql"
|
|
"q5"
|
|
"reflect"
|
|
"errors"
|
|
)
|
|
|
|
type DataSet struct {
|
|
columns []string
|
|
rows [][]interface{}
|
|
currRow []interface{}
|
|
numOfReaded int64
|
|
closed bool
|
|
}
|
|
|
|
//已读取函数(调用Next成功的次数)
|
|
func (this *DataSet) NumOfReaded() int64 {
|
|
return this.numOfReaded
|
|
}
|
|
|
|
func (this *DataSet) close() {
|
|
this.closed = true
|
|
}
|
|
|
|
func (this *DataSet) init(rows *sql.Rows) {
|
|
if rows == nil {
|
|
return
|
|
}
|
|
defer rows.Close()
|
|
|
|
if len(this.columns) <= 0 {
|
|
columns, err := rows.Columns()
|
|
if err == nil {
|
|
this.columns = columns
|
|
} else {
|
|
panic("NewDataSet Next Columns error:" + err.Error())
|
|
}
|
|
}
|
|
|
|
q5.NewSlice(&this.rows, 0, 100)
|
|
for rows.Next() {
|
|
values := []interface{}{}
|
|
for i := 0; i < len(this.columns); i++ {
|
|
str := sql.NullString{}
|
|
values = append(values, &str)
|
|
}
|
|
err := rows.Scan(values...)
|
|
if err != nil {
|
|
panic("NewDataSet Next Scan error:" + err.Error())
|
|
}
|
|
q5.AppendSlice(&this.rows, values)
|
|
}
|
|
}
|
|
|
|
func (this *DataSet) Next() bool {
|
|
/*
|
|
if this.closed {
|
|
panic("NewDataSet is closed")
|
|
}*/
|
|
if this.numOfReaded >= int64(len(this.rows)) {
|
|
return false
|
|
}
|
|
this.currRow = this.rows[this.numOfReaded]
|
|
this.numOfReaded += 1
|
|
return true
|
|
}
|
|
|
|
func (this *DataSet) GetColumns() []string {
|
|
return this.columns
|
|
}
|
|
|
|
/*
|
|
安全版:nil值视为""
|
|
*/
|
|
func (this *DataSet) GetValues() *[]string {
|
|
values := []string{}
|
|
for _, val := range this.currRow {
|
|
raw_val := val.(*sql.NullString)
|
|
if raw_val.Valid {
|
|
values = append(values, raw_val.String)
|
|
} else {
|
|
values = append(values, *q5.NewEmptyStrPtr())
|
|
}
|
|
}
|
|
return &values
|
|
}
|
|
|
|
/*
|
|
安全版:nil值视为""
|
|
*/
|
|
func (this *DataSet) GetByName(name string) string {
|
|
val := this.GetRawValueByName(name)
|
|
if val == nil {
|
|
return ""
|
|
} else {
|
|
return *val
|
|
}
|
|
}
|
|
|
|
/*
|
|
安全版:nil值视为""
|
|
*/
|
|
func (this *DataSet) GetByIndex(index int32) string {
|
|
val := this.GetRawValueByIndex(index)
|
|
if val == nil {
|
|
return ""
|
|
} else {
|
|
return *val
|
|
}
|
|
}
|
|
|
|
/*
|
|
!!!原始版: 调用方应处理值为nil的情况
|
|
*/
|
|
func (this *DataSet) GetRawValues() *[]string {
|
|
values := []*string{}
|
|
for _, val := range this.currRow {
|
|
raw_val := val.(*sql.NullString)
|
|
if raw_val.Valid {
|
|
values = append(values, &raw_val.String)
|
|
} else {
|
|
values = append(values, nil)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
/*
|
|
!!!原始版: 调用方应处理值为nil的情况
|
|
*/
|
|
func (this *DataSet) GetRawValueByName(name string) *string {
|
|
this.GetColumns()
|
|
for i := 0; i < len(this.columns); i++ {
|
|
if this.columns[i] == name {
|
|
return this.GetRawValueByIndex(int32(i))
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
/*
|
|
!!!原始版: 调用方应处理值为nil的情况
|
|
*/
|
|
func (this *DataSet) GetRawValueByIndex(index int32) *string {
|
|
this.GetColumns()
|
|
sql_val := this.currRow[index].(*sql.NullString)
|
|
if sql_val.Valid {
|
|
return &sql_val.String
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func UnmarshalModelList[T any](ds *DataSet, models *[]*T) error {
|
|
var resultErr error
|
|
for ds.Next() {
|
|
p := new(T)
|
|
resultErr = UnmarshalModel(ds, p)
|
|
if resultErr != nil {
|
|
*models = (*models)[:0]
|
|
break
|
|
}
|
|
q5.AppendSlice(models, p)
|
|
}
|
|
return resultErr
|
|
}
|
|
|
|
/*
|
|
只支持1级指针
|
|
*/
|
|
func UnmarshalModel[T any](ds *DataSet, m *T) error {
|
|
mType := reflect.TypeOf(m).Elem()
|
|
mVal := reflect.ValueOf(m).Elem()
|
|
for i := 0; i < mType.NumField(); i++ {
|
|
field := mType.Field(i)
|
|
gormTag := field.Tag.Get("gorm")
|
|
if gormTag == "" {
|
|
continue
|
|
}
|
|
gormFieldName := ""
|
|
gormIsJson := false
|
|
params := q5.StrSplit(gormTag, ";")
|
|
for _, val := range params {
|
|
tmpStrs := q5.StrSplit(val, ":")
|
|
if len(tmpStrs) == 2 {
|
|
if tmpStrs[0] == "column" {
|
|
gormFieldName = tmpStrs[1]
|
|
}
|
|
if tmpStrs[0] == "serializer" {
|
|
gormIsJson = true
|
|
if tmpStrs[1] != "json" {
|
|
return errors.New("gorm unknow serializer:" + tmpStrs[1])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if gormFieldName == "" {
|
|
return errors.New("gormFieldName is empty")
|
|
}
|
|
fieldVal := ds.GetByName(gormFieldName)
|
|
if gormIsJson {
|
|
q5.DecodeJson(fieldVal, mVal.Field(i).Addr().Interface())
|
|
} else {
|
|
if (q5.IsSimpleReflectKind(field.Type.Kind())) {
|
|
mVal.Field(i).Set(*q5.StrToSimpleReflectValue(fieldVal, field.Type.Kind()))
|
|
} else {
|
|
switch field.Type.Kind() {
|
|
case reflect.Ptr:
|
|
{
|
|
if (q5.IsSimpleReflectKind(field.Type.Elem().Kind())) {
|
|
mVal.Field(i).Set(*q5.StrToSimplePtrReflectValue(fieldVal, field.Type.Elem().Kind()))
|
|
} else {
|
|
GetSysLog().Info("UnmarshalModel unknow fieldPtrType:%s", field.Type.Elem());
|
|
}
|
|
}
|
|
default:
|
|
{
|
|
GetSysLog().Info("UnmarshalModel unknow fieldType:%s", field.Type.Kind());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func newDataSet(rows *sql.Rows) *DataSet {
|
|
dataSet := new(DataSet)
|
|
dataSet.init(rows)
|
|
return dataSet
|
|
}
|