-
Notifications
You must be signed in to change notification settings - Fork 84
feat: implement :serverlist command #630
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
601948f
8fd1d8f
1af7232
5be11cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -172,6 +172,41 @@ switches are most important to you to have implemented next in the new sqlcmd. | |||||||||||||||||||
| - `: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 `--vertical` command line option to set it. It's also controlled by the `SQLCMDFORMAT` scripting variable. | ||||||||||||||||||||
| - `:help` displays a list of available sqlcmd commands. | ||||||||||||||||||||
| - `:serverlist` lists local SQL Server instances discovered via the SQL Server Browser service (UDP port 1434). The command queries the SQL Browser service and displays the server name and instance name for each discovered instance. If no instances are found or the Browser service is not running, no output is produced. Non-timeout errors are printed to stderr. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| ``` | ||||||||||||||||||||
| 1> :serverlist | ||||||||||||||||||||
| MYSERVER\SQL2019 | ||||||||||||||||||||
| MYSERVER\SQL2022 | ||||||||||||||||||||
|
Comment on lines
+180
to
+181
|
||||||||||||||||||||
| MYSERVER\SQL2019 | |
| MYSERVER\SQL2022 | |
| MYSERVER\SQL2019 | |
| MYSERVER\SQL2022 |
Copilot
AI
Jan 25, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example output doesn't show the behavior when the default MSSQLSERVER instance is present. According to the code (serverlist.go:82-83), the default instance produces two entries in the output: "(local)" and the actual server name (e.g., "MYSERVER"). Consider adding an example showing this case, such as " (local)\n MYSERVER\n MYSERVER\SQL2019".
| MYSERVER\SQL2019 | |
| MYSERVER\SQL2022 | |
| (local) | |
| MYSERVER | |
| MYSERVER\SQL2019 |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,121 @@ | ||||||||||
| // Copyright (c) Microsoft Corporation. | ||||||||||
| // Licensed under the MIT license. | ||||||||||
|
|
||||||||||
| package sqlcmd | ||||||||||
|
|
||||||||||
| import ( | ||||||||||
| "context" | ||||||||||
| "errors" | ||||||||||
| "fmt" | ||||||||||
| "io" | ||||||||||
| "net" | ||||||||||
| "os" | ||||||||||
| "sort" | ||||||||||
| "strings" | ||||||||||
| "time" | ||||||||||
|
|
||||||||||
| "github.com/microsoft/go-mssqldb/msdsn" | ||||||||||
| ) | ||||||||||
|
|
||||||||||
| // ListLocalServers queries the SQL Browser service for available SQL Server instances | ||||||||||
| // and writes the results to the provided writer. | ||||||||||
| func ListLocalServers(w io.Writer) { | ||||||||||
| instances, err := GetLocalServerInstances() | ||||||||||
| if err != nil { | ||||||||||
| fmt.Fprintln(os.Stderr, err) | ||||||||||
|
||||||||||
| fmt.Fprintln(os.Stderr, err) | |
| fmt.Fprintln(w, err) |
Copilot
AI
Jan 25, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The validation added here (checking if InstanceName exists and is non-empty) is a good improvement over the old implementation. However, consider adding a comment explaining why instances without InstanceName should be skipped, as this represents a defensive measure against malformed SQL Browser responses.
| // Only add if InstanceName key exists and is non-empty | |
| // Only add if InstanceName key exists and is non-empty. | |
| // This defensively skips malformed or partial SQL Browser responses | |
| // that do not include a valid InstanceName for an instance. |
Uh oh!
There was an error while loading. Please reload this page.