terraform/vendor/github.com/ziutek/mymysql/mysql/types.go

226 lines
4.2 KiB
Go

package mysql
import (
"errors"
"fmt"
"strconv"
"strings"
"time"
)
// For MySQL DATE type
type Date struct {
Year int16
Month, Day byte
}
func (dd Date) String() string {
return fmt.Sprintf("%04d-%02d-%02d", dd.Year, dd.Month, dd.Day)
}
// True if date is 0000-00-00
func (dd Date) IsZero() bool {
return dd.Day == 0 && dd.Month == 0 && dd.Year == 0
}
// Converts Date to time.Time using loc location.
// Converts MySQL zero to time.Time zero.
func (dd Date) Time(loc *time.Location) (t time.Time) {
if !dd.IsZero() {
t = time.Date(
int(dd.Year), time.Month(dd.Month), int(dd.Day),
0, 0, 0, 0,
loc,
)
}
return
}
// Converts Date to time.Time using Local location.
// Converts MySQL zero to time.Time zero.
func (dd Date) Localtime() time.Time {
return dd.Time(time.Local)
}
// Convert string date in format YYYY-MM-DD to Date.
// Leading and trailing spaces are ignored.
func ParseDate(str string) (dd Date, err error) {
str = strings.TrimSpace(str)
if str == "0000-00-00" {
return
}
var (
y, m, d int
)
if len(str) != 10 || str[4] != '-' || str[7] != '-' {
goto invalid
}
if y, err = strconv.Atoi(str[0:4]); err != nil {
return
}
if m, err = strconv.Atoi(str[5:7]); err != nil {
return
}
if m < 0 || m > 12 { // MySQL permits month == 0
goto invalid
}
if d, err = strconv.Atoi(str[8:10]); err != nil {
return
}
if d < 0 { // MySQL permits day == 0
goto invalid
}
switch m {
case 1, 3, 5, 7, 8, 10, 12:
if d > 31 {
goto invalid
}
case 4, 6, 9, 11:
if d > 30 {
goto invalid
}
case 2:
if d > 29 {
goto invalid
}
}
dd.Year = int16(y)
dd.Month = byte(m)
dd.Day = byte(d)
return
invalid:
err = errors.New("Invalid MySQL DATE string: " + str)
return
}
// Sandard MySQL datetime format
const TimeFormat = "2006-01-02 15:04:05.000000000"
// Returns t as string in MySQL format Converts time.Time zero to MySQL zero.
func TimeString(t time.Time) string {
if t.IsZero() {
return "0000-00-00 00:00:00"
}
if t.Nanosecond() == 0 {
return t.Format(TimeFormat[:19])
}
return t.Format(TimeFormat)
}
// Parses string datetime in TimeFormat using loc location.
// Converts MySQL zero to time.Time zero.
func ParseTime(str string, loc *time.Location) (t time.Time, err error) {
str = strings.TrimSpace(str)
format := TimeFormat[:19]
switch len(str) {
case 10:
if str == "0000-00-00" {
return
}
format = format[:10]
case 19:
if str == "0000-00-00 00:00:00" {
return
}
}
// Don't expect 0000-00-00 00:00:00.0+
t, err = time.ParseInLocation(format, str, loc)
return
}
// Convert time.Duration to string representation of mysql.TIME
func DurationString(d time.Duration) string {
sign := 1
if d < 0 {
sign = -1
d = -d
}
ns := int(d % 1e9)
d /= 1e9
sec := int(d % 60)
d /= 60
min := int(d % 60)
hour := int(d/60) * sign
if ns == 0 {
return fmt.Sprintf("%d:%02d:%02d", hour, min, sec)
}
return fmt.Sprintf("%d:%02d:%02d.%09d", hour, min, sec, ns)
}
// Parse duration from MySQL string format [+-]H+:MM:SS[.UUUUUUUUU].
// Leading and trailing spaces are ignored. If format is invalid returns nil.
func ParseDuration(str string) (dur time.Duration, err error) {
str = strings.TrimSpace(str)
orig := str
// Check sign
sign := int64(1)
switch str[0] {
case '-':
sign = -1
fallthrough
case '+':
str = str[1:]
}
var i, d int64
// Find houre
if nn := strings.IndexRune(str, ':'); nn != -1 {
if i, err = strconv.ParseInt(str[0:nn], 10, 64); err != nil {
return
}
d = i * 3600
str = str[nn+1:]
} else {
goto invalid
}
if len(str) != 5 && len(str) != 15 || str[2] != ':' {
goto invalid
}
if i, err = strconv.ParseInt(str[0:2], 10, 64); err != nil {
return
}
if i < 0 || i > 59 {
goto invalid
}
d += i * 60
if i, err = strconv.ParseInt(str[3:5], 10, 64); err != nil {
return
}
if i < 0 || i > 59 {
goto invalid
}
d += i
d *= 1e9
if len(str) == 15 {
if str[5] != '.' {
goto invalid
}
if i, err = strconv.ParseInt(str[6:15], 10, 64); err != nil {
return
}
d += i
}
dur = time.Duration(d * sign)
return
invalid:
err = errors.New("invalid MySQL TIME string: " + orig)
return
}
type Blob []byte
type Raw struct {
Typ uint16
Val *[]byte
}
type Timestamp struct {
time.Time
}
func (t Timestamp) String() string {
return TimeString(t.Time)
}