diff --git a/package.json b/package.json index 97798a8ffe..902cd8ac61 100644 --- a/package.json +++ b/package.json @@ -98,6 +98,11 @@ "command": "extension.disconnect", "title": "Disconnect active connection", "category": "MSSQL" + }, + { + "command": "extension.chooseDatabase", + "title": "Switch database on current server", + "category": "MSSQL" } ], "keybindings": [ diff --git a/src/controllers/connectionManager.ts b/src/controllers/connectionManager.ts index 7ecb5d7296..aca02849a4 100644 --- a/src/controllers/connectionManager.ts +++ b/src/controllers/connectionManager.ts @@ -74,6 +74,24 @@ export default class ConnectionManager { return this._connection && this._connection.connected; } + // choose database to use on current server + public onChooseDatabase(): void { + const self = this; + + if (typeof self._connection === 'undefined' || typeof self._connectionCreds === 'undefined') { + Utils.showWarnMsg(Constants.msgChooseDatabaseNotConnected); + return; + } + + self.connectionUI.showDatabasesOnCurrentServer(self._connectionCreds).then( newDatabaseCredentials => { + if (typeof newDatabaseCredentials !== 'undefined') { + self.onDisconnect().then( () => { + self.connect(newDatabaseCredentials); + }); + } + }); + } + // close active connection, if any public onDisconnect(): Promise { return new Promise((resolve, reject) => { diff --git a/src/controllers/controller.ts b/src/controllers/controller.ts index 5fdf642ed6..9aa1fd1390 100644 --- a/src/controllers/controller.ts +++ b/src/controllers/controller.ts @@ -51,6 +51,8 @@ export default class MainController implements vscode.Disposable { this._event.on(Constants.cmdDisconnect, () => { self.onDisconnect(); }); this.registerCommand(Constants.cmdRunQuery); this._event.on(Constants.cmdRunQuery, () => { self.onRunQuery(); }); + this.registerCommand(Constants.cmdChooseDatabase); + this._event.on(Constants.cmdChooseDatabase, () => { self.onChooseDatabase(); } ); // Init status bar this._statusview = new StatusView(); @@ -76,6 +78,11 @@ export default class MainController implements vscode.Disposable { Utils.logDebug(Constants.extensionActivated); } + // Choose a new database from the current server + private onChooseDatabase(): void { + return this._connectionMgr.onChooseDatabase(); + } + // Close active connection, if any private onDisconnect(): Promise { return this._connectionMgr.onDisconnect(); diff --git a/src/models/constants.ts b/src/models/constants.ts index 2db3395fc7..aa0e900e49 100644 --- a/src/models/constants.ts +++ b/src/models/constants.ts @@ -6,6 +6,7 @@ export const outputChannelName = 'MSSQL'; export const cmdRunQuery = 'extension.runQuery'; export const cmdConnect = 'extension.connect'; export const cmdDisconnect = 'extension.disconnect'; +export const cmdChooseDatabase = 'extension.chooseDatabase'; export const sqlDbPrefix = '.database.windows.net'; export const defaultConnectionTimeout = 15000; @@ -49,6 +50,9 @@ export const msgContentProviderOnClear = 'Content provider: clear called'; export const msgContentProviderOnUpdateContent = 'Content provider: updateContent called'; export const msgContentProviderProvideContent = 'Content provider: provideTextDocumentContent called: '; +export const msgChooseDatabaseNotConnected = 'Not connected. Please connect to a server first.'; +export const msgChooseDatabasePlaceholder = 'Choose a database from the list below'; + export const extensionActivated = 'activated.'; export const extensionDeactivated = 'de-activated.'; export const msgOpenSqlFile = `To use this command, Open a .sql file -or- diff --git a/src/views/connectionUI.ts b/src/views/connectionUI.ts index 4e0eebb484..9b27965bb9 100644 --- a/src/views/connectionUI.ts +++ b/src/views/connectionUI.ts @@ -5,6 +5,7 @@ import { RecentConnections } from '../models/recentConnections'; import Interfaces = require('../models/interfaces'); let async = require('async'); +const mssql = require('mssql'); export class ConnectionUI { // Helper to let user choose a connection from a picklist @@ -33,6 +34,52 @@ export class ConnectionUI { }); } + // Helper to let the user choose a database on the current server + // TODO: refactor this to use the service layer/SMO once the plumbing/conversion is complete + public showDatabasesOnCurrentServer(currentCredentials: Interfaces.IConnectionCredentials): Promise { + const self = this; + return new Promise((resolve, reject) => { + // create a new connection to the master db using the current connection as a base + let masterCredentials: Interfaces.IConnectionCredentials = {}; + Object.assign(masterCredentials, currentCredentials); + masterCredentials.database = 'master'; + const masterConnection = new mssql.Connection(masterCredentials); + + masterConnection.connect().then( () => { + // query sys.databases for a list of databases on the server + new mssql.Request(masterConnection).query('SELECT name FROM sys.databases').then( recordset => { + const pickListItems = recordset.map(record => { + let newCredentials: Interfaces.IConnectionCredentials = {}; + Object.assign(newCredentials, currentCredentials); + newCredentials.database = record.name; + + return { + label: record.name, + description: '', + detail: '', + connectionCreds: newCredentials + }; + }); + + const pickListOptions: vscode.QuickPickOptions = { + placeHolder: Constants.msgChooseDatabasePlaceholder + }; + + // show database picklist, and modify the current connection to switch the active database + vscode.window.showQuickPick(pickListItems, pickListOptions).then( selection => { + if (typeof selection !== 'undefined') { + resolve(selection.connectionCreds); + } else { + resolve(undefined); + } + }); + }).catch( err => { + reject(err); + }); + }); + }); + } + // Helper to prompt user to open VS Code user settings or workspace settings private openUserOrWorkspaceSettings(): void { let openGlobalSettingsItem: vscode.MessageItem = {