Fix timesatmp
This commit is contained in:
parent
983e5fdf99
commit
54606d5bfd
|
@ -5,50 +5,53 @@
|
||||||
package dialects
|
package dialects
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"xorm.io/xorm/schemas"
|
"xorm.io/xorm/schemas"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FormatTime format time as column type
|
|
||||||
func FormatTime(dialect Dialect, sqlTypeName string, t time.Time) (v interface{}) {
|
|
||||||
switch sqlTypeName {
|
|
||||||
case schemas.Time:
|
|
||||||
s := t.Format("2006-01-02 15:04:05") // time.RFC3339
|
|
||||||
v = s[11:19]
|
|
||||||
case schemas.Date:
|
|
||||||
v = t.Format("2006-01-02")
|
|
||||||
case schemas.DateTime, schemas.TimeStamp, schemas.Varchar: // !DarthPestilane! format time when sqlTypeName is schemas.Varchar.
|
|
||||||
if dialect.URI().DBType == schemas.ORACLE {
|
|
||||||
v = t
|
|
||||||
} else {
|
|
||||||
v = t.Format("2006-01-02 15:04:05")
|
|
||||||
}
|
|
||||||
case schemas.TimeStampz:
|
|
||||||
if dialect.URI().DBType == schemas.MSSQL {
|
|
||||||
v = t.Format("2006-01-02T15:04:05.9999999Z07:00")
|
|
||||||
} else {
|
|
||||||
v = t.Format(time.RFC3339Nano)
|
|
||||||
}
|
|
||||||
case schemas.BigInt, schemas.Int:
|
|
||||||
v = t.Unix()
|
|
||||||
default:
|
|
||||||
v = t
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// FormatColumnTime format column time
|
// FormatColumnTime format column time
|
||||||
func FormatColumnTime(dialect Dialect, defaultTimeZone *time.Location, col *schemas.Column, t time.Time) (v interface{}) {
|
func FormatColumnTime(dialect Dialect, dbLocation *time.Location, col *schemas.Column, t time.Time) (interface{}, error) {
|
||||||
if t.IsZero() {
|
if t.IsZero() {
|
||||||
if col.Nullable {
|
if col.Nullable {
|
||||||
return nil
|
return nil, nil
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if col.TimeZone != nil {
|
if col.SQLType.IsNumeric() {
|
||||||
return FormatTime(dialect, col.SQLType.Name, t.In(col.TimeZone))
|
return 0, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmZone = dbLocation
|
||||||
|
if col.TimeZone != nil {
|
||||||
|
tmZone = col.TimeZone
|
||||||
|
}
|
||||||
|
|
||||||
|
t = t.In(tmZone)
|
||||||
|
|
||||||
|
switch col.SQLType.Name {
|
||||||
|
case schemas.Time:
|
||||||
|
s := t.Format("2006-01-02 15:04:05") // time.RFC3339
|
||||||
|
return s[11:19], nil
|
||||||
|
case schemas.Date:
|
||||||
|
return t.Format("2006-01-02"), nil
|
||||||
|
case schemas.DateTime, schemas.TimeStamp:
|
||||||
|
if col.Length > 0 {
|
||||||
|
return t.Format("2006-01-02 15:04:05." + strings.Repeat("0", col.Length)), nil
|
||||||
|
}
|
||||||
|
return t.Format("2006-01-02 15:04:05"), nil
|
||||||
|
case schemas.Varchar:
|
||||||
|
return t.Format("2006-01-02 15:04:05"), nil
|
||||||
|
case schemas.TimeStampz:
|
||||||
|
if dialect.URI().DBType == schemas.MSSQL {
|
||||||
|
return t.Format("2006-01-02T15:04:05.9999999Z07:00"), nil
|
||||||
|
} else {
|
||||||
|
return t.Format(time.RFC3339Nano), nil
|
||||||
|
}
|
||||||
|
case schemas.BigInt, schemas.Int:
|
||||||
|
return t.Unix(), nil
|
||||||
|
default:
|
||||||
|
return t, nil
|
||||||
}
|
}
|
||||||
return FormatTime(dialect, col.SQLType.Name, t.In(defaultTimeZone))
|
|
||||||
}
|
}
|
||||||
|
|
10
engine.go
10
engine.go
|
@ -1226,13 +1226,13 @@ func (engine *Engine) Import(r io.Reader) ([]sql.Result, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// nowTime return current time
|
// nowTime return current time
|
||||||
func (engine *Engine) nowTime(col *schemas.Column) (interface{}, time.Time) {
|
func (engine *Engine) nowTime(col *schemas.Column) (interface{}, time.Time, error) {
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
var tz = engine.DatabaseTZ
|
result, err := dialects.FormatColumnTime(engine.dialect, engine.DatabaseTZ, col, t)
|
||||||
if !col.DisableTimeZone && col.TimeZone != nil {
|
if err != nil {
|
||||||
tz = col.TimeZone
|
return nil, time.Time{}, err
|
||||||
}
|
}
|
||||||
return dialects.FormatTime(engine.dialect, col.SQLType.Name, t.In(tz)), t.In(engine.TZLocation)
|
return result, t.In(engine.TZLocation), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetColumnMapper returns the column name mapper
|
// GetColumnMapper returns the column name mapper
|
||||||
|
|
|
@ -575,7 +575,7 @@ func TestTimestamp(t *testing.T) {
|
||||||
|
|
||||||
type TimestampStruct struct {
|
type TimestampStruct struct {
|
||||||
Id int64
|
Id int64
|
||||||
InsertTime time.Time `xorm:"timestamp"`
|
InsertTime time.Time `xorm:"DATETIME(6)"`
|
||||||
}
|
}
|
||||||
|
|
||||||
assertSync(t, new(TimestampStruct))
|
assertSync(t, new(TimestampStruct))
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"xorm.io/xorm/internal/utils"
|
"xorm.io/xorm/internal/utils"
|
||||||
|
@ -39,6 +40,14 @@ func String2Time(s string, originalLocation *time.Location, convertedLocation *t
|
||||||
}
|
}
|
||||||
dt = dt.In(convertedLocation)
|
dt = dt.In(convertedLocation)
|
||||||
return &dt, nil
|
return &dt, nil
|
||||||
|
} else if len(s) >= 21 && s[19] == '.' {
|
||||||
|
var layout = "2006-01-02 15:04:05." + strings.Repeat("0", len(s)-20)
|
||||||
|
dt, err := time.ParseInLocation(layout, s, originalLocation)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dt = dt.In(convertedLocation)
|
||||||
|
return &dt, nil
|
||||||
} else {
|
} else {
|
||||||
i, err := strconv.ParseInt(s, 10, 64)
|
i, err := strconv.ParseInt(s, 10, 64)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
|
@ -734,7 +734,11 @@ func (statement *Statement) asDBCond(fieldValue reflect.Value, fieldType reflect
|
||||||
if !requiredField && (t.IsZero() || !fieldValue.IsValid()) {
|
if !requiredField && (t.IsZero() || !fieldValue.IsValid()) {
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
return dialects.FormatColumnTime(statement.dialect, statement.defaultTimeZone, col, t), true, nil
|
res, err := dialects.FormatColumnTime(statement.dialect, statement.defaultTimeZone, col, t)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
return res, true, nil
|
||||||
} else if fieldType.ConvertibleTo(schemas.BigFloatType) {
|
} else if fieldType.ConvertibleTo(schemas.BigFloatType) {
|
||||||
t := fieldValue.Convert(schemas.BigFloatType).Interface().(big.Float)
|
t := fieldValue.Convert(schemas.BigFloatType).Interface().(big.Float)
|
||||||
v := t.String()
|
v := t.String()
|
||||||
|
|
|
@ -208,7 +208,10 @@ func (statement *Statement) BuildUpdates(tableValue reflect.Value,
|
||||||
if !requiredField && (t.IsZero() || !fieldValue.IsValid()) {
|
if !requiredField && (t.IsZero() || !fieldValue.IsValid()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
val = dialects.FormatColumnTime(statement.dialect, statement.defaultTimeZone, col, t)
|
val, err = dialects.FormatColumnTime(statement.dialect, statement.defaultTimeZone, col, t)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
} else if nulType, ok := fieldValue.Interface().(driver.Valuer); ok {
|
} else if nulType, ok := fieldValue.Interface().(driver.Valuer); ok {
|
||||||
val, _ = nulType.Value()
|
val, _ = nulType.Value()
|
||||||
if val == nil && !requiredField {
|
if val == nil && !requiredField {
|
||||||
|
|
|
@ -87,8 +87,8 @@ func (statement *Statement) Value2Interface(col *schemas.Column, fieldValue refl
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
if fieldType.ConvertibleTo(schemas.TimeType) {
|
if fieldType.ConvertibleTo(schemas.TimeType) {
|
||||||
t := fieldValue.Convert(schemas.TimeType).Interface().(time.Time)
|
t := fieldValue.Convert(schemas.TimeType).Interface().(time.Time)
|
||||||
tf := dialects.FormatColumnTime(statement.dialect, statement.defaultTimeZone, col, t)
|
tf, err := dialects.FormatColumnTime(statement.dialect, statement.defaultTimeZone, col, t)
|
||||||
return tf, nil
|
return tf, err
|
||||||
} else if fieldType.ConvertibleTo(nullFloatType) {
|
} else if fieldType.ConvertibleTo(nullFloatType) {
|
||||||
t := fieldValue.Convert(nullFloatType).Interface().(sql.NullFloat64)
|
t := fieldValue.Convert(nullFloatType).Interface().(sql.NullFloat64)
|
||||||
if !t.Valid {
|
if !t.Valid {
|
||||||
|
|
|
@ -212,7 +212,10 @@ func (session *Session) Delete(beans ...interface{}) (int64, error) {
|
||||||
paramsLen := len(condArgs)
|
paramsLen := len(condArgs)
|
||||||
copy(condArgs[1:paramsLen], condArgs[0:paramsLen-1])
|
copy(condArgs[1:paramsLen], condArgs[0:paramsLen-1])
|
||||||
|
|
||||||
val, t := session.engine.nowTime(deletedColumn)
|
val, t, err := session.engine.nowTime(deletedColumn)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
condArgs[0] = val
|
condArgs[0] = val
|
||||||
|
|
||||||
var colName = deletedColumn.Name
|
var colName = deletedColumn.Name
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"xorm.io/xorm/dialects"
|
||||||
"xorm.io/xorm/internal/convert"
|
"xorm.io/xorm/internal/convert"
|
||||||
"xorm.io/xorm/internal/utils"
|
"xorm.io/xorm/internal/utils"
|
||||||
"xorm.io/xorm/schemas"
|
"xorm.io/xorm/schemas"
|
||||||
|
@ -137,7 +138,10 @@ func (session *Session) insertMultipleStruct(rowsSlicePtr interface{}) (int64, e
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime {
|
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime {
|
||||||
val, t := session.engine.nowTime(col)
|
val, t, err := session.engine.nowTime(col)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
args = append(args, val)
|
args = append(args, val)
|
||||||
|
|
||||||
var colName = col.Name
|
var colName = col.Name
|
||||||
|
@ -427,29 +431,12 @@ func (session *Session) genInsertColumns(bean interface{}) ([]string, []interfac
|
||||||
if col.MapType == schemas.ONLYFROMDB {
|
if col.MapType == schemas.ONLYFROMDB {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if col.IsDeleted {
|
|
||||||
colNames = append(colNames, col.Name)
|
|
||||||
if !col.Nullable {
|
|
||||||
if col.SQLType.IsNumeric() {
|
|
||||||
args = append(args, 0)
|
|
||||||
} else {
|
|
||||||
args = append(args, time.Time{}.Format("2006-01-02 15:04:05"))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
args = append(args, nil)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if session.statement.OmitColumnMap.Contain(col.Name) {
|
if session.statement.OmitColumnMap.Contain(col.Name) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(session.statement.ColumnMap) > 0 && !session.statement.ColumnMap.Contain(col.Name) {
|
if len(session.statement.ColumnMap) > 0 && !session.statement.ColumnMap.Contain(col.Name) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if session.statement.IncrColumns.IsColExist(col.Name) {
|
if session.statement.IncrColumns.IsColExist(col.Name) {
|
||||||
continue
|
continue
|
||||||
} else if session.statement.DecrColumns.IsColExist(col.Name) {
|
} else if session.statement.DecrColumns.IsColExist(col.Name) {
|
||||||
|
@ -458,6 +445,16 @@ func (session *Session) genInsertColumns(bean interface{}) ([]string, []interfac
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if col.IsDeleted {
|
||||||
|
arg, err := dialects.FormatColumnTime(session.engine.dialect, session.engine.DatabaseTZ, col, time.Time{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
args = append(args, arg)
|
||||||
|
colNames = append(colNames, col.Name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
fieldValuePtr, err := col.ValueOf(bean)
|
fieldValuePtr, err := col.ValueOf(bean)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -478,7 +475,10 @@ func (session *Session) genInsertColumns(bean interface{}) ([]string, []interfac
|
||||||
|
|
||||||
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ {
|
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ {
|
||||||
// if time is non-empty, then set to auto time
|
// if time is non-empty, then set to auto time
|
||||||
val, t := session.engine.nowTime(col)
|
val, t, err := session.engine.nowTime(col)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
args = append(args, val)
|
args = append(args, val)
|
||||||
|
|
||||||
var colName = col.Name
|
var colName = col.Name
|
||||||
|
|
|
@ -215,7 +215,10 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
!session.statement.OmitColumnMap.Contain(table.Updated) {
|
!session.statement.OmitColumnMap.Contain(table.Updated) {
|
||||||
colNames = append(colNames, session.engine.Quote(table.Updated)+" = ?")
|
colNames = append(colNames, session.engine.Quote(table.Updated)+" = ?")
|
||||||
col := table.UpdatedColumn()
|
col := table.UpdatedColumn()
|
||||||
val, t := session.engine.nowTime(col)
|
val, t, err := session.engine.nowTime(col)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
if session.engine.dialect.URI().DBType == schemas.ORACLE {
|
if session.engine.dialect.URI().DBType == schemas.ORACLE {
|
||||||
args = append(args, t)
|
args = append(args, t)
|
||||||
} else {
|
} else {
|
||||||
|
@ -521,7 +524,10 @@ func (session *Session) genUpdateColumns(bean interface{}) ([]string, []interfac
|
||||||
|
|
||||||
if col.IsUpdated && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ {
|
if col.IsUpdated && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ {
|
||||||
// if time is non-empty, then set to auto time
|
// if time is non-empty, then set to auto time
|
||||||
val, t := session.engine.nowTime(col)
|
val, t, err := session.engine.nowTime(col)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
args = append(args, val)
|
args = append(args, val)
|
||||||
|
|
||||||
var colName = col.Name
|
var colName = col.Name
|
||||||
|
|
Loading…
Reference in New Issue