1
1
package mysql
2
2
3
3
import (
4
+ "bytes"
5
+ "encoding/binary"
4
6
"math"
5
7
"strconv"
8
+ "time"
6
9
7
10
"github.com/pingcap/errors"
8
11
@@ -39,13 +42,53 @@ func FormatTextValue(value interface{}) ([]byte, error) {
39
42
return v , nil
40
43
case string :
41
44
return utils .StringToByteSlice (v ), nil
45
+ case time.Time :
46
+ return utils .StringToByteSlice (v .Format (time .DateTime )), nil
42
47
case nil :
43
48
return nil , nil
44
49
default :
45
50
return nil , errors .Errorf ("invalid type %T" , value )
46
51
}
47
52
}
48
53
54
+ func toBinaryDateTime (t time.Time ) ([]byte , error ) {
55
+ var buf bytes.Buffer
56
+
57
+ if t .IsZero () {
58
+ return nil , nil
59
+ }
60
+
61
+ year , month , day := t .Year (), t .Month (), t .Day ()
62
+ hour , min , sec := t .Hour (), t .Minute (), t .Second ()
63
+ nanosec := t .Nanosecond ()
64
+
65
+ if nanosec > 0 {
66
+ buf .WriteByte (byte (11 ))
67
+ _ = binary .Write (& buf , binary .LittleEndian , uint16 (year ))
68
+ buf .WriteByte (byte (month ))
69
+ buf .WriteByte (byte (day ))
70
+ buf .WriteByte (byte (hour ))
71
+ buf .WriteByte (byte (min ))
72
+ buf .WriteByte (byte (sec ))
73
+ _ = binary .Write (& buf , binary .LittleEndian , uint32 (nanosec / 1000 ))
74
+ } else if hour > 0 || min > 0 || sec > 0 {
75
+ buf .WriteByte (byte (7 ))
76
+ _ = binary .Write (& buf , binary .LittleEndian , uint16 (year ))
77
+ buf .WriteByte (byte (month ))
78
+ buf .WriteByte (byte (day ))
79
+ buf .WriteByte (byte (hour ))
80
+ buf .WriteByte (byte (min ))
81
+ buf .WriteByte (byte (sec ))
82
+ } else {
83
+ buf .WriteByte (byte (4 ))
84
+ _ = binary .Write (& buf , binary .LittleEndian , uint16 (year ))
85
+ buf .WriteByte (byte (month ))
86
+ buf .WriteByte (byte (day ))
87
+ }
88
+
89
+ return buf .Bytes (), nil
90
+ }
91
+
49
92
func formatBinaryValue (value interface {}) ([]byte , error ) {
50
93
switch v := value .(type ) {
51
94
case int8 :
@@ -76,6 +119,8 @@ func formatBinaryValue(value interface{}) ([]byte, error) {
76
119
return v , nil
77
120
case string :
78
121
return utils .StringToByteSlice (v ), nil
122
+ case time.Time :
123
+ return toBinaryDateTime (v )
79
124
default :
80
125
return nil , errors .Errorf ("invalid type %T" , value )
81
126
}
@@ -91,6 +136,8 @@ func fieldType(value interface{}) (typ uint8, err error) {
91
136
typ = MYSQL_TYPE_DOUBLE
92
137
case string , []byte :
93
138
typ = MYSQL_TYPE_VAR_STRING
139
+ case time.Time :
140
+ typ = MYSQL_TYPE_DATETIME
94
141
case nil :
95
142
typ = MYSQL_TYPE_NULL
96
143
default :
@@ -110,7 +157,7 @@ func formatField(field *Field, value interface{}) error {
110
157
case float32 , float64 :
111
158
field .Charset = 63
112
159
field .Flag = BINARY_FLAG | NOT_NULL_FLAG
113
- case string , []byte :
160
+ case string , []byte , time. Time :
114
161
field .Charset = 33
115
162
case nil :
116
163
field .Charset = 33
0 commit comments