add AfterSet processor support & resolved #276
This commit is contained in:
parent
b6a31aa9a3
commit
f9e450f348
|
@ -23,6 +23,10 @@ type BeforeSetProcessor interface {
|
||||||
BeforeSet(string, Cell)
|
BeforeSet(string, Cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AfterSetProcessor interface {
|
||||||
|
AfterSet(string, Cell)
|
||||||
|
}
|
||||||
|
|
||||||
// !nashtsai! TODO enable BeforeValidateProcessor when xorm start to support validations
|
// !nashtsai! TODO enable BeforeValidateProcessor when xorm start to support validations
|
||||||
//// Executed before an object is validated
|
//// Executed before an object is validated
|
||||||
//type BeforeValidateProcessor interface {
|
//type BeforeValidateProcessor interface {
|
||||||
|
|
78
session.go
78
session.go
|
@ -1626,6 +1626,14 @@ func (session *Session) _row2Bean(rows *core.Rows, fields []string, fieldsCount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if b, hasAfterSet := bean.(AfterSetProcessor); hasAfterSet {
|
||||||
|
for ii, key := range fields {
|
||||||
|
b.AfterSet(key, Cell(scanResults[ii].(*interface{})))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
var tempMap = make(map[string]int)
|
var tempMap = make(map[string]int)
|
||||||
for ii, key := range fields {
|
for ii, key := range fields {
|
||||||
var idx int
|
var idx int
|
||||||
|
@ -1675,7 +1683,6 @@ func (session *Session) _row2Bean(rows *core.Rows, fields []string, fieldsCount
|
||||||
hasAssigned := false
|
hasAssigned := false
|
||||||
|
|
||||||
switch fieldType.Kind() {
|
switch fieldType.Kind() {
|
||||||
|
|
||||||
case reflect.Complex64, reflect.Complex128:
|
case reflect.Complex64, reflect.Complex128:
|
||||||
if rawValueType.Kind() == reflect.String {
|
if rawValueType.Kind() == reflect.String {
|
||||||
hasAssigned = true
|
hasAssigned = true
|
||||||
|
@ -1686,6 +1693,15 @@ func (session *Session) _row2Bean(rows *core.Rows, fields []string, fieldsCount
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fieldValue.Set(x.Elem())
|
fieldValue.Set(x.Elem())
|
||||||
|
} else if rawValueType.Kind() == reflect.Slice {
|
||||||
|
hasAssigned = true
|
||||||
|
x := reflect.New(fieldType)
|
||||||
|
err := json.Unmarshal(vv.Bytes(), x.Interface())
|
||||||
|
if err != nil {
|
||||||
|
session.Engine.LogError(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fieldValue.Set(x.Elem())
|
||||||
}
|
}
|
||||||
case reflect.Slice, reflect.Array:
|
case reflect.Slice, reflect.Array:
|
||||||
switch rawValueType.Kind() {
|
switch rawValueType.Kind() {
|
||||||
|
@ -1730,6 +1746,7 @@ func (session *Session) _row2Bean(rows *core.Rows, fields []string, fieldsCount
|
||||||
fieldValue.SetUint(uint64(vv.Int()))
|
fieldValue.SetUint(uint64(vv.Int()))
|
||||||
}
|
}
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
|
col := table.GetColumn(key)
|
||||||
if fieldType.ConvertibleTo(core.TimeType) {
|
if fieldType.ConvertibleTo(core.TimeType) {
|
||||||
if rawValueType == core.TimeType {
|
if rawValueType == core.TimeType {
|
||||||
hasAssigned = true
|
hasAssigned = true
|
||||||
|
@ -1763,11 +1780,31 @@ func (session *Session) _row2Bean(rows *core.Rows, fields []string, fieldsCount
|
||||||
session.Engine.LogError("sql.Sanner error:", err.Error())
|
session.Engine.LogError("sql.Sanner error:", err.Error())
|
||||||
hasAssigned = false
|
hasAssigned = false
|
||||||
}
|
}
|
||||||
|
} else if col.SQLType.IsJson() {
|
||||||
|
if rawValueType.Kind() == reflect.String {
|
||||||
|
hasAssigned = true
|
||||||
|
x := reflect.New(fieldType)
|
||||||
|
err := json.Unmarshal([]byte(vv.String()), x.Interface())
|
||||||
|
if err != nil {
|
||||||
|
session.Engine.LogError(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fieldValue.Set(x.Elem())
|
||||||
|
} else if rawValueType.Kind() == reflect.Slice {
|
||||||
|
hasAssigned = true
|
||||||
|
x := reflect.New(fieldType)
|
||||||
|
err := json.Unmarshal(vv.Bytes(), x.Interface())
|
||||||
|
if err != nil {
|
||||||
|
session.Engine.LogError(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fieldValue.Set(x.Elem())
|
||||||
|
}
|
||||||
} else if session.Statement.UseCascade {
|
} else if session.Statement.UseCascade {
|
||||||
table := session.Engine.autoMapType(*fieldValue)
|
table := session.Engine.autoMapType(*fieldValue)
|
||||||
if table != nil {
|
if table != nil {
|
||||||
if len(table.PrimaryKeys) > 1 {
|
if len(table.PrimaryKeys) != 1 {
|
||||||
panic("unsupported composited primary key cascade")
|
panic("unsupported non or composited primary key cascade")
|
||||||
}
|
}
|
||||||
var pk = make(core.PK, len(table.PrimaryKeys))
|
var pk = make(core.PK, len(table.PrimaryKeys))
|
||||||
|
|
||||||
|
@ -2952,17 +2989,31 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val
|
||||||
if len(fieldTable.PrimaryKeys) == 1 {
|
if len(fieldTable.PrimaryKeys) == 1 {
|
||||||
pkField := reflect.Indirect(fieldValue).FieldByName(fieldTable.PKColumns()[0].FieldName)
|
pkField := reflect.Indirect(fieldValue).FieldByName(fieldTable.PKColumns()[0].FieldName)
|
||||||
return pkField.Interface(), nil
|
return pkField.Interface(), nil
|
||||||
} else {
|
|
||||||
return 0, fmt.Errorf("no primary key for col %v", col.Name)
|
|
||||||
}
|
}
|
||||||
} else {
|
return 0, fmt.Errorf("no primary key for col %v", col.Name)
|
||||||
// !<winxxp>! 增加支持driver.Valuer接口的结构,如sql.NullString
|
|
||||||
if v, ok := fieldValue.Interface().(driver.Valuer); ok {
|
|
||||||
return v.Value()
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0, fmt.Errorf("Unsupported type %v", fieldValue.Type())
|
|
||||||
}
|
}
|
||||||
|
// !<winxxp>! 增加支持driver.Valuer接口的结构,如sql.NullString
|
||||||
|
if v, ok := fieldValue.Interface().(driver.Valuer); ok {
|
||||||
|
return v.Value()
|
||||||
|
}
|
||||||
|
|
||||||
|
if col.SQLType.IsText() {
|
||||||
|
bytes, err := json.Marshal(fieldValue.Interface())
|
||||||
|
if err != nil {
|
||||||
|
session.Engine.LogError(err)
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return string(bytes), nil
|
||||||
|
} else if col.SQLType.IsBlob() {
|
||||||
|
bytes, err := json.Marshal(fieldValue.Interface())
|
||||||
|
if err != nil {
|
||||||
|
session.Engine.LogError(err)
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return bytes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("Unsupported type %v", fieldValue.Type())
|
||||||
case reflect.Complex64, reflect.Complex128:
|
case reflect.Complex64, reflect.Complex128:
|
||||||
bytes, err := json.Marshal(fieldValue.Interface())
|
bytes, err := json.Marshal(fieldValue.Interface())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2996,9 +3047,8 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bytes, nil
|
return bytes, nil
|
||||||
} else {
|
|
||||||
return nil, ErrUnSupportedType
|
|
||||||
}
|
}
|
||||||
|
return nil, ErrUnSupportedType
|
||||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||||
return int64(fieldValue.Uint()), nil
|
return int64(fieldValue.Uint()), nil
|
||||||
default:
|
default:
|
||||||
|
|
49
statement.go
49
statement.go
|
@ -417,6 +417,9 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{},
|
||||||
if engine.dialect.DBType() == core.MSSQL && col.SQLType.Name == core.Text {
|
if engine.dialect.DBType() == core.MSSQL && col.SQLType.Name == core.Text {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if col.SQLType.IsJson() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
var colName string
|
var colName string
|
||||||
if addedTableName {
|
if addedTableName {
|
||||||
|
@ -519,23 +522,43 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{},
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
engine.autoMapType(fieldValue)
|
if col.SQLType.IsJson() {
|
||||||
if table, ok := engine.Tables[fieldValue.Type()]; ok {
|
if col.SQLType.IsText() {
|
||||||
if len(table.PrimaryKeys) == 1 {
|
bytes, err := json.Marshal(fieldValue.Interface())
|
||||||
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
|
if err != nil {
|
||||||
// fix non-int pk issues
|
engine.LogError(err)
|
||||||
//if pkField.Int() != 0 {
|
|
||||||
if pkField.IsValid() && !isZero(pkField.Interface()) {
|
|
||||||
val = pkField.Interface()
|
|
||||||
} else {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
val = string(bytes)
|
||||||
//TODO: how to handler?
|
} else if col.SQLType.IsBlob() {
|
||||||
panic(fmt.Sprintln("not supported", fieldValue.Interface(), "as", table.PrimaryKeys))
|
var bytes []byte
|
||||||
|
var err error
|
||||||
|
bytes, err = json.Marshal(fieldValue.Interface())
|
||||||
|
if err != nil {
|
||||||
|
engine.LogError(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val = bytes
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val = fieldValue.Interface()
|
engine.autoMapType(fieldValue)
|
||||||
|
if table, ok := engine.Tables[fieldValue.Type()]; ok {
|
||||||
|
if len(table.PrimaryKeys) == 1 {
|
||||||
|
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
|
||||||
|
// fix non-int pk issues
|
||||||
|
//if pkField.Int() != 0 {
|
||||||
|
if pkField.IsValid() && !isZero(pkField.Interface()) {
|
||||||
|
val = pkField.Interface()
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//TODO: how to handler?
|
||||||
|
panic(fmt.Sprintln("not supported", fieldValue.Interface(), "as", table.PrimaryKeys))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val = fieldValue.Interface()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case reflect.Array, reflect.Slice, reflect.Map:
|
case reflect.Array, reflect.Slice, reflect.Map:
|
||||||
|
|
Loading…
Reference in New Issue