diff --git a/binlog/event_rows.go b/binlog/event_rows.go index 2488f4f..6b5be4b 100644 --- a/binlog/event_rows.go +++ b/binlog/event_rows.go @@ -1,7 +1,6 @@ package binlog import ( - "fmt" "time" "github.com/localhots/bocadillo/mysql" @@ -169,23 +168,11 @@ func (e *RowsEvent) decodeValue(buf *tools.Buffer, ct mysql.ColumnType, meta uin // Date and Time case mysql.ColumnTypeYear: - return uint16(buf.ReadUint8()) + 1900 + return mysql.DecodeYear(buf.ReadUint8()) case mysql.ColumnTypeDate: - v := buf.ReadUint24() - if v == 0 { - return "0000-00-00" - } - return fmt.Sprintf("%04d-%02d-%02d", v/(16*32), v/32%16, v%32) + return mysql.DecodeDate(buf.ReadUint24()) case mysql.ColumnTypeTime: - v := buf.ReadUint24() - if v == 0 { - return "00:00:00" - } - var sign string - if v < 0 { - sign = "-" - } - return fmt.Sprintf("%s%02d:%02d:%02d", sign, v/10000, (v%10000)/100, v%100) + return mysql.DecodeTime(buf.ReadUint24()) case mysql.ColumnTypeTime2: v, n := mysql.DecodeTime2(buf.Cur(), meta) buf.Skip(n) @@ -198,24 +185,13 @@ func (e *RowsEvent) decodeValue(buf *tools.Buffer, ct mysql.ColumnType, meta uin buf.Skip(n) return v case mysql.ColumnTypeDatetime: - v := buf.ReadUint64() - d := v / 1000000 - t := v % 1000000 - return mysql.FracTime{Time: time.Date(int(d/10000), - time.Month((d%10000)/100), - int(d%100), - int(t/10000), - int((t%10000)/100), - int(t%100), - 0, - time.UTC)}.String() + return mysql.DecodeDatetime(buf.ReadUint64()) case mysql.ColumnTypeDatetime2: v, n := mysql.DecodeDatetime2(buf.Cur(), meta) buf.Skip(n) return v // Strings - // FIXME case mysql.ColumnTypeString: return readString(buf, length) case mysql.ColumnTypeVarchar, mysql.ColumnTypeVarstring: diff --git a/mysql/time.go b/mysql/time.go index a2d912e..be64441 100644 --- a/mysql/time.go +++ b/mysql/time.go @@ -7,6 +7,31 @@ import ( "time" ) +// DecodeYear ... +func DecodeYear(v uint8) uint16 { + return uint16(v) + 1900 +} + +// DecodeDate ... +func DecodeDate(v uint32) string { + if v == 0 { + return "0000-00-00" + } + return fmt.Sprintf("%04d-%02d-%02d", v/(16*32), v/32%16, v%32) +} + +// DecodeTime ... +func DecodeTime(v uint32) string { + if v == 0 { + return "00:00:00" + } + var sign string + if v < 0 { + sign = "-" + } + return fmt.Sprintf("%s%02d:%02d:%02d", sign, v/10000, (v%10000)/100, v%100) +} + // DecodeTimestamp2 ... // Implementation borrowed from https://github.com/siddontang/go-mysql/ func DecodeTimestamp2(data []byte, dec uint16) (string, int) { @@ -30,6 +55,20 @@ func DecodeTimestamp2(data []byte, dec uint16) (string, int) { return FracTime{time.Unix(sec, usec*1000), int(dec)}.String(), n } +// DecodeDatetime ... +func DecodeDatetime(v uint64) string { + d := v / 1000000 + t := v % 1000000 + return FracTime{Time: time.Date(int(d/10000), + time.Month((d%10000)/100), + int(d%100), + int(t/10000), + int((t%10000)/100), + int(t%100), + 0, + time.UTC)}.String() +} + // DecodeDatetime2 ... // Implementation borrowed from https://github.com/siddontang/go-mysql/ func DecodeDatetime2(data []byte, dec uint16) (string, int) {