@@ -20,6 +20,7 @@ import { Logger } from "../models/logger";
2020import { Profiler as LocProfiler } from "../constants/locConstants" ;
2121import * as Constants from "../constants/constants" ;
2222import { TreeNodeInfo } from "../objectExplorer/nodes/treeNodeInfo" ;
23+ import { ObjectExplorerUtils } from "../objectExplorer/objectExplorerUtils" ;
2324import { IConnectionProfile } from "../models/interfaces" ;
2425import { getServerTypes , isAzureSqlDbCompatible } from "../models/connectionInfo" ;
2526import { getErrorMessage , uuid } from "../utils/utils" ;
@@ -59,9 +60,11 @@ export class ProfilerController {
5960 * Launches the profiler UI with a provided connection profile (from Object Explorer).
6061 * This is the main entry point - profiler can only be launched via right-click context menu.
6162 * @param connectionProfile - The connection profile to use for profiling
63+ * @param databaseScopeFilter - If provided, pre-populates a DatabaseName filter in the profiler UI
6264 */
6365 public async launchProfilerWithConnection (
6466 connectionProfile : IConnectionProfile ,
67+ databaseScopeFilter ?: string ,
6568 ) : Promise < void > {
6669 this . _logger . verbose (
6770 `Launching profiler with connection to ${ connectionProfile . server } ...` ,
@@ -90,13 +93,23 @@ export class ProfilerController {
9093 // For Azure SQL and Fabric, we need to ensure a user database is selected
9194 let profileToUse = connectionProfile ;
9295 if ( isAzureOrFabric ) {
93- const updatedProfile = await this . ensureAzureDatabaseSelected ( connectionProfile ) ;
96+ // When launched from a Database node, pre-fill the database so
97+ // the user is not prompted to select one again.
98+ if ( databaseScopeFilter ) {
99+ profileToUse = { ...connectionProfile , database : databaseScopeFilter } ;
100+ }
101+
102+ const updatedProfile = await this . ensureAzureDatabaseSelected ( profileToUse ) ;
94103 if ( ! updatedProfile ) {
95104 // User cancelled database selection
96105 this . _logger . verbose ( "User cancelled database selection" ) ;
97106 return ;
98107 }
99108 profileToUse = updatedProfile ;
109+
110+ // Azure sessions are already database-scoped via ON DATABASE,
111+ // so skip the client-side DatabaseName filter entirely.
112+ databaseScopeFilter = undefined ;
100113 }
101114
102115 // Generate a unique URI for this profiler connection
@@ -118,7 +131,7 @@ export class ProfilerController {
118131 this . _profilerEngineTypes . set ( profilerUri , this . _currentEngineType ) ;
119132
120133 // Use the common setup method - pass engine type to avoid race condition
121- await this . setupProfilerUI ( profilerUri , this . _currentEngineType ) ;
134+ await this . setupProfilerUI ( profilerUri , this . _currentEngineType , databaseScopeFilter ) ;
122135 } catch ( e ) {
123136 this . _logger . error ( `Error launching profiler: ${ e } ` ) ;
124137 vscode . window . showErrorMessage ( LocProfiler . failedToLaunchProfiler ( getErrorMessage ( e ) ) ) ;
@@ -245,6 +258,31 @@ export class ProfilerController {
245258 ) ,
246259 ) ;
247260
261+ // Launch Profiler from a Database node in Object Explorer (pre-filters by database)
262+ this . _context . subscriptions . push (
263+ vscode . commands . registerCommand (
264+ "mssql.profiler.launchFromDatabase" ,
265+ async ( treeNodeInfo : TreeNodeInfo ) => {
266+ try {
267+ const connectionProfile = treeNodeInfo . connectionProfile ;
268+ // Use ObjectExplorerUtils.getDatabaseName to reliably get the database name.
269+ // connectionProfile.database is often empty for Database nodes because they
270+ // inherit the parent Server node's connection profile unchanged.
271+ const databaseName = ObjectExplorerUtils . getDatabaseName ( treeNodeInfo ) ;
272+ this . _logger . verbose (
273+ `Launching profiler from database node: ${ databaseName } ` ,
274+ ) ;
275+ await this . launchProfilerWithConnection ( connectionProfile , databaseName ) ;
276+ } catch ( e ) {
277+ this . _logger . error ( `Command error: ${ e } ` ) ;
278+ vscode . window . showErrorMessage (
279+ LocProfiler . failedToLaunchProfiler ( getErrorMessage ( e ) ) ,
280+ ) ;
281+ }
282+ } ,
283+ ) ,
284+ ) ;
285+
248286 // Open XEL File command
249287 this . _context . subscriptions . push (
250288 vscode . commands . registerCommand ( "mssql.profiler.openXelFile" , async ( ) => {
@@ -524,8 +562,13 @@ export class ProfilerController {
524562 * and auto-starts profiling.
525563 * @param profilerUri - The URI of the established profiler connection
526564 * @param engineType - The engine type for filtering templates
565+ * @param databaseScopeFilter - If provided, pre-populates a DatabaseName filter in the profiler UI
527566 */
528- private async setupProfilerUI ( profilerUri : string , engineType : EngineType ) : Promise < void > {
567+ private async setupProfilerUI (
568+ profilerUri : string ,
569+ engineType : EngineType ,
570+ databaseScopeFilter ?: string ,
571+ ) : Promise < void > {
529572 this . _profilerUri = profilerUri ;
530573
531574 // Step 1: Show template selection quick pick (filtered by engine type)
@@ -616,6 +659,11 @@ export class ProfilerController {
616659 selectedTemplate . template . id ,
617660 ) ;
618661
662+ // If launched from a database node, set the initial database filter
663+ if ( databaseScopeFilter ) {
664+ webviewController . setInitialDatabaseFilter ( databaseScopeFilter ) ;
665+ }
666+
619667 // Track this webview controller along with its profiler URI for cleanup
620668 const webviewId = uuid ( ) ;
621669 const webviewProfilerUri = profilerUri ; // Capture for cleanup
0 commit comments