Skip to content

Commit ea1580b

Browse files
authored
Merge pull request #283 from databacker/fix-time-parsing
fix datetime parsing
2 parents 5288e5c + 117ffe0 commit ea1580b

File tree

4 files changed

+78
-1
lines changed

4 files changed

+78
-1
lines changed

pkg/database/connection.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ func (c Connection) MySQL() string {
1919
config.Passwd = c.Pass
2020
config.Net = "tcp"
2121
config.Addr = fmt.Sprintf("%s:%d", c.Host, c.Port)
22+
config.ParseTime = true
2223
return config.FormatDSN()
2324
}

pkg/database/mysql/date.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package mysql
2+
3+
import (
4+
"database/sql/driver"
5+
"fmt"
6+
"time"
7+
)
8+
9+
// NullDate represents a time.Time that may be null.
10+
// NullDate implements the Scanner interface so
11+
// it can be used as a scan destination, similar to NullString.
12+
// It is distinct from sql.NullTime in that it can output formats only as a date
13+
type NullDate struct {
14+
Date time.Time
15+
Valid bool
16+
}
17+
18+
// Scan implements the Scanner interface.
19+
func (n *NullDate) Scan(value any) error {
20+
if value == nil {
21+
n.Date, n.Valid = time.Time{}, false
22+
return nil
23+
}
24+
switch s := value.(type) {
25+
case string:
26+
t, err := time.Parse("2006-01-02", s)
27+
if err != nil {
28+
return err
29+
}
30+
n.Date = t
31+
n.Valid = true
32+
return nil
33+
case time.Time:
34+
n.Date = s
35+
n.Valid = true
36+
return nil
37+
}
38+
n.Valid = false
39+
return fmt.Errorf("unknown type %T for NullDate", value)
40+
}
41+
42+
// Value implements the driver Valuer interface.
43+
func (n NullDate) Value() (driver.Value, error) {
44+
if !n.Valid {
45+
return nil, nil
46+
}
47+
return n.Date.Format("2006-01-02"), nil
48+
}

pkg/database/mysql/dump.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,12 @@ func reflectColumnType(tp *sql.ColumnType) reflect.Type {
488488
return reflect.TypeOf(sql.NullInt64{})
489489
case "DOUBLE":
490490
return reflect.TypeOf(sql.NullFloat64{})
491+
case "TIMESTAMP", "DATETIME":
492+
return reflect.TypeOf(sql.NullTime{})
493+
case "DATE":
494+
return reflect.TypeOf(NullDate{})
495+
case "TIME":
496+
return reflect.TypeOf(sql.NullString{})
491497
}
492498

493499
// unknown datatype
@@ -557,6 +563,18 @@ func (table *table) RowBuffer() *bytes.Buffer {
557563
} else {
558564
fmt.Fprintf(&b, "_binary '%s'", sanitize(string(*s)))
559565
}
566+
case *NullDate:
567+
if s.Valid {
568+
fmt.Fprintf(&b, "'%s'", sanitize(s.Date.Format("2006-01-02")))
569+
} else {
570+
b.WriteString(nullType)
571+
}
572+
case *sql.NullTime:
573+
if s.Valid {
574+
fmt.Fprintf(&b, "'%s'", sanitize(s.Time.Format("2006-01-02 15:04:05")))
575+
} else {
576+
b.WriteString(nullType)
577+
}
560578
default:
561579
fmt.Fprintf(&b, "'%s'", value)
562580
}

test/backup_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,17 @@ func (d *dockerContext) createBackupFile(mysqlCID, mysqlUser, mysqlPass, outfile
303303
ctx := context.Background()
304304

305305
// Create and populate the table
306-
mysqlCreateCmd := []string{"mysql", "-hlocalhost", "--protocol=tcp", fmt.Sprintf("-u%s", mysqlUser), fmt.Sprintf("-p%s", mysqlPass), "-e", `use tester; create table t1 (id INT, name VARCHAR(20)); INSERT INTO t1 (id,name) VALUES (1, "John"), (2, "Jill"), (3, "Sam"), (4, "Sarah");`}
306+
mysqlCreateCmd := []string{"mysql", "-hlocalhost", "--protocol=tcp", fmt.Sprintf("-u%s", mysqlUser), fmt.Sprintf("-p%s", mysqlPass), "-e", `
307+
use tester;
308+
create table t1
309+
(id int, name varchar(20), d date, t time, dt datetime, ts timestamp);
310+
INSERT INTO t1 (id,name,d,t,dt,ts)
311+
VALUES
312+
(1, "John", "2012-11-01", "00:15:00", "2012-11-01 00:15:00", "2012-11-01 00:15:00"),
313+
(2, "Jill", "2012-11-02", "00:16:00", "2012-11-02 00:16:00", "2012-11-02 00:16:00"),
314+
(3, "Sam", "2012-11-03", "00:17:00", "2012-11-03 00:17:00", "2012-11-03 00:17:00"),
315+
(4, "Sarah", "2012-11-04", "00:18:00", "2012-11-04 00:18:00", "2012-11-04 00:18:00");
316+
`}
307317
attachResp, exitCode, err := d.execInContainer(ctx, mysqlCID, mysqlCreateCmd)
308318
if err != nil {
309319
return fmt.Errorf("failed to attach to exec: %w", err)

0 commit comments

Comments
 (0)