fix tests bug
This commit is contained in:
parent
bd716c52e5
commit
29ba280ee5
170
helpers.go
170
helpers.go
|
@ -12,6 +12,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
|
@ -319,175 +320,6 @@ func sliceEq(left, right []string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func reflect2value(rawValue *reflect.Value) (str string, err error) {
|
||||
aa := reflect.TypeOf((*rawValue).Interface())
|
||||
vv := reflect.ValueOf((*rawValue).Interface())
|
||||
switch aa.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
str = strconv.FormatInt(vv.Int(), 10)
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
str = strconv.FormatUint(vv.Uint(), 10)
|
||||
case reflect.Float32, reflect.Float64:
|
||||
str = strconv.FormatFloat(vv.Float(), 'f', -1, 64)
|
||||
case reflect.String:
|
||||
str = vv.String()
|
||||
case reflect.Array, reflect.Slice:
|
||||
switch aa.Elem().Kind() {
|
||||
case reflect.Uint8:
|
||||
data := rawValue.Interface().([]byte)
|
||||
str = string(data)
|
||||
default:
|
||||
err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
|
||||
}
|
||||
// time type
|
||||
case reflect.Struct:
|
||||
if aa.ConvertibleTo(core.TimeType) {
|
||||
str = vv.Convert(core.TimeType).Interface().(time.Time).Format(time.RFC3339Nano)
|
||||
} else {
|
||||
err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
|
||||
}
|
||||
case reflect.Bool:
|
||||
str = strconv.FormatBool(vv.Bool())
|
||||
case reflect.Complex128, reflect.Complex64:
|
||||
str = fmt.Sprintf("%v", vv.Complex())
|
||||
/* TODO: unsupported types below
|
||||
case reflect.Map:
|
||||
case reflect.Ptr:
|
||||
case reflect.Uintptr:
|
||||
case reflect.UnsafePointer:
|
||||
case reflect.Chan, reflect.Func, reflect.Interface:
|
||||
*/
|
||||
default:
|
||||
err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func value2Bytes(rawValue *reflect.Value) (data []byte, err error) {
|
||||
var str string
|
||||
str, err = reflect2value(rawValue)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
data = []byte(str)
|
||||
return
|
||||
}
|
||||
|
||||
func value2String(rawValue *reflect.Value) (data string, err error) {
|
||||
data, err = reflect2value(rawValue)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error) {
|
||||
fields, err := rows.Columns()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for rows.Next() {
|
||||
result, err := row2mapStr(rows, fields)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resultsSlice = append(resultsSlice, result)
|
||||
}
|
||||
|
||||
return resultsSlice, nil
|
||||
}
|
||||
|
||||
func rows2maps(rows *core.Rows) (resultsSlice []map[string][]byte, err error) {
|
||||
fields, err := rows.Columns()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for rows.Next() {
|
||||
result, err := row2map(rows, fields)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resultsSlice = append(resultsSlice, result)
|
||||
}
|
||||
|
||||
return resultsSlice, nil
|
||||
}
|
||||
|
||||
func row2map(rows *core.Rows, fields []string) (resultsMap map[string][]byte, err error) {
|
||||
result := make(map[string][]byte)
|
||||
scanResultContainers := make([]interface{}, len(fields))
|
||||
for i := 0; i < len(fields); i++ {
|
||||
var scanResultContainer interface{}
|
||||
scanResultContainers[i] = &scanResultContainer
|
||||
}
|
||||
if err := rows.Scan(scanResultContainers...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for ii, key := range fields {
|
||||
rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
|
||||
//if row is null then ignore
|
||||
if rawValue.Interface() == nil {
|
||||
//fmt.Println("ignore ...", key, rawValue)
|
||||
continue
|
||||
}
|
||||
|
||||
if data, err := value2Bytes(&rawValue); err == nil {
|
||||
result[key] = data
|
||||
} else {
|
||||
return nil, err // !nashtsai! REVIEW, should return err or just error log?
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func row2mapStr(rows *core.Rows, fields []string) (resultsMap map[string]string, err error) {
|
||||
result := make(map[string]string)
|
||||
scanResultContainers := make([]interface{}, len(fields))
|
||||
for i := 0; i < len(fields); i++ {
|
||||
var scanResultContainer interface{}
|
||||
scanResultContainers[i] = &scanResultContainer
|
||||
}
|
||||
if err := rows.Scan(scanResultContainers...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for ii, key := range fields {
|
||||
rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
|
||||
//if row is null then ignore
|
||||
if rawValue.Interface() == nil {
|
||||
//fmt.Println("ignore ...", key, rawValue)
|
||||
continue
|
||||
}
|
||||
|
||||
if data, err := value2String(&rawValue); err == nil {
|
||||
result[key] = data
|
||||
} else {
|
||||
return nil, err // !nashtsai! REVIEW, should return err or just error log?
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func txQuery2(tx *core.Tx, sqlStr string, params ...interface{}) ([]map[string]string, error) {
|
||||
rows, err := tx.Query(sqlStr, params...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
return rows2Strings(rows)
|
||||
}
|
||||
|
||||
func query2(db *core.DB, sqlStr string, params ...interface{}) ([]map[string]string, error) {
|
||||
rows, err := db.Query(sqlStr, params...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
return rows2Strings(rows)
|
||||
}
|
||||
|
||||
func setColumnInt(bean interface{}, col *core.Column, t int64) {
|
||||
v, err := col.ValueOf(bean)
|
||||
if err != nil {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2017 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
zeroTime0 = "0000-00-00 00:00:00"
|
||||
zeroTime1 = "0001-01-01 00:00:00"
|
||||
)
|
||||
|
||||
func formatTime(t time.Time) string {
|
||||
return t.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
func isTimeZero(t time.Time) bool {
|
||||
return t.IsZero() || formatTime(t) == zeroTime0 ||
|
||||
formatTime(t) == zeroTime1
|
||||
}
|
22
session.go
22
session.go
|
@ -344,15 +344,6 @@ func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount i
|
|||
}
|
||||
}()
|
||||
|
||||
dbTZ := session.Engine.DatabaseTZ
|
||||
if dbTZ == nil {
|
||||
if session.Engine.dialect.DBType() == core.SQLITE {
|
||||
dbTZ = time.UTC
|
||||
} else {
|
||||
dbTZ = time.Local
|
||||
}
|
||||
}
|
||||
|
||||
var tempMap = make(map[string]int)
|
||||
var pk core.PK
|
||||
for ii, key := range fields {
|
||||
|
@ -528,11 +519,9 @@ func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount i
|
|||
}
|
||||
case reflect.Struct:
|
||||
if fieldType.ConvertibleTo(core.TimeType) {
|
||||
var tz *time.Location
|
||||
if col.TimeZone == nil {
|
||||
tz = session.Engine.TZLocation
|
||||
} else {
|
||||
tz = col.TimeZone
|
||||
dbTZ := session.Engine.DatabaseTZ
|
||||
if col.TimeZone != nil {
|
||||
dbTZ = col.TimeZone
|
||||
}
|
||||
|
||||
if rawValueType == core.TimeType {
|
||||
|
@ -548,14 +537,13 @@ func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount i
|
|||
t.Minute(), t.Second(), t.Nanosecond(), dbTZ)
|
||||
}
|
||||
|
||||
// !nashtsai! convert to engine location
|
||||
t = t.In(tz)
|
||||
t = t.In(session.Engine.TZLocation)
|
||||
fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
|
||||
} else if rawValueType == core.IntType || rawValueType == core.Int64Type ||
|
||||
rawValueType == core.Int32Type {
|
||||
hasAssigned = true
|
||||
|
||||
t := time.Unix(vv.Int(), 0).In(tz)
|
||||
t := time.Unix(vv.Int(), 0).In(session.Engine.TZLocation)
|
||||
fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
|
||||
} else {
|
||||
if d, ok := vv.Interface().([]uint8); ok {
|
||||
|
|
173
session_raw.go
173
session_raw.go
|
@ -6,6 +6,10 @@ package xorm
|
|||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
@ -59,6 +63,60 @@ func (session *Session) innerQuery(sqlStr string, params ...interface{}) (*core.
|
|||
return stmt, rows, nil
|
||||
}
|
||||
|
||||
func rows2maps(rows *core.Rows) (resultsSlice []map[string][]byte, err error) {
|
||||
fields, err := rows.Columns()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for rows.Next() {
|
||||
result, err := row2map(rows, fields)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resultsSlice = append(resultsSlice, result)
|
||||
}
|
||||
|
||||
return resultsSlice, nil
|
||||
}
|
||||
|
||||
func value2Bytes(rawValue *reflect.Value) (data []byte, err error) {
|
||||
var str string
|
||||
str, err = reflect2value(rawValue)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
data = []byte(str)
|
||||
return
|
||||
}
|
||||
|
||||
func row2map(rows *core.Rows, fields []string) (resultsMap map[string][]byte, err error) {
|
||||
result := make(map[string][]byte)
|
||||
scanResultContainers := make([]interface{}, len(fields))
|
||||
for i := 0; i < len(fields); i++ {
|
||||
var scanResultContainer interface{}
|
||||
scanResultContainers[i] = &scanResultContainer
|
||||
}
|
||||
if err := rows.Scan(scanResultContainers...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for ii, key := range fields {
|
||||
rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
|
||||
//if row is null then ignore
|
||||
if rawValue.Interface() == nil {
|
||||
//fmt.Println("ignore ...", key, rawValue)
|
||||
continue
|
||||
}
|
||||
|
||||
if data, err := value2Bytes(&rawValue); err == nil {
|
||||
result[key] = data
|
||||
} else {
|
||||
return nil, err // !nashtsai! REVIEW, should return err or just error log?
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (session *Session) innerQuery2(sqlStr string, params ...interface{}) ([]map[string][]byte, error) {
|
||||
_, rows, err := session.innerQuery(sqlStr, params...)
|
||||
if rows != nil {
|
||||
|
@ -80,6 +138,121 @@ func (session *Session) Query(sqlStr string, paramStr ...interface{}) ([]map[str
|
|||
return session.query(sqlStr, paramStr...)
|
||||
}
|
||||
|
||||
func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error) {
|
||||
fields, err := rows.Columns()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for rows.Next() {
|
||||
result, err := row2mapStr(rows, fields)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resultsSlice = append(resultsSlice, result)
|
||||
}
|
||||
|
||||
return resultsSlice, nil
|
||||
}
|
||||
|
||||
func reflect2value(rawValue *reflect.Value) (str string, err error) {
|
||||
aa := reflect.TypeOf((*rawValue).Interface())
|
||||
vv := reflect.ValueOf((*rawValue).Interface())
|
||||
switch aa.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
str = strconv.FormatInt(vv.Int(), 10)
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
str = strconv.FormatUint(vv.Uint(), 10)
|
||||
case reflect.Float32, reflect.Float64:
|
||||
str = strconv.FormatFloat(vv.Float(), 'f', -1, 64)
|
||||
case reflect.String:
|
||||
str = vv.String()
|
||||
case reflect.Array, reflect.Slice:
|
||||
switch aa.Elem().Kind() {
|
||||
case reflect.Uint8:
|
||||
data := rawValue.Interface().([]byte)
|
||||
str = string(data)
|
||||
default:
|
||||
err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
|
||||
}
|
||||
// time type
|
||||
case reflect.Struct:
|
||||
if aa.ConvertibleTo(core.TimeType) {
|
||||
str = vv.Convert(core.TimeType).Interface().(time.Time).Format(time.RFC3339Nano)
|
||||
} else {
|
||||
err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
|
||||
}
|
||||
case reflect.Bool:
|
||||
str = strconv.FormatBool(vv.Bool())
|
||||
case reflect.Complex128, reflect.Complex64:
|
||||
str = fmt.Sprintf("%v", vv.Complex())
|
||||
/* TODO: unsupported types below
|
||||
case reflect.Map:
|
||||
case reflect.Ptr:
|
||||
case reflect.Uintptr:
|
||||
case reflect.UnsafePointer:
|
||||
case reflect.Chan, reflect.Func, reflect.Interface:
|
||||
*/
|
||||
default:
|
||||
err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func value2String(rawValue *reflect.Value) (data string, err error) {
|
||||
data, err = reflect2value(rawValue)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func row2mapStr(rows *core.Rows, fields []string) (resultsMap map[string]string, err error) {
|
||||
result := make(map[string]string)
|
||||
scanResultContainers := make([]interface{}, len(fields))
|
||||
for i := 0; i < len(fields); i++ {
|
||||
var scanResultContainer interface{}
|
||||
scanResultContainers[i] = &scanResultContainer
|
||||
}
|
||||
if err := rows.Scan(scanResultContainers...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for ii, key := range fields {
|
||||
rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
|
||||
//if row is null then ignore
|
||||
if rawValue.Interface() == nil {
|
||||
//fmt.Println("ignore ...", key, rawValue)
|
||||
continue
|
||||
}
|
||||
|
||||
if data, err := value2String(&rawValue); err == nil {
|
||||
result[key] = data
|
||||
} else {
|
||||
return nil, err // !nashtsai! REVIEW, should return err or just error log?
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func txQuery2(tx *core.Tx, sqlStr string, params ...interface{}) ([]map[string]string, error) {
|
||||
rows, err := tx.Query(sqlStr, params...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
return rows2Strings(rows)
|
||||
}
|
||||
|
||||
func query2(db *core.DB, sqlStr string, params ...interface{}) ([]map[string]string, error) {
|
||||
rows, err := db.Query(sqlStr, params...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
return rows2Strings(rows)
|
||||
}
|
||||
|
||||
// QueryString runs a raw sql and return records as []map[string]string
|
||||
func (session *Session) QueryString(sqlStr string, args ...interface{}) ([]map[string]string, error) {
|
||||
defer session.resetStatement()
|
||||
|
|
229
time_test.go
229
time_test.go
|
@ -6,16 +6,13 @@ package xorm
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func formatTime(t time.Time) string {
|
||||
return t.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
func TestTimeUserTime(t *testing.T) {
|
||||
assert.NoError(t, prepareEngine())
|
||||
|
||||
|
@ -253,3 +250,227 @@ func TestTimeUserUpdatedDiffLoc(t *testing.T) {
|
|||
assert.EqualValues(t, formatTime(user3.UpdatedAt), formatTime(user4.UpdatedAt))
|
||||
fmt.Println("user3", user.CreatedAt, user4.UpdatedAt)
|
||||
}
|
||||
|
||||
func TestTimeUserDeleted(t *testing.T) {
|
||||
assert.NoError(t, prepareEngine())
|
||||
|
||||
type UserDeleted struct {
|
||||
Id string
|
||||
CreatedAt time.Time `xorm:"created"`
|
||||
UpdatedAt time.Time `xorm:"updated"`
|
||||
DeletedAt time.Time `xorm:"deleted"`
|
||||
}
|
||||
|
||||
assertSync(t, new(UserDeleted))
|
||||
|
||||
var user = UserDeleted{
|
||||
Id: "lunny",
|
||||
}
|
||||
|
||||
cnt, err := testEngine.Insert(&user)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
fmt.Println("user", user.CreatedAt, user.UpdatedAt, user.DeletedAt)
|
||||
|
||||
var user2 UserDeleted
|
||||
has, err := testEngine.Get(&user2)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, user.CreatedAt.Unix(), user2.CreatedAt.Unix())
|
||||
assert.EqualValues(t, formatTime(user.CreatedAt), formatTime(user2.CreatedAt))
|
||||
assert.EqualValues(t, user.UpdatedAt.Unix(), user2.UpdatedAt.Unix())
|
||||
assert.EqualValues(t, formatTime(user.UpdatedAt), formatTime(user2.UpdatedAt))
|
||||
assert.True(t, isTimeZero(user2.DeletedAt))
|
||||
fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt, user2.DeletedAt)
|
||||
|
||||
var user3 UserDeleted
|
||||
cnt, err = testEngine.Where("id = ?", "lunny").Delete(&user3)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
assert.True(t, !isTimeZero(user3.DeletedAt))
|
||||
|
||||
var user4 UserDeleted
|
||||
has, err = testEngine.Unscoped().Get(&user4)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, user3.DeletedAt.Unix(), user4.DeletedAt.Unix())
|
||||
assert.EqualValues(t, formatTime(user3.DeletedAt), formatTime(user4.DeletedAt))
|
||||
fmt.Println("user3", user3.DeletedAt, user4.DeletedAt)
|
||||
}
|
||||
|
||||
func TestTimeUserDeletedDiffLoc(t *testing.T) {
|
||||
assert.NoError(t, prepareEngine())
|
||||
loc, err := time.LoadLocation("Asia/Shanghai")
|
||||
assert.NoError(t, err)
|
||||
testEngine.TZLocation = loc
|
||||
dbLoc, err := time.LoadLocation("America/New_York")
|
||||
assert.NoError(t, err)
|
||||
testEngine.DatabaseTZ = dbLoc
|
||||
|
||||
type UserDeleted struct {
|
||||
Id string
|
||||
CreatedAt time.Time `xorm:"created"`
|
||||
UpdatedAt time.Time `xorm:"updated"`
|
||||
DeletedAt time.Time `xorm:"deleted"`
|
||||
}
|
||||
|
||||
assertSync(t, new(UserDeleted))
|
||||
|
||||
var user = UserDeleted{
|
||||
Id: "lunny",
|
||||
}
|
||||
|
||||
cnt, err := testEngine.Insert(&user)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
fmt.Println("user", user.CreatedAt, user.UpdatedAt, user.DeletedAt)
|
||||
|
||||
var user2 UserDeleted
|
||||
has, err := testEngine.Get(&user2)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, user.CreatedAt.Unix(), user2.CreatedAt.Unix())
|
||||
assert.EqualValues(t, formatTime(user.CreatedAt), formatTime(user2.CreatedAt))
|
||||
assert.EqualValues(t, user.UpdatedAt.Unix(), user2.UpdatedAt.Unix())
|
||||
assert.EqualValues(t, formatTime(user.UpdatedAt), formatTime(user2.UpdatedAt))
|
||||
assert.True(t, isTimeZero(user2.DeletedAt))
|
||||
fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt, user2.DeletedAt)
|
||||
|
||||
var user3 UserDeleted
|
||||
cnt, err = testEngine.Where("id = ?", "lunny").Delete(&user3)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
assert.True(t, !isTimeZero(user3.DeletedAt))
|
||||
|
||||
var user4 UserDeleted
|
||||
has, err = testEngine.Unscoped().Get(&user4)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, user3.DeletedAt.Unix(), user4.DeletedAt.Unix())
|
||||
assert.EqualValues(t, formatTime(user3.DeletedAt), formatTime(user4.DeletedAt))
|
||||
fmt.Println("user3", user3.DeletedAt, user4.DeletedAt)
|
||||
}
|
||||
|
||||
type JsonDate time.Time
|
||||
|
||||
func (j JsonDate) MarshalJSON() ([]byte, error) {
|
||||
if time.Time(j).IsZero() {
|
||||
return []byte(`""`), nil
|
||||
}
|
||||
return []byte(`"` + time.Time(j).Format("2006-01-02 15:04:05") + `"`), nil
|
||||
}
|
||||
|
||||
func (j *JsonDate) UnmarshalJSON(value []byte) error {
|
||||
var v = strings.TrimSpace(strings.Trim(string(value), "\""))
|
||||
|
||||
t, err := time.ParseInLocation("2006-01-02 15:04:05", v, time.Local)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*j = JsonDate(t)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (j *JsonDate) Unix() int64 {
|
||||
return (*time.Time)(j).Unix()
|
||||
}
|
||||
|
||||
func TestCustomTimeUserDeleted(t *testing.T) {
|
||||
assert.NoError(t, prepareEngine())
|
||||
|
||||
type UserDeleted struct {
|
||||
Id string
|
||||
CreatedAt JsonDate `xorm:"created"`
|
||||
UpdatedAt JsonDate `xorm:"updated"`
|
||||
DeletedAt JsonDate `xorm:"deleted"`
|
||||
}
|
||||
|
||||
assertSync(t, new(UserDeleted))
|
||||
|
||||
var user = UserDeleted{
|
||||
Id: "lunny",
|
||||
}
|
||||
|
||||
cnt, err := testEngine.Insert(&user)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
fmt.Println("user", user.CreatedAt, user.UpdatedAt, user.DeletedAt)
|
||||
|
||||
var user2 UserDeleted
|
||||
has, err := testEngine.Get(&user2)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, user.CreatedAt.Unix(), user2.CreatedAt.Unix())
|
||||
assert.EqualValues(t, formatTime(time.Time(user.CreatedAt)), formatTime(time.Time(user2.CreatedAt)))
|
||||
assert.EqualValues(t, user.UpdatedAt.Unix(), user2.UpdatedAt.Unix())
|
||||
assert.EqualValues(t, formatTime(time.Time(user.UpdatedAt)), formatTime(time.Time(user2.UpdatedAt)))
|
||||
assert.True(t, isTimeZero(time.Time(user2.DeletedAt)))
|
||||
fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt, user2.DeletedAt)
|
||||
|
||||
var user3 UserDeleted
|
||||
cnt, err = testEngine.Where("id = ?", "lunny").Delete(&user3)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
assert.True(t, !isTimeZero(time.Time(user3.DeletedAt)))
|
||||
|
||||
var user4 UserDeleted
|
||||
has, err = testEngine.Unscoped().Get(&user4)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, user3.DeletedAt.Unix(), user4.DeletedAt.Unix())
|
||||
assert.EqualValues(t, formatTime(time.Time(user3.DeletedAt)), formatTime(time.Time(user4.DeletedAt)))
|
||||
fmt.Println("user3", user3.DeletedAt, user4.DeletedAt)
|
||||
}
|
||||
|
||||
func TestCustomTimeUserDeletedDiffLoc(t *testing.T) {
|
||||
assert.NoError(t, prepareEngine())
|
||||
loc, err := time.LoadLocation("Asia/Shanghai")
|
||||
assert.NoError(t, err)
|
||||
testEngine.TZLocation = loc
|
||||
dbLoc, err := time.LoadLocation("America/New_York")
|
||||
assert.NoError(t, err)
|
||||
testEngine.DatabaseTZ = dbLoc
|
||||
|
||||
type UserDeleted struct {
|
||||
Id string
|
||||
CreatedAt JsonDate `xorm:"created"`
|
||||
UpdatedAt JsonDate `xorm:"updated"`
|
||||
DeletedAt JsonDate `xorm:"deleted"`
|
||||
}
|
||||
|
||||
assertSync(t, new(UserDeleted))
|
||||
|
||||
var user = UserDeleted{
|
||||
Id: "lunny",
|
||||
}
|
||||
|
||||
cnt, err := testEngine.Insert(&user)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
fmt.Println("user", user.CreatedAt, user.UpdatedAt, user.DeletedAt)
|
||||
|
||||
var user2 UserDeleted
|
||||
has, err := testEngine.Get(&user2)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, user.CreatedAt.Unix(), user2.CreatedAt.Unix())
|
||||
assert.EqualValues(t, formatTime(time.Time(user.CreatedAt)), formatTime(time.Time(user2.CreatedAt)))
|
||||
assert.EqualValues(t, user.UpdatedAt.Unix(), user2.UpdatedAt.Unix())
|
||||
assert.EqualValues(t, formatTime(time.Time(user.UpdatedAt)), formatTime(time.Time(user2.UpdatedAt)))
|
||||
assert.True(t, isTimeZero(time.Time(user2.DeletedAt)))
|
||||
fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt, user2.DeletedAt)
|
||||
|
||||
var user3 UserDeleted
|
||||
cnt, err = testEngine.Where("id = ?", "lunny").Delete(&user3)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
assert.True(t, !isTimeZero(time.Time(user3.DeletedAt)))
|
||||
|
||||
var user4 UserDeleted
|
||||
has, err = testEngine.Unscoped().Get(&user4)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, user3.DeletedAt.Unix(), user4.DeletedAt.Unix())
|
||||
assert.EqualValues(t, formatTime(time.Time(user3.DeletedAt)), formatTime(time.Time(user4.DeletedAt)))
|
||||
fmt.Println("user3", user3.DeletedAt, user4.DeletedAt)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue