From 26ad8b271f82284eaffc8bf3963c5f2689040248 Mon Sep 17 00:00:00 2001 From: David Shiflet Date: Wed, 12 Oct 2022 17:04:53 -0400 Subject: [PATCH] implement -s, -w, -W --- cmd/sqlcmd/main.go | 28 ++++++++++++++++++++++------ cmd/sqlcmd/main_test.go | 4 ++++ go.mod | 6 +++--- go.sum | 12 ++++++++++++ 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/cmd/sqlcmd/main.go b/cmd/sqlcmd/main.go index 44684140..4e1d280d 100644 --- a/cmd/sqlcmd/main.go +++ b/cmd/sqlcmd/main.go @@ -55,6 +55,9 @@ type SQLCmdArguments struct { Headers int `short:"h" help:"Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed."` UnicodeOutputFile bool `short:"u" help:"Specifies that all output files are encoded with little-endian Unicode"` Version bool `help:"Show the sqlcmd version information"` + ColumnSeparator string `short:"s" help:"Specifies the column separator character. Sets the SQLCMDCOLSEP variable."` + ScreenWidth *int `short:"w" help:"Specifies the screen width for output. Sets the SQLCMDCOLWIDTH variable."` + TrimSpaces bool `short:"W" help:"Remove trailing spaces from a column."` // Keep Help at the end of the list Help bool `short:"?" help:"Show syntax summary."` } @@ -68,6 +71,9 @@ func (a *SQLCmdArguments) Validate() error { if a.Headers < -1 { return fmt.Errorf(`'-h %d': header value must be either -1 or a value between 1 and 2147483647`, a.Headers) } + if a.ScreenWidth != nil && (*a.ScreenWidth < 9 || *a.ScreenWidth > 65535) { + return fmt.Errorf(`'-w %d': value must be greater than 8 and less than 65536.`, *a.ScreenWidth) + } return nil } @@ -155,11 +161,21 @@ func setVars(vars *sqlcmd.Variables, args *SQLCmdArguments) { } return "" }, - sqlcmd.SQLCMDUSER: func(a *SQLCmdArguments) string { return a.UserName }, - sqlcmd.SQLCMDSTATTIMEOUT: func(a *SQLCmdArguments) string { return "" }, - sqlcmd.SQLCMDHEADERS: func(a *SQLCmdArguments) string { return fmt.Sprint(a.Headers) }, - sqlcmd.SQLCMDCOLSEP: func(a *SQLCmdArguments) string { return "" }, - sqlcmd.SQLCMDCOLWIDTH: func(a *SQLCmdArguments) string { return "" }, + sqlcmd.SQLCMDUSER: func(a *SQLCmdArguments) string { return a.UserName }, + sqlcmd.SQLCMDSTATTIMEOUT: func(a *SQLCmdArguments) string { return "" }, + sqlcmd.SQLCMDHEADERS: func(a *SQLCmdArguments) string { return fmt.Sprint(a.Headers) }, + sqlcmd.SQLCMDCOLSEP: func(a *SQLCmdArguments) string { + if a.ColumnSeparator != "" { + return string(a.ColumnSeparator[0]) + } + return "" + }, + sqlcmd.SQLCMDCOLWIDTH: func(a *SQLCmdArguments) string { + if a.ScreenWidth != nil { + return fmt.Sprint(*a.ScreenWidth) + } + return "" + }, sqlcmd.SQLCMDMAXVARTYPEWIDTH: func(a *SQLCmdArguments) string { return "" }, sqlcmd.SQLCMDMAXFIXEDTYPEWIDTH: func(a *SQLCmdArguments) string { return "" }, sqlcmd.SQLCMDFORMAT: func(a *SQLCmdArguments) string { return a.Format }, @@ -246,7 +262,7 @@ func run(vars *sqlcmd.Variables, args *SQLCmdArguments) (int, error) { } s.Connect = &connectConfig - s.Format = sqlcmd.NewSQLCmdDefaultFormatter(false) + s.Format = sqlcmd.NewSQLCmdDefaultFormatter(args.TrimSpaces) if args.OutputFile != "" { err = s.RunCommand(s.Cmd["OUT"], []string{args.OutputFile}) if err != nil { diff --git a/cmd/sqlcmd/main_test.go b/cmd/sqlcmd/main_test.go index a69f5b65..1177f503 100644 --- a/cmd/sqlcmd/main_test.go +++ b/cmd/sqlcmd/main_test.go @@ -88,6 +88,9 @@ func TestValidCommandLineToArgsConversion(t *testing.T) { {[]string{"--version"}, func(args SQLCmdArguments) bool { return args.Version }}, + {[]string{"-s", "|", "-w", "10", "-W"}, func(args SQLCmdArguments) bool { + return args.TrimSpaces && args.ColumnSeparator == "|" && *args.ScreenWidth == 10 + }}, } for _, test := range commands { @@ -117,6 +120,7 @@ func TestInvalidCommandLine(t *testing.T) { {[]string{"-F", "what"}, "--format must be one of \"horiz\",\"horizontal\",\"vert\",\"vertical\" but got \"what\""}, {[]string{"-r", "5"}, `--errors-to-stderr must be one of "-1","0","1" but got '\x05'`}, {[]string{"-h-4"}, "test: '-h -4': header value must be either -1 or a value between 1 and 2147483647"}, + {[]string{"-w", "6"}, "test: '-w 6': value must be greater than 8 and less than 65536."}, } for _, test := range commands { diff --git a/go.mod b/go.mod index 162ec093..e9b839b9 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,12 @@ module github.com/microsoft/go-sqlcmd go 1.18 require ( - github.com/alecthomas/kong v0.5.1-0.20220516223738-0aaa4c11997b + github.com/alecthomas/kong v0.6.2-0.20220922001058-c62bf25854a0 github.com/golang-sql/sqlexp v0.1.0 github.com/google/uuid v1.3.0 github.com/microsoft/go-mssqldb v0.17.0 github.com/peterh/liner v1.2.2 - github.com/stretchr/testify v1.7.1 + github.com/stretchr/testify v1.8.0 golang.org/x/text v0.3.7 ) @@ -27,5 +27,5 @@ require ( golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88 // indirect golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7 // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 21114d54..3a6ec387 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,13 @@ github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0 h1:WVsrXCnHlDD github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= github.com/alecthomas/kong v0.5.1-0.20220516223738-0aaa4c11997b h1:QF7Hdi3ReQRAST66vU7bqkHODmcVJIUZyTGo9gLHluk= github.com/alecthomas/kong v0.5.1-0.20220516223738-0aaa4c11997b/go.mod h1:GaAkr/DV/nSKftP7snQLewFh9pZqrm+OEn3HqkvWU7c= +github.com/alecthomas/kong v0.6.1 h1:1kNhcFepkR+HmasQpbiKDLylIL8yh5B5y1zPp5bJimA= +github.com/alecthomas/kong v0.6.1/go.mod h1:JfHWDzLmbh/puW6I3V7uWenoh56YNVONW+w8eKeUr9I= +github.com/alecthomas/kong v0.6.2-0.20220922001058-c62bf25854a0 h1:HQ3WlFsqBcr4qsiHtfA7UdFSrChglOcQa8q/tbXJFBI= +github.com/alecthomas/kong v0.6.2-0.20220922001058-c62bf25854a0/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U= github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142 h1:8Uy0oSf5co/NZXje7U1z8Mpep++QJOldL2hs/sBQf48= github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= +github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -44,9 +49,14 @@ github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzL github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88 h1:Tgea0cVUD0ivh5ADBX4WwuI12DUd2to3nCYe2eayMIw= @@ -85,3 +95,5 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=