Skip to content

Conversation

@DavidWiseman
Copy link
Collaborator

DB exists check against master DB might fail for contained databases or if the user doesn't have permissions against master. If we can connect to the database, then it exists. Use both checks as trying to connect to a database that doesn't exist can introduce a delay. #1609

Copilot AI review requested due to automatic review settings November 7, 2025 15:44

This comment was marked as resolved.

This comment was marked as resolved.

This comment was marked as resolved.

DB exists check against master DB might fail for contained databases or if the user doesn't have permissions against master.  If we can connect to the database, then it exists.  Use both checks as trying to connect to a database that doesn't exist can introduce a delay. trimble-oss#1609
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

{
// Success on first completed (either DB or master)
DialogResult = DialogResult.OK;
cts.Cancel(); // cancel other pending attempt if still running
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After canceling at line 202, the code immediately returns without waiting for the cancelled task to complete. The cancelled task may still be executing and could throw an exception. Consider using try/finally or awaiting with exception suppression to ensure clean resource disposal.

Suggested change
cts.Cancel(); // cancel other pending attempt if still running
cts.Cancel(); // cancel other pending attempt if still running
try
{
// Await the other task to ensure clean completion and observe exceptions
var other = first == dbTask ? masterTask : dbTask;
await other.ContinueWith(t => { var _ = t.Exception; }, TaskContinuationOptions.OnlyOnFaulted);
}
catch
{
// Suppress any exceptions from the cancelled task
}

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created extension method to simplify

Comment on lines +409 to +411
catch
{
InvokeSetStatus(lblServerNameWarning, lblServerNameWarning.Text, lblServerNameWarning.ForeColor, lblServerNameWarning.Font.Style);
InvokeSetVisible(lblServerNameWarning, true);
// Ignore error. We might not be able to connect to master database
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nested try-catch blocks with empty catch clause on the inner block. The outer try at line 399 appears redundant since it doesn't have a matching catch block in the visible diff. Consider simplifying this structure or documenting the purpose of the outer try block.

Suggested change
catch
{
InvokeSetStatus(lblServerNameWarning, lblServerNameWarning.Text, lblServerNameWarning.ForeColor, lblServerNameWarning.Font.Style);
InvokeSetVisible(lblServerNameWarning, true);
// Ignore error. We might not be able to connect to master database
catch (Exception ex)
{
// Exception ignored intentionally: unable to connect to master database is expected in some scenarios (e.g., invalid credentials, network issues).
// If logging is available, consider logging ex at a debug or trace level for troubleshooting.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Outer is not redundant

builder.InitialCatalog = "master";
await using var cn = new SqlConnection(builder.ConnectionString);
await using var cmd = new SqlCommand(
"SELECT CASE WHEN EXISTS(SELECT 1 FROM sys.databases WHERE name = @db) THEN 1 ELSE 0 END",
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The query returns an int (1 or 0) but the original code expected a BIT/bool. The change from CAST(1 as BIT) to just 1 requires casting the result to int at line 58. This is correctly handled, but consider adding a comment explaining this type change for future maintainers.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't make much difference. Either is fine. 🤷

else
{
return Task.CompletedTask;
await Task.Run(() => dac.ProcessDacPac(connectionString, db, DACPackPath, status.VersionStatus));
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrapping a synchronous method ProcessDacPac in Task.Run creates a new thread. If ProcessDacPac is a long-running or frequently called operation, consider converting it to a truly async method rather than using thread pool offloading.

Suggested change
await Task.Run(() => dac.ProcessDacPac(connectionString, db, DACPackPath, status.VersionStatus));
await dac.ProcessDacPacAsync(connectionString, db, DACPackPath, status.VersionStatus);

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope. Could maybe be refactored but no async methods are currently provided.

Parser.Default.ParseArguments<Options>(args).WithParsed(async o => ...). An async lambda passed to WithParsed (which expects Action<Options>) becomes async void. Exceptions inside async void bypass normal Task exception propagation and can terminate the process.
Add ObserveFault() extension methods as a neater way to apply suggestion in PR trimble-oss#1626
@DavidWiseman DavidWiseman requested a review from Copilot November 8, 2025 13:26
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

builder.InitialCatalog = "master";
await using var cn = new SqlConnection(builder.ConnectionString);
await using var cmd = new SqlCommand(
"SELECT CASE WHEN EXISTS(SELECT 1 FROM sys.databases WHERE name = @db) THEN 1 ELSE 0 END",
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The query returns an int value instead of a bit. Consider using CAST(1 AS BIT) ELSE CAST(0 AS BIT) to match the original return type and avoid the type check result is int i && i == 1 in favor of a simpler (bool)result.

Copilot uses AI. Check for mistakes.
InvokeSetStatus(lblVersionInfo, "Validating...", DashColors.TrimbleBlue, FontStyle.Regular);
_ = Task.Run(() =>
{
_ = Task.Run(async ()=>{
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fire-and-forget task pattern detected. The underscore discard indicates the task result is intentionally ignored, but exceptions in this task will not be observed. Consider using .ContinueWith with error handling or storing the task reference to observe exceptions.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope

@DavidWiseman DavidWiseman merged commit cf0af31 into trimble-oss:main Nov 8, 2025
@DavidWiseman DavidWiseman deleted the 1609_DBExistsCheck branch November 8, 2025 13:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant