Skip to content

Commit 7bd70e5

Browse files
authored
Fix rendering of dynamic time values (#82)
1 parent cbafb93 commit 7bd70e5

File tree

5 files changed

+66
-6
lines changed

5 files changed

+66
-6
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ require (
1212
golang.org/x/text v0.3.6
1313
)
1414

15-
replace github.com/denisenkom/go-mssqldb => github.com/shueybubbles/go-mssqldb v0.10.1-0.20220317022252-fafb9d92e469
15+
replace github.com/denisenkom/go-mssqldb => github.com/microsoft/go-mssqldb v0.12.1-0.20220421181353-0db958cd919d

go.sum

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
2020
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
2121
github.com/mattn/go-runewidth v0.0.3 h1:a+kO+98RDGEfo6asOGMmpodZq4FNtnGP54yps8BzLR4=
2222
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
23+
github.com/microsoft/go-mssqldb v0.12.1-0.20220421181353-0db958cd919d h1:tsq7LhO5f4wOIPzLhDnwy2MAEQJTjc8KNu1LGmVwxJk=
24+
github.com/microsoft/go-mssqldb v0.12.1-0.20220421181353-0db958cd919d/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU=
2325
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
2426
github.com/peterh/liner v1.2.2 h1:aJ4AOodmL+JxOZZEL2u9iJf8omNRpqHc/EbrK+3mAXw=
2527
github.com/peterh/liner v1.2.2/go.mod h1:xFwJyiKIXJZUKItq5dGHZSTBRAuG/CpeNpWLyiNRNwI=
@@ -29,8 +31,6 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
2931
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
3032
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
3133
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
32-
github.com/shueybubbles/go-mssqldb v0.10.1-0.20220317022252-fafb9d92e469 h1:BuUMqsxB86i1QEBf0q+dkQYfNLVpD1nH1fRJPKvXWSg=
33-
github.com/shueybubbles/go-mssqldb v0.10.1-0.20220317022252-fafb9d92e469/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU=
3434
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
3535
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
3636
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
@@ -42,7 +42,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
4242
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b h1:k+E048sYJHyVnsr1GDrRZWQ32D2C7lWs9JRc0bel53A=
4343
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
4444
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
45-
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
4645
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
4746
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
4847
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -55,7 +54,6 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
5554
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
5655
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
5756
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
58-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
5957
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
6058
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
6159
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

pkg/sqlcmd/format.go

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ type columnDetail struct {
5656
leftJustify bool
5757
zeroesAfterDecimal bool
5858
col sql.ColumnType
59+
precision int
60+
scale int
5961
}
6062

6163
// The default formatter based on the native sqlcmd style
@@ -304,6 +306,11 @@ func calcColumnDetails(cols []*sql.ColumnType, fixed int64, variable int64) ([]c
304306
columnDetails[i].col = *c
305307
columnDetails[i].leftJustify = true
306308
columnDetails[i].zeroesAfterDecimal = false
309+
p, s, ok := c.DecimalSize()
310+
if ok {
311+
columnDetails[i].precision = int(p)
312+
columnDetails[i].scale = int(s)
313+
}
307314
if length == 0 {
308315
columnDetails[i].displayWidth = defaultMaxDisplayWidth
309316
} else {
@@ -359,6 +366,9 @@ func calcColumnDetails(cols []*sql.ColumnType, fixed int64, variable int64) ([]c
359366
columnDetails[i].leftJustify = false
360367
columnDetails[i].displayWidth = max64(38, nameLen)
361368
columnDetails[i].zeroesAfterDecimal = true
369+
case "TIME":
370+
columnDetails[i].leftJustify = false
371+
columnDetails[i].displayWidth = max64(16, nameLen)
362372
case "DATETIMEOFFSET":
363373
columnDetails[i].leftJustify = false
364374
columnDetails[i].displayWidth = max64(45, nameLen)
@@ -451,7 +461,26 @@ func (f *sqlCmdFormatterType) scanRow(rows *sql.Rows) ([]string, error) {
451461
row[n] = x
452462
case time.Time:
453463
// Go lacks any way to get the user's preferred time format or even the system default
454-
row[n] = x.String()
464+
switch f.columnDetails[n].col.DatabaseTypeName() {
465+
case "DATE":
466+
row[n] = x.Format("2006-01-02")
467+
case "DATETIME":
468+
row[n] = x.Format(dateTimeFormatString(3, false))
469+
case "DATETIME2":
470+
row[n] = x.Format(dateTimeFormatString(f.columnDetails[n].scale, false))
471+
case "SMALLDATETIME":
472+
row[n] = x.Format(dateTimeFormatString(0, false))
473+
case "DATETIMEOFFSET":
474+
row[n] = x.Format(dateTimeFormatString(f.columnDetails[n].scale, true))
475+
case "TIME":
476+
format := "15:04:05"
477+
if f.columnDetails[n].scale > 0 {
478+
format = fmt.Sprintf("%s.%0*d", format, f.columnDetails[n].scale, 0)
479+
}
480+
row[n] = x.Format(format)
481+
default:
482+
row[n] = x.Format(time.RFC3339)
483+
}
455484
case fmt.Stringer:
456485
row[n] = x.String()
457486
// not sure why go-mssql reports bit as bool
@@ -472,6 +501,17 @@ func (f *sqlCmdFormatterType) scanRow(rows *sql.Rows) ([]string, error) {
472501
return row, nil
473502
}
474503

504+
func dateTimeFormatString(scale int, addOffset bool) string {
505+
format := `2006-01-02 15:04:05`
506+
if scale > 0 {
507+
format = fmt.Sprintf("%s.%0*d", format, scale, 0)
508+
}
509+
if addOffset {
510+
format += " -07:00"
511+
}
512+
return format
513+
}
514+
475515
// Prints the final version of a cell based on formatting variables and command line parameters
476516
func (f *sqlCmdFormatterType) printColumnValue(val string, col int) {
477517
c := f.columnDetails[col]

pkg/sqlcmd/sqlcmd_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,19 @@ func TestSqlCmdMaintainsConnectionBetweenBatches(t *testing.T) {
417417
}
418418
}
419419

420+
func TestDateTimeFormats(t *testing.T) {
421+
s, buf := setupSqlCmdWithMemoryOutput(t)
422+
defer buf.Close()
423+
err := s.IncludeFile(`testdata/selectdates.sql`, true)
424+
if assert.NoError(t, err, "selectdates.sql") {
425+
assert.Equal(t,
426+
`2022-03-05 14:01:02.000 2021-01-02 11:06:02.2000 2021-05-05 00:00:00.000000 +00:00 2019-01-11 13:00:00 14:01:02.0000000 2011-02-03`+SqlcmdEol+SqlcmdEol,
427+
buf.buf.String(),
428+
"Unexpected date format output")
429+
430+
}
431+
}
432+
420433
// runSqlCmd uses lines as input for sqlcmd instead of relying on file or console input
421434
func runSqlCmd(t testing.TB, s *Sqlcmd, lines []string) error {
422435
t.Helper()
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
set nocount on
2+
declare @d1 datetime = '2022-03-05 14:01:02'
3+
declare @d2 datetime2(4) = '2021-1-2 11:06:02.2'
4+
declare @d3 datetimeoffset(6) = '2021-5-5'
5+
declare @d4 smalldatetime = '2019-01-11 13:00:00'
6+
declare @d5 time = '14:01:02'
7+
declare @d6 date = '2011-02-03'
8+
9+
select @d1, @d2, @d3, @d4, @d5, @d6

0 commit comments

Comments
 (0)