Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"request": "launch",
"mode" : "auto",
"program": "${workspaceFolder}/cmd/modern",
"args" : ["-S", "davidshi-2022", "-g", "-Q", "select nvarcharcol from encrypt.dbo.encrypted", "--driver-logging-level=65"],
"args" : ["-S", ".", "-Q", "select top 8 name from sys.all_objects"],
},
{
"name" : "Run file query",
Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"go.lintTool": "golangci-lint",
"go.lintOnSave": "workspace",
"azure-pipelines.1ESPipelineTemplatesSchemaFile": true
"azure-pipelines.1ESPipelineTemplatesSchemaFile": true,
"sarif-viewer.connectToGithubCodeScanning": "on"
}
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ The following switches have different behavior in this version of `sqlcmd` compa
- If `-N` is provided but `-C` is not, sqlcmd will require validation of the server certificate. Note that a `false` value for encryption could still lead to encryption of the login packet.
- `-C` has no effect when `strict` value is specified for `-N`.
- If both `-N` and `-C` are provided, sqlcmd will use their values for encryption negotiation.
- To provide the value of the host name in the server certificate when using strict encryption, pass the host name with `-F`. Example: `-Ns -F myhost.domain.com`
- More information about client/server encryption negotiation can be found at <https://docs.microsoft.com/openspecs/windows_protocols/ms-tds/60f56408-0188-4cd5-8b90-25c6f2423868>
- `-u` The generated Unicode output file will have the UTF16 Little-Endian Byte-order mark (BOM) written to it.
- Some behaviors that were kept to maintain compatibility with `OSQL` may be changed, such as alignment of column headers for some data types.
Expand All @@ -152,7 +153,7 @@ switches are most important to you to have implemented next in the new sqlcmd.
- Console output coloring (see below)
- `:Connect` now has an optional `-G` parameter to select one of the authentication methods for Azure SQL Database - `SqlAuthentication`, `ActiveDirectoryDefault`, `ActiveDirectoryIntegrated`, `ActiveDirectoryServicePrincipal`, `ActiveDirectoryManagedIdentity`, `ActiveDirectoryPassword`. If `-G` is not provided, either Integrated security or SQL Authentication will be used, dependent on the presence of a `-U` username parameter.
- The new `--driver-logging-level` command line parameter allows you to see traces from the `go-mssqldb` client driver. Use `64` to see all traces.
- Sqlcmd can now print results using a vertical format. Use the new `-F vertical` command line option to set it. It's also controlled by the `SQLCMDFORMAT` scripting variable.
- Sqlcmd can now print results using a vertical format. Use the new `--vertical` command line option to set it. It's also controlled by the `SQLCMDFORMAT` scripting variable.

```
1> select session_id, client_interface_name, program_name from sys.dm_exec_sessions where session_id=@@spid
Expand Down
28 changes: 14 additions & 14 deletions cmd/sqlcmd/sqlcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,12 @@ type SQLCmdArguments struct {
WorkstationName string
ApplicationIntent string
EncryptConnection string
HostNameInCertificate string
DriverLoggingLevel int
ExitOnError bool
ErrorSeverityLevel uint8
ErrorLevel int
Format string
Vertical bool
ErrorsToStderr *int
Headers int
UnicodeOutputFile bool
Expand Down Expand Up @@ -117,7 +118,6 @@ const (
sqlcmdErrorPrefix = "Sqlcmd: "
applicationIntent = "application-intent"
errorsToStderr = "errors-to-stderr"
format = "format"
encryptConnection = "encrypt-connection"
screenWidth = "screen-width"
fixedTypeWidth = "fixed-type-width"
Expand Down Expand Up @@ -316,14 +316,16 @@ func checkDefaultValue(args []string, i int) (val string) {
'k': "0",
'L': "|", // | is the sentinel for no value since users are unlikely to use it. It's "reserved" in most shells
'X': "0",
'N': "true",
}
if isFlag(args[i]) && len(args[i]) == 2 && (len(args) == i+1 || args[i+1][0] == '-') {
if v, ok := flags[rune(args[i][1])]; ok {
val = v
return
}
}
if args[i] == "-N" && (len(args) == i+1 || args[i+1][0] == '-') {
val = "true"
}
return
}

Expand Down Expand Up @@ -426,9 +428,10 @@ func setFlags(rootCmd *cobra.Command, args *SQLCmdArguments) {

rootCmd.Flags().StringVarP(&args.ApplicationIntent, applicationIntent, "K", "default", localizer.Sprintf("Declares the application workload type when connecting to a server. The only currently supported value is ReadOnly. If %s is not specified, the sqlcmd utility will not support connectivity to a secondary replica in an Always On availability group", localizer.ApplicationIntentFlagShort))
rootCmd.Flags().StringVarP(&args.EncryptConnection, encryptConnection, "N", "default", localizer.Sprintf("This switch is used by the client to request an encrypted connection"))
rootCmd.Flags().StringVarP(&args.HostNameInCertificate, "host-name-in-certificate", "F", "", localizer.Sprintf("Specifies the host name in the server certificate."))
// Can't use NoOptDefVal until this fix: https://github.com/spf13/cobra/issues/866
//rootCmd.Flags().Lookup(encryptConnection).NoOptDefVal = "true"
rootCmd.Flags().StringVarP(&args.Format, format, "F", "horiz", localizer.Sprintf("Specifies the formatting for results"))
rootCmd.Flags().BoolVarP(&args.Vertical, "vertical", "", false, localizer.Sprintf("Prints the output in vertical format. This option sets the sqlcmd scripting variable %s to '%s'. The default is false", sqlcmd.SQLCMDFORMAT, "vert"))
_ = rootCmd.Flags().IntP(errorsToStderr, "r", -1, localizer.Sprintf("%s Redirects error messages with severity >= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", "-r[0 | 1]"))
rootCmd.Flags().IntVar(&args.DriverLoggingLevel, "driver-logging-level", 0, localizer.Sprintf("Level of mssql driver messages to print"))
rootCmd.Flags().BoolVarP(&args.ExitOnError, "exit-on-error", "b", false, localizer.Sprintf("Specifies that sqlcmd exits and returns a %s value when an error occurs", localizer.DosErrorLevel))
Expand Down Expand Up @@ -492,15 +495,6 @@ func normalizeFlags(cmd *cobra.Command) error {
err = invalidParameterError("-N", v, "m[andatory]", "yes", "1", "t[rue]", "disable", "o[ptional]", "no", "0", "f[alse]", "s[trict]")
return pflag.NormalizedName("")
}
case format:
value := strings.ToLower(v)
switch value {
case "horiz", "horizontal", "vert", "vertical":
return pflag.NormalizedName(name)
default:
err = invalidParameterError("-F", v, "horiz", "horizontal", "vert", "vertical")
return pflag.NormalizedName("")
}
case errorsToStderr:
switch v {
case "0", "1":
Expand Down Expand Up @@ -670,7 +664,12 @@ func setVars(vars *sqlcmd.Variables, args *SQLCmdArguments) {
}
return ""
},
sqlcmd.SQLCMDFORMAT: func(a *SQLCmdArguments) string { return a.Format },
sqlcmd.SQLCMDFORMAT: func(a *SQLCmdArguments) string {
if a.Vertical {
return "vert"
}
return "horizontal"
},
}
for varname, set := range varmap {
val := set(args)
Expand Down Expand Up @@ -721,6 +720,7 @@ func setConnect(connect *sqlcmd.ConnectSettings, args *SQLCmdArguments, vars *sq
default:
connect.Encrypt = args.EncryptConnection
}
connect.HostNameInCertificate = args.HostNameInCertificate
connect.PacketSize = args.PacketSize
connect.WorkstationName = args.WorkstationName
connect.LogLevel = args.DriverLoggingLevel
Expand Down
8 changes: 5 additions & 3 deletions cmd/sqlcmd/sqlcmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ func TestValidCommandLineToArgsConversion(t *testing.T) {
{[]string{"-b", "-m", "15", "-V", "20"}, func(args SQLCmdArguments) bool {
return args.ExitOnError && args.ErrorLevel == 15 && args.ErrorSeverityLevel == 20
}},
{[]string{"-F", "vert"}, func(args SQLCmdArguments) bool {
return args.Format == "vert"
{[]string{"--vertical"}, func(args SQLCmdArguments) bool {
return args.Vertical
}},
{[]string{"-r", "1"}, func(args SQLCmdArguments) bool {
return *args.ErrorsToStderr == 1
Expand Down Expand Up @@ -108,6 +108,9 @@ func TestValidCommandLineToArgsConversion(t *testing.T) {
{[]string{"-ifoo.sql", "bar.sql", "-V10"}, func(args SQLCmdArguments) bool {
return args.ErrorSeverityLevel == 10 && args.InputFile[0] == "foo.sql" && args.InputFile[1] == "bar.sql"
}},
{[]string{"-N", "s", "-F", "myserver.domain.com"}, func(args SQLCmdArguments) bool {
return args.EncryptConnection == "s" && args.HostNameInCertificate == "myserver.domain.com"
}},
}

for _, test := range commands {
Expand Down Expand Up @@ -151,7 +154,6 @@ func TestInvalidCommandLine(t *testing.T) {
{[]string{"-E", "-U", "someuser"}, "The -E and the -U/-P options are mutually exclusive."},
{[]string{"-L", "-q", `"select 1"`}, "The -L parameter can not be used in combination with other parameters."},
{[]string{"-i", "foo.sql", "-q", `"select 1"`}, "The i and the -Q/-q options are mutually exclusive."},
{[]string{"-F", "what"}, "'-F what': Unexpected argument. Argument value has to be one of [horiz horizontal vert vertical]."},
{[]string{"-r", "5"}, `'-r 5': Unexpected argument. Argument value has to be one of [0 1].`},
{[]string{"-w", "x"}, "'-w x': value must be greater than 8 and less than 65536."},
{[]string{"-y", "111111"}, "'-y 111111': value must be greater than or equal to 0 and less than or equal to 8000."},
Expand Down
Loading
Loading