Commit 415b9cf3 authored by Victor Popkov's avatar Victor Popkov

add support for time.Time pointer in struct types

Allow to use pointer *time.Time as a type in combination with orm tags in struct. This enables to treat them as "empty" in JSON marshaling/unmarshaling when using 'json:"null,omitempty'.
parent ed474b51
...@@ -243,6 +243,9 @@ func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Val ...@@ -243,6 +243,9 @@ func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Val
if fi.isFielder { if fi.isFielder {
f := field.Addr().Interface().(Fielder) f := field.Addr().Interface().(Fielder)
f.SetRaw(tnow.In(DefaultTimeLoc)) f.SetRaw(tnow.In(DefaultTimeLoc))
} else if field.Kind() == reflect.Ptr {
v := tnow.In(DefaultTimeLoc)
field.Set(reflect.ValueOf(&v))
} else { } else {
field.Set(reflect.ValueOf(tnow.In(DefaultTimeLoc))) field.Set(reflect.ValueOf(tnow.In(DefaultTimeLoc)))
} }
...@@ -1273,8 +1276,14 @@ setValue: ...@@ -1273,8 +1276,14 @@ setValue:
if isNative { if isNative {
if value == nil { if value == nil {
value = time.Time{} value = time.Time{}
} else if field.Kind() == reflect.Ptr {
if value != nil {
v := value.(time.Time)
field.Set(reflect.ValueOf(&v))
}
} else {
field.Set(reflect.ValueOf(value))
} }
field.Set(reflect.ValueOf(value))
} }
case fieldType == TypePositiveBitField && field.Kind() == reflect.Ptr: case fieldType == TypePositiveBitField && field.Kind() == reflect.Ptr:
if value != nil { if value != nil {
......
...@@ -181,6 +181,9 @@ type DataNull struct { ...@@ -181,6 +181,9 @@ type DataNull struct {
Float32Ptr *float32 `orm:"null"` Float32Ptr *float32 `orm:"null"`
Float64Ptr *float64 `orm:"null"` Float64Ptr *float64 `orm:"null"`
DecimalPtr *float64 `orm:"digits(8);decimals(4);null"` DecimalPtr *float64 `orm:"digits(8);decimals(4);null"`
TimePtr *time.Time `orm:"null;type(time)"`
DatePtr *time.Time `orm:"null;type(date)"`
DateTimePtr *time.Time `orm:"null"`
} }
type String string type String string
......
...@@ -137,6 +137,8 @@ func getFieldType(val reflect.Value) (ft int, err error) { ...@@ -137,6 +137,8 @@ func getFieldType(val reflect.Value) (ft int, err error) {
ft = TypeBooleanField ft = TypeBooleanField
case reflect.TypeOf(new(string)): case reflect.TypeOf(new(string)):
ft = TypeCharField ft = TypeCharField
case reflect.TypeOf(new(time.Time)):
ft = TypeDateTimeField
default: default:
elm := reflect.Indirect(val) elm := reflect.Indirect(val)
switch elm.Kind() { switch elm.Kind() {
......
...@@ -350,6 +350,9 @@ func TestNullDataTypes(t *testing.T) { ...@@ -350,6 +350,9 @@ func TestNullDataTypes(t *testing.T) {
throwFail(t, AssertIs(d.Float32Ptr, nil)) throwFail(t, AssertIs(d.Float32Ptr, nil))
throwFail(t, AssertIs(d.Float64Ptr, nil)) throwFail(t, AssertIs(d.Float64Ptr, nil))
throwFail(t, AssertIs(d.DecimalPtr, nil)) throwFail(t, AssertIs(d.DecimalPtr, nil))
throwFail(t, AssertIs(d.TimePtr, nil))
throwFail(t, AssertIs(d.DatePtr, nil))
throwFail(t, AssertIs(d.DateTimePtr, nil))
_, err = dORM.Raw(`INSERT INTO data_null (boolean) VALUES (?)`, nil).Exec() _, err = dORM.Raw(`INSERT INTO data_null (boolean) VALUES (?)`, nil).Exec()
throwFail(t, err) throwFail(t, err)
...@@ -376,6 +379,9 @@ func TestNullDataTypes(t *testing.T) { ...@@ -376,6 +379,9 @@ func TestNullDataTypes(t *testing.T) {
float32Ptr := float32(42.0) float32Ptr := float32(42.0)
float64Ptr := float64(42.0) float64Ptr := float64(42.0)
decimalPtr := float64(42.0) decimalPtr := float64(42.0)
timePtr := time.Now()
datePtr := time.Now()
dateTimePtr := time.Now()
d = DataNull{ d = DataNull{
DateTime: time.Now(), DateTime: time.Now(),
...@@ -401,6 +407,9 @@ func TestNullDataTypes(t *testing.T) { ...@@ -401,6 +407,9 @@ func TestNullDataTypes(t *testing.T) {
Float32Ptr: &float32Ptr, Float32Ptr: &float32Ptr,
Float64Ptr: &float64Ptr, Float64Ptr: &float64Ptr,
DecimalPtr: &decimalPtr, DecimalPtr: &decimalPtr,
TimePtr: &timePtr,
DatePtr: &datePtr,
DateTimePtr: &dateTimePtr,
} }
id, err = dORM.Insert(&d) id, err = dORM.Insert(&d)
...@@ -441,6 +450,9 @@ func TestNullDataTypes(t *testing.T) { ...@@ -441,6 +450,9 @@ func TestNullDataTypes(t *testing.T) {
throwFail(t, AssertIs(*d.Float32Ptr, float32Ptr)) throwFail(t, AssertIs(*d.Float32Ptr, float32Ptr))
throwFail(t, AssertIs(*d.Float64Ptr, float64Ptr)) throwFail(t, AssertIs(*d.Float64Ptr, float64Ptr))
throwFail(t, AssertIs(*d.DecimalPtr, decimalPtr)) throwFail(t, AssertIs(*d.DecimalPtr, decimalPtr))
throwFail(t, AssertIs((*d.TimePtr).Format(testTime), timePtr.Format(testTime)))
throwFail(t, AssertIs((*d.DatePtr).Format(testDate), datePtr.Format(testDate)))
throwFail(t, AssertIs((*d.DateTimePtr).Format(testDateTime), dateTimePtr.Format(testDateTime)))
} }
func TestDataCustomTypes(t *testing.T) { func TestDataCustomTypes(t *testing.T) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment