mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-17 09:35:37 -05:00
Merge from vscode 81d7885dc2e9dc617e1522697a2966bc4025a45d (#5949)
* Merge from vscode 81d7885dc2e9dc617e1522697a2966bc4025a45d * Fix vs unit tests and hygiene issue * Fix strict null check issue
This commit is contained in:
@@ -1,104 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import { IAccountManagementService } from 'sql/platform/accounts/common/interfaces';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import {
|
||||
ExtHostAccountManagementShape,
|
||||
MainThreadAccountManagementShape,
|
||||
SqlExtHostContext,
|
||||
SqlMainContext
|
||||
} from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
|
||||
|
||||
@extHostNamedCustomer(SqlMainContext.MainThreadAccountManagement)
|
||||
export class MainThreadAccountManagement implements MainThreadAccountManagementShape {
|
||||
private _providerMetadata: { [handle: number]: azdata.AccountProviderMetadata };
|
||||
private _proxy: ExtHostAccountManagementShape;
|
||||
private _toDispose: IDisposable[];
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@IAccountManagementService private _accountManagementService: IAccountManagementService
|
||||
) {
|
||||
this._providerMetadata = {};
|
||||
if (extHostContext) {
|
||||
this._proxy = extHostContext.getProxy(SqlExtHostContext.ExtHostAccountManagement);
|
||||
}
|
||||
this._toDispose = [];
|
||||
|
||||
this._accountManagementService.updateAccountListEvent((e: UpdateAccountListEventParams) => {
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
|
||||
const providerMetadataIndex = Object.values(this._providerMetadata).findIndex((providerMetadata: azdata.AccountProviderMetadata) => providerMetadata.id === e.providerId);
|
||||
if (providerMetadataIndex === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const providerHandle = parseInt(Object.keys(this._providerMetadata)[providerMetadataIndex]);
|
||||
this._proxy.$accountsChanged(providerHandle, e.accountList);
|
||||
});
|
||||
}
|
||||
|
||||
public $beginAutoOAuthDeviceCode(providerId: string, title: string, message: string, userCode: string, uri: string): Thenable<void> {
|
||||
return this._accountManagementService.beginAutoOAuthDeviceCode(providerId, title, message, userCode, uri);
|
||||
}
|
||||
|
||||
public $endAutoOAuthDeviceCode(): void {
|
||||
return this._accountManagementService.endAutoOAuthDeviceCode();
|
||||
}
|
||||
|
||||
$accountUpdated(updatedAccount: azdata.Account): void {
|
||||
this._accountManagementService.accountUpdated(updatedAccount);
|
||||
}
|
||||
|
||||
public $getAccountsForProvider(providerId: string): Thenable<azdata.Account[]> {
|
||||
return this._accountManagementService.getAccountsForProvider(providerId);
|
||||
}
|
||||
|
||||
public $registerAccountProvider(providerMetadata: azdata.AccountProviderMetadata, handle: number): Thenable<any> {
|
||||
let self = this;
|
||||
|
||||
// Create the account provider that interfaces with the extension via the proxy and register it
|
||||
let accountProvider: azdata.AccountProvider = {
|
||||
autoOAuthCancelled(): Thenable<void> {
|
||||
return self._proxy.$autoOAuthCancelled(handle);
|
||||
},
|
||||
clear(accountKey: azdata.AccountKey): Thenable<void> {
|
||||
return self._proxy.$clear(handle, accountKey);
|
||||
},
|
||||
getSecurityToken(account: azdata.Account, resource: azdata.AzureResource): Thenable<{}> {
|
||||
return self._proxy.$getSecurityToken(account, resource);
|
||||
},
|
||||
initialize(restoredAccounts: azdata.Account[]): Thenable<azdata.Account[]> {
|
||||
return self._proxy.$initialize(handle, restoredAccounts);
|
||||
},
|
||||
prompt(): Thenable<azdata.Account | azdata.PromptFailedResult> {
|
||||
return self._proxy.$prompt(handle);
|
||||
},
|
||||
refresh(account: azdata.Account): Thenable<azdata.Account | azdata.PromptFailedResult> {
|
||||
return self._proxy.$refresh(handle, account);
|
||||
}
|
||||
};
|
||||
this._accountManagementService.registerProvider(providerMetadata, accountProvider);
|
||||
this._providerMetadata[handle] = providerMetadata;
|
||||
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
public $unregisterAccountProvider(handle: number): Thenable<any> {
|
||||
this._accountManagementService.unregisterProvider(this._providerMetadata[handle]);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._toDispose = dispose(this._toDispose);
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ITaskService } from 'sql/platform/tasks/common/tasksService';
|
||||
import { MainThreadBackgroundTaskManagementShape, SqlMainContext, ExtHostBackgroundTaskManagementShape, SqlExtHostContext } from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
|
||||
export enum TaskStatus {
|
||||
NotStarted = 0,
|
||||
InProgress = 1,
|
||||
Succeeded = 2,
|
||||
SucceededWithWarning = 3,
|
||||
Failed = 4,
|
||||
Canceled = 5,
|
||||
Canceling = 6
|
||||
}
|
||||
|
||||
@extHostNamedCustomer(SqlMainContext.MainThreadBackgroundTaskManagement)
|
||||
export class MainThreadBackgroundTaskManagement extends Disposable implements MainThreadBackgroundTaskManagementShape {
|
||||
private readonly _proxy: ExtHostBackgroundTaskManagementShape;
|
||||
|
||||
constructor(
|
||||
context: IExtHostContext,
|
||||
@ITaskService private _taskService: ITaskService
|
||||
) {
|
||||
super();
|
||||
this._proxy = context.getProxy(SqlExtHostContext.ExtHostBackgroundTaskManagement);
|
||||
this._register(this._taskService.onTaskComplete(task => {
|
||||
if (task.status === TaskStatus.Canceling) {
|
||||
this._proxy.$onTaskCanceled(task.id);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
$registerTask(taskInfo: azdata.TaskInfo): void {
|
||||
this._taskService.createNewTask(taskInfo);
|
||||
this._proxy.$onTaskRegistered(taskInfo.taskId);
|
||||
}
|
||||
|
||||
$updateTask(taskProgressInfo: azdata.TaskProgressInfo): void {
|
||||
this._taskService.updateTask(taskProgressInfo);
|
||||
}
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { SqlExtHostContext, SqlMainContext, ExtHostConnectionManagementShape, MainThreadConnectionManagementShape } from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||
import * as azdata from 'azdata';
|
||||
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { IConnectionManagementService, ConnectionType } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import * as TaskUtilities from 'sql/workbench/common/taskUtilities';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||
import { IConnectionDialogService } from 'sql/workbench/services/connection/common/connectionDialogService';
|
||||
|
||||
@extHostNamedCustomer(SqlMainContext.MainThreadConnectionManagement)
|
||||
export class MainThreadConnectionManagement implements MainThreadConnectionManagementShape {
|
||||
|
||||
private _proxy: ExtHostConnectionManagementShape;
|
||||
private _toDispose: IDisposable[];
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
|
||||
@IObjectExplorerService private _objectExplorerService: IObjectExplorerService,
|
||||
@IEditorService private _workbenchEditorService: IEditorService,
|
||||
@IConnectionDialogService private _connectionDialogService: IConnectionDialogService,
|
||||
@ICapabilitiesService private _capabilitiesService: ICapabilitiesService
|
||||
) {
|
||||
if (extHostContext) {
|
||||
this._proxy = extHostContext.getProxy(SqlExtHostContext.ExtHostConnectionManagement);
|
||||
}
|
||||
this._toDispose = [];
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._toDispose = dispose(this._toDispose);
|
||||
}
|
||||
|
||||
public $getActiveConnections(): Thenable<azdata.connection.Connection[]> {
|
||||
return Promise.resolve(this._connectionManagementService.getActiveConnections().map(profile => this.convertConnection(profile)));
|
||||
}
|
||||
|
||||
public $getCurrentConnection(): Thenable<azdata.connection.Connection> {
|
||||
return Promise.resolve(this.convertConnection(TaskUtilities.getCurrentGlobalConnection(this._objectExplorerService, this._connectionManagementService, this._workbenchEditorService, true)));
|
||||
}
|
||||
|
||||
public $getCredentials(connectionId: string): Thenable<{ [name: string]: string }> {
|
||||
return Promise.resolve(this._connectionManagementService.getActiveConnectionCredentials(connectionId));
|
||||
}
|
||||
|
||||
public $getServerInfo(connectionId: string): Thenable<azdata.ServerInfo> {
|
||||
return Promise.resolve(this._connectionManagementService.getServerInfo(connectionId));
|
||||
}
|
||||
|
||||
public async $openConnectionDialog(providers: string[], initialConnectionProfile?: IConnectionProfile, connectionCompletionOptions?: azdata.IConnectionCompletionOptions): Promise<azdata.connection.Connection> {
|
||||
// Here we default to ConnectionType.editor which saves the connecton in the connection store by default
|
||||
let connectionType = ConnectionType.editor;
|
||||
|
||||
// If the API call explicitly set saveConnection to false, set it to ConnectionType.extension
|
||||
// which doesn't save the connection by default
|
||||
if (connectionCompletionOptions && !connectionCompletionOptions.saveConnection) {
|
||||
connectionType = ConnectionType.temporary;
|
||||
}
|
||||
let connectionProfile = await this._connectionDialogService.openDialogAndWait(this._connectionManagementService,
|
||||
{ connectionType: connectionType, providers: providers }, initialConnectionProfile, undefined);
|
||||
const connection = connectionProfile ? {
|
||||
connectionId: connectionProfile.id,
|
||||
options: connectionProfile.options,
|
||||
providerName: connectionProfile.providerName
|
||||
} : undefined;
|
||||
|
||||
if (connectionCompletionOptions && connectionCompletionOptions.saveConnection) {
|
||||
// Somehow, connectionProfile.saveProfile is false even if initialConnectionProfile.saveProfile is true, reset the flag here.
|
||||
connectionProfile.saveProfile = initialConnectionProfile.saveProfile;
|
||||
await this._connectionManagementService.connectAndSaveProfile(connectionProfile, undefined, {
|
||||
saveTheConnection: isUndefinedOrNull(connectionCompletionOptions.saveConnection) ? true : connectionCompletionOptions.saveConnection,
|
||||
showDashboard: isUndefinedOrNull(connectionCompletionOptions.showDashboard) ? false : connectionCompletionOptions.showDashboard,
|
||||
params: undefined,
|
||||
showConnectionDialogOnError: isUndefinedOrNull(connectionCompletionOptions.showConnectionDialogOnError) ? true : connectionCompletionOptions.showConnectionDialogOnError,
|
||||
showFirewallRuleOnError: isUndefinedOrNull(connectionCompletionOptions.showFirewallRuleOnError) ? true : connectionCompletionOptions.showFirewallRuleOnError
|
||||
});
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
||||
public async $listDatabases(connectionId: string): Promise<string[]> {
|
||||
let connectionUri = await this.$getUriForConnection(connectionId);
|
||||
let result = await this._connectionManagementService.listDatabases(connectionUri);
|
||||
return result.databaseNames;
|
||||
}
|
||||
|
||||
public async $getConnectionString(connectionId: string, includePassword: boolean): Promise<string> {
|
||||
return this._connectionManagementService.getConnectionString(connectionId, includePassword);
|
||||
}
|
||||
|
||||
public $getUriForConnection(connectionId: string): Thenable<string> {
|
||||
return Promise.resolve(this._connectionManagementService.getConnectionUriFromId(connectionId));
|
||||
}
|
||||
|
||||
private convertConnection(profile: IConnectionProfile): azdata.connection.Connection {
|
||||
if (!profile) {
|
||||
return undefined;
|
||||
}
|
||||
profile = this._connectionManagementService.removeConnectionProfileCredentials(profile);
|
||||
let connection: azdata.connection.Connection = {
|
||||
providerName: profile.providerName,
|
||||
connectionId: profile.id,
|
||||
options: profile.options
|
||||
};
|
||||
return connection;
|
||||
}
|
||||
|
||||
public $connect(connectionProfile: IConnectionProfile, saveConnection: boolean = true, showDashboard: boolean = true): Thenable<azdata.ConnectionResult> {
|
||||
let profile = new ConnectionProfile(this._capabilitiesService, connectionProfile);
|
||||
profile.id = generateUuid();
|
||||
return this._connectionManagementService.connectAndSaveProfile(profile, undefined, {
|
||||
saveTheConnection: saveConnection,
|
||||
showDashboard: showDashboard,
|
||||
params: undefined,
|
||||
showConnectionDialogOnError: true,
|
||||
showFirewallRuleOnError: true
|
||||
}).then((result) => {
|
||||
return <azdata.ConnectionResult>{
|
||||
connected: result.connected,
|
||||
connectionId: result.connected ? profile.id : undefined,
|
||||
errorCode: result.errorCode,
|
||||
errorMessage: result.errorMessage
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import {
|
||||
SqlExtHostContext, ExtHostCredentialManagementShape,
|
||||
MainThreadCredentialManagementShape, SqlMainContext
|
||||
} from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||
import { ICredentialsService } from 'sql/platform/credentials/common/credentialsService';
|
||||
import * as azdata from 'azdata';
|
||||
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
|
||||
@extHostNamedCustomer(SqlMainContext.MainThreadCredentialManagement)
|
||||
export class MainThreadCredentialManagement implements MainThreadCredentialManagementShape {
|
||||
|
||||
private _proxy: ExtHostCredentialManagementShape;
|
||||
|
||||
private _toDispose: IDisposable[];
|
||||
|
||||
private _registrations: { [handle: number]: IDisposable; } = Object.create(null);
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@ICredentialsService private credentialService: ICredentialsService
|
||||
) {
|
||||
if (extHostContext) {
|
||||
this._proxy = extHostContext.getProxy(SqlExtHostContext.ExtHostCredentialManagement);
|
||||
}
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._toDispose = dispose(this._toDispose);
|
||||
}
|
||||
|
||||
public $registerCredentialProvider(handle: number): Promise<any> {
|
||||
let self = this;
|
||||
|
||||
this._registrations[handle] = this.credentialService.addEventListener(handle, {
|
||||
onSaveCredential(credentialId: string, password: string): Thenable<boolean> {
|
||||
return self._proxy.$saveCredential(credentialId, password);
|
||||
},
|
||||
onReadCredential(credentialId: string): Thenable<azdata.Credential> {
|
||||
return self._proxy.$readCredential(credentialId);
|
||||
},
|
||||
onDeleteCredential(credentialId: string): Thenable<boolean> {
|
||||
return self._proxy.$deleteCredential(credentialId);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $unregisterCredentialProvider(handle: number): Promise<any> {
|
||||
let registration = this._registrations[handle];
|
||||
if (registration) {
|
||||
registration.dispose();
|
||||
delete this._registrations[handle];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { MainThreadDashboardWebviewShape, SqlMainContext, ExtHostDashboardWebviewsShape, SqlExtHostContext } from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { IDashboardViewService, IDashboardWebview } from 'sql/platform/dashboard/common/dashboardViewService';
|
||||
|
||||
@extHostNamedCustomer(SqlMainContext.MainThreadDashboardWebview)
|
||||
export class MainThreadDashboardWebview implements MainThreadDashboardWebviewShape {
|
||||
|
||||
private static _handlePool = 0;
|
||||
private readonly _proxy: ExtHostDashboardWebviewsShape;
|
||||
private readonly _dialogs = new Map<number, IDashboardWebview>();
|
||||
|
||||
private knownWidgets = new Array<string>();
|
||||
|
||||
constructor(
|
||||
context: IExtHostContext,
|
||||
@IDashboardViewService viewService: IDashboardViewService
|
||||
) {
|
||||
this._proxy = context.getProxy(SqlExtHostContext.ExtHostDashboardWebviews);
|
||||
viewService.onRegisteredWebview(e => {
|
||||
if (this.knownWidgets.includes(e.id)) {
|
||||
let handle = MainThreadDashboardWebview._handlePool++;
|
||||
this._dialogs.set(handle, e);
|
||||
this._proxy.$registerWidget(handle, e.id, e.connection, e.serverInfo);
|
||||
e.onMessage(e => {
|
||||
this._proxy.$onMessage(handle, e);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
$sendMessage(handle: number, message: string) {
|
||||
this._dialogs.get(handle).sendMessage(message);
|
||||
}
|
||||
|
||||
$setHtml(handle: number, value: string) {
|
||||
this._dialogs.get(handle).setHtml(value);
|
||||
}
|
||||
|
||||
$registerProvider(widgetId: string) {
|
||||
this.knownWidgets.push(widgetId);
|
||||
}
|
||||
}
|
||||
@@ -1,597 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import {
|
||||
SqlExtHostContext, ExtHostDataProtocolShape,
|
||||
MainThreadDataProtocolShape, SqlMainContext
|
||||
} from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||
import { IQueryManagementService } from 'sql/platform/query/common/queryManagement';
|
||||
import * as azdata from 'azdata';
|
||||
import { IMetadataService } from 'sql/platform/metadata/common/metadataService';
|
||||
import { IObjectExplorerService, NodeExpandInfoWithProviderId } from 'sql/workbench/services/objectExplorer/common/objectExplorerService';
|
||||
import { IScriptingService } from 'sql/platform/scripting/common/scriptingService';
|
||||
import { IAdminService } from 'sql/workbench/services/admin/common/adminService';
|
||||
import { IJobManagementService } from 'sql/platform/jobManagement/common/interfaces';
|
||||
import { IBackupService } from 'sql/platform/backup/common/backupService';
|
||||
import { IRestoreService } from 'sql/platform/restore/common/restoreService';
|
||||
import { ITaskService } from 'sql/platform/tasks/common/tasksService';
|
||||
import { IProfilerService } from 'sql/workbench/services/profiler/common/interfaces';
|
||||
import { ISerializationService } from 'sql/platform/serialization/common/serializationService';
|
||||
import { IFileBrowserService } from 'sql/platform/fileBrowser/common/interfaces';
|
||||
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { IDacFxService } from 'sql/platform/dacfx/common/dacFxService';
|
||||
import { ISchemaCompareService } from 'sql/platform/schemaCompare/common/schemaCompareService';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
|
||||
/**
|
||||
* Main thread class for handling data protocol management registration.
|
||||
*/
|
||||
@extHostNamedCustomer(SqlMainContext.MainThreadDataProtocol)
|
||||
export class MainThreadDataProtocol implements MainThreadDataProtocolShape {
|
||||
|
||||
private _proxy: ExtHostDataProtocolShape;
|
||||
|
||||
private _toDispose: IDisposable[];
|
||||
|
||||
private _capabilitiesRegistrations: { [handle: number]: IDisposable; } = Object.create(null);
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
|
||||
@ICapabilitiesService private _capabilitiesService: ICapabilitiesService,
|
||||
@IQueryManagementService private _queryManagementService: IQueryManagementService,
|
||||
@IMetadataService private _metadataService: IMetadataService,
|
||||
@IObjectExplorerService private _objectExplorerService: IObjectExplorerService,
|
||||
@IScriptingService private _scriptingService: IScriptingService,
|
||||
@IAdminService private _adminService: IAdminService,
|
||||
@IJobManagementService private _jobManagementService: IJobManagementService,
|
||||
@IBackupService private _backupService: IBackupService,
|
||||
@IRestoreService private _restoreService: IRestoreService,
|
||||
@ITaskService private _taskService: ITaskService,
|
||||
@IProfilerService private _profilerService: IProfilerService,
|
||||
@ISerializationService private _serializationService: ISerializationService,
|
||||
@IFileBrowserService private _fileBrowserService: IFileBrowserService,
|
||||
@IDacFxService private _dacFxService: IDacFxService,
|
||||
@ISchemaCompareService private _schemaCompareService: ISchemaCompareService,
|
||||
) {
|
||||
if (extHostContext) {
|
||||
this._proxy = extHostContext.getProxy(SqlExtHostContext.ExtHostDataProtocol);
|
||||
}
|
||||
if (this._connectionManagementService) {
|
||||
this._connectionManagementService.onLanguageFlavorChanged(e => this._proxy.$languageFlavorChanged(e), this, this._toDispose);
|
||||
}
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._toDispose = dispose(this._toDispose);
|
||||
}
|
||||
|
||||
public $registerConnectionProvider(providerId: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._connectionManagementService.registerProvider(providerId, <azdata.ConnectionProvider>{
|
||||
connect(connectionUri: string, connectionInfo: azdata.ConnectionInfo): Thenable<boolean> {
|
||||
return self._proxy.$connect(handle, connectionUri, connectionInfo);
|
||||
},
|
||||
disconnect(connectionUri: string): Thenable<boolean> {
|
||||
return self._proxy.$disconnect(handle, connectionUri);
|
||||
},
|
||||
changeDatabase(connectionUri: string, newDatabase: string): Thenable<boolean> {
|
||||
return self._proxy.$changeDatabase(handle, connectionUri, newDatabase);
|
||||
},
|
||||
cancelConnect(connectionUri: string): Thenable<boolean> {
|
||||
return self._proxy.$cancelConnect(handle, connectionUri);
|
||||
},
|
||||
listDatabases(connectionUri: string): Thenable<azdata.ListDatabasesResult> {
|
||||
return self._proxy.$listDatabases(handle, connectionUri);
|
||||
},
|
||||
getConnectionString(connectionUri: string, includePassword: boolean): Thenable<string> {
|
||||
return self._proxy.$getConnectionString(handle, connectionUri, includePassword);
|
||||
},
|
||||
buildConnectionInfo(connectionString: string): Thenable<azdata.ConnectionInfo> {
|
||||
return self._proxy.$buildConnectionInfo(handle, connectionString);
|
||||
},
|
||||
rebuildIntelliSenseCache(connectionUri: string): Thenable<void> {
|
||||
return self._proxy.$rebuildIntelliSenseCache(handle, connectionUri);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $registerQueryProvider(providerId: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._queryManagementService.addQueryRequestHandler(providerId, {
|
||||
cancelQuery(ownerUri: string): Thenable<azdata.QueryCancelResult> {
|
||||
return self._proxy.$cancelQuery(handle, ownerUri);
|
||||
},
|
||||
runQuery(ownerUri: string, selection: azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions): Thenable<void> {
|
||||
return self._proxy.$runQuery(handle, ownerUri, selection, runOptions);
|
||||
},
|
||||
runQueryStatement(ownerUri: string, line: number, column: number): Thenable<void> {
|
||||
return self._proxy.$runQueryStatement(handle, ownerUri, line, column);
|
||||
},
|
||||
runQueryString(ownerUri: string, queryString: string): Thenable<void> {
|
||||
return self._proxy.$runQueryString(handle, ownerUri, queryString);
|
||||
},
|
||||
runQueryAndReturn(ownerUri: string, queryString: string): Thenable<azdata.SimpleExecuteResult> {
|
||||
return self._proxy.$runQueryAndReturn(handle, ownerUri, queryString);
|
||||
},
|
||||
parseSyntax(ownerUri: string, query: string): Thenable<azdata.SyntaxParseResult> {
|
||||
return self._proxy.$parseSyntax(handle, ownerUri, query);
|
||||
},
|
||||
getQueryRows(rowData: azdata.QueryExecuteSubsetParams): Thenable<azdata.QueryExecuteSubsetResult> {
|
||||
return self._proxy.$getQueryRows(handle, rowData);
|
||||
},
|
||||
setQueryExecutionOptions(ownerUri: string, options: azdata.QueryExecutionOptions): Thenable<void> {
|
||||
return self._proxy.$setQueryExecutionOptions(handle, ownerUri, options);
|
||||
},
|
||||
disposeQuery(ownerUri: string): Thenable<void> {
|
||||
return self._proxy.$disposeQuery(handle, ownerUri);
|
||||
},
|
||||
saveResults(requestParams: azdata.SaveResultsRequestParams): Thenable<azdata.SaveResultRequestResult> {
|
||||
let serializationProvider = self._serializationService.getSerializationFeatureMetadataProvider(requestParams.ownerUri);
|
||||
if (serializationProvider && serializationProvider.enabled) {
|
||||
return self._proxy.$saveResults(handle, requestParams);
|
||||
}
|
||||
else if (serializationProvider && !serializationProvider.enabled) {
|
||||
return self._serializationService.disabledSaveAs();
|
||||
}
|
||||
else {
|
||||
return self._serializationService.saveAs(requestParams.resultFormat, requestParams.filePath, undefined, true);
|
||||
}
|
||||
},
|
||||
initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): Thenable<void> {
|
||||
return self._proxy.$initializeEdit(handle, ownerUri, schemaName, objectName, objectType, rowLimit, queryString);
|
||||
},
|
||||
updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Thenable<azdata.EditUpdateCellResult> {
|
||||
return self._proxy.$updateCell(handle, ownerUri, rowId, columnId, newValue);
|
||||
},
|
||||
commitEdit(ownerUri): Thenable<void> {
|
||||
return self._proxy.$commitEdit(handle, ownerUri);
|
||||
},
|
||||
createRow(ownerUri: string): Thenable<azdata.EditCreateRowResult> {
|
||||
return self._proxy.$createRow(handle, ownerUri);
|
||||
},
|
||||
deleteRow(ownerUri: string, rowId: number): Thenable<void> {
|
||||
return self._proxy.$deleteRow(handle, ownerUri, rowId);
|
||||
},
|
||||
disposeEdit(ownerUri: string): Thenable<void> {
|
||||
return self._proxy.$disposeEdit(handle, ownerUri);
|
||||
},
|
||||
revertCell(ownerUri: string, rowId: number, columnId: number): Thenable<azdata.EditRevertCellResult> {
|
||||
return self._proxy.$revertCell(handle, ownerUri, rowId, columnId);
|
||||
},
|
||||
revertRow(ownerUri: string, rowId: number): Thenable<void> {
|
||||
return self._proxy.$revertRow(handle, ownerUri, rowId);
|
||||
},
|
||||
getEditRows(rowData: azdata.EditSubsetParams): Thenable<azdata.EditSubsetResult> {
|
||||
return self._proxy.$getEditRows(handle, rowData);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $registerBackupProvider(providerId: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._backupService.registerProvider(providerId, <azdata.BackupProvider>{
|
||||
backup(connectionUri: string, backupInfo: { [key: string]: any }, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.BackupResponse> {
|
||||
return self._proxy.$backup(handle, connectionUri, backupInfo, taskExecutionMode);
|
||||
},
|
||||
getBackupConfigInfo(connectionUri: string): Thenable<azdata.BackupConfigInfo> {
|
||||
return self._proxy.$getBackupConfigInfo(handle, connectionUri);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $registerRestoreProvider(providerId: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._restoreService.registerProvider(providerId, <azdata.RestoreProvider>{
|
||||
getRestorePlan(connectionUri: string, restoreInfo: azdata.RestoreInfo): Thenable<azdata.RestorePlanResponse> {
|
||||
return self._proxy.$getRestorePlan(handle, connectionUri, restoreInfo);
|
||||
},
|
||||
cancelRestorePlan(connectionUri: string, restoreInfo: azdata.RestoreInfo): Thenable<boolean> {
|
||||
return self._proxy.$cancelRestorePlan(handle, connectionUri, restoreInfo);
|
||||
},
|
||||
restore(connectionUri: string, restoreInfo: azdata.RestoreInfo): Thenable<azdata.RestoreResponse> {
|
||||
return self._proxy.$restore(handle, connectionUri, restoreInfo);
|
||||
},
|
||||
getRestoreConfigInfo(connectionUri: string): Thenable<azdata.RestoreConfigInfo> {
|
||||
return self._proxy.$getRestoreConfigInfo(handle, connectionUri);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $registerMetadataProvider(providerId: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._metadataService.registerProvider(providerId, <azdata.MetadataProvider>{
|
||||
getMetadata(connectionUri: string): Thenable<azdata.ProviderMetadata> {
|
||||
return self._proxy.$getMetadata(handle, connectionUri);
|
||||
},
|
||||
getDatabases(connectionUri: string): Thenable<string[]> {
|
||||
return self._proxy.$getDatabases(handle, connectionUri);
|
||||
},
|
||||
getTableInfo(connectionUri: string, metadata: azdata.ObjectMetadata): Thenable<azdata.ColumnMetadata[]> {
|
||||
return self._proxy.$getTableInfo(handle, connectionUri, metadata);
|
||||
},
|
||||
getViewInfo(connectionUri: string, metadata: azdata.ObjectMetadata): Thenable<azdata.ColumnMetadata[]> {
|
||||
return self._proxy.$getViewInfo(handle, connectionUri, metadata);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $registerObjectExplorerProvider(providerId: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._objectExplorerService.registerProvider(providerId, <azdata.ObjectExplorerProvider>{
|
||||
providerId: providerId,
|
||||
createNewSession(connection: azdata.ConnectionInfo): Thenable<azdata.ObjectExplorerSessionResponse> {
|
||||
return self._proxy.$createObjectExplorerSession(handle, connection);
|
||||
},
|
||||
expandNode(nodeInfo: azdata.ExpandNodeInfo): Thenable<boolean> {
|
||||
return self._proxy.$expandObjectExplorerNode(handle, nodeInfo);
|
||||
},
|
||||
refreshNode(nodeInfo: azdata.ExpandNodeInfo): Thenable<boolean> {
|
||||
return self._proxy.$refreshObjectExplorerNode(handle, nodeInfo);
|
||||
},
|
||||
closeSession(closeSessionInfo: azdata.ObjectExplorerCloseSessionInfo): Thenable<azdata.ObjectExplorerCloseSessionResponse> {
|
||||
return self._proxy.$closeObjectExplorerSession(handle, closeSessionInfo);
|
||||
},
|
||||
findNodes(findNodesInfo: azdata.FindNodesInfo): Thenable<azdata.ObjectExplorerFindNodesResponse> {
|
||||
return self._proxy.$findNodes(handle, findNodesInfo);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $registerObjectExplorerNodeProvider(providerId: string, supportedProviderId: string, group: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._objectExplorerService.registerNodeProvider(<azdata.ObjectExplorerNodeProvider>{
|
||||
supportedProviderId: supportedProviderId,
|
||||
providerId: providerId,
|
||||
group: group,
|
||||
expandNode(nodeInfo: azdata.ExpandNodeInfo): Thenable<boolean> {
|
||||
return self._proxy.$expandObjectExplorerNode(handle, nodeInfo);
|
||||
},
|
||||
refreshNode(nodeInfo: azdata.ExpandNodeInfo): Thenable<boolean> {
|
||||
return self._proxy.$refreshObjectExplorerNode(handle, nodeInfo);
|
||||
},
|
||||
findNodes(findNodesInfo: azdata.FindNodesInfo): Thenable<azdata.ObjectExplorerFindNodesResponse> {
|
||||
return self._proxy.$findNodes(handle, findNodesInfo);
|
||||
},
|
||||
handleSessionOpen(session: azdata.ObjectExplorerSession): Thenable<boolean> {
|
||||
return self._proxy.$createObjectExplorerNodeProviderSession(handle, session);
|
||||
},
|
||||
handleSessionClose(closeSessionInfo: azdata.ObjectExplorerCloseSessionInfo): void {
|
||||
return self._proxy.$handleSessionClose(handle, closeSessionInfo);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $registerIconProvider(providerId: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._connectionManagementService.registerIconProvider(providerId, <azdata.IconProvider>{
|
||||
getConnectionIconId(connection: azdata.IConnectionProfile, serverInfo: azdata.ServerInfo): Thenable<string> {
|
||||
return self._proxy.$getConnectionIconId(handle, connection, serverInfo);
|
||||
}
|
||||
});
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $registerTaskServicesProvider(providerId: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._taskService.registerProvider(providerId, <azdata.TaskServicesProvider>{
|
||||
getAllTasks(listTasksParams: azdata.ListTasksParams): Thenable<azdata.ListTasksResponse> {
|
||||
return self._proxy.$getAllTasks(handle, listTasksParams);
|
||||
},
|
||||
cancelTask(cancelTaskParams: azdata.CancelTaskParams): Thenable<boolean> {
|
||||
return self._proxy.$cancelTask(handle, cancelTaskParams);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $registerScriptingProvider(providerId: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._scriptingService.registerProvider(providerId, <azdata.ScriptingProvider>{
|
||||
scriptAsOperation(connectionUri: string, operation: azdata.ScriptOperation, metadata: azdata.ObjectMetadata, paramDetails: azdata.ScriptingParamDetails): Thenable<azdata.ScriptingResult> {
|
||||
return self._proxy.$scriptAsOperation(handle, connectionUri, operation, metadata, paramDetails);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $registerFileBrowserProvider(providerId: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._fileBrowserService.registerProvider(providerId, <azdata.FileBrowserProvider>{
|
||||
openFileBrowser(ownerUri: string, expandPath: string, fileFilters: string[], changeFilter: boolean): Thenable<boolean> {
|
||||
return self._proxy.$openFileBrowser(handle, ownerUri, expandPath, fileFilters, changeFilter);
|
||||
},
|
||||
expandFolderNode(ownerUri: string, expandPath: string): Thenable<boolean> {
|
||||
return self._proxy.$expandFolderNode(handle, ownerUri, expandPath);
|
||||
},
|
||||
validateFilePaths(ownerUri: string, serviceType: string, selectedFiles: string[]): Thenable<boolean> {
|
||||
return self._proxy.$validateFilePaths(handle, ownerUri, serviceType, selectedFiles);
|
||||
},
|
||||
closeFileBrowser(ownerUri: string): Thenable<azdata.FileBrowserCloseResponse> {
|
||||
return self._proxy.$closeFileBrowser(handle, ownerUri);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $registerProfilerProvider(providerId: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._profilerService.registerProvider(providerId, <azdata.ProfilerProvider>{
|
||||
createSession(sessionId: string, createStatement: string, template: azdata.ProfilerSessionTemplate): Thenable<boolean> {
|
||||
return self._proxy.$createSession(handle, sessionId, createStatement, template);
|
||||
},
|
||||
startSession(sessionId: string, sessionName: string): Thenable<boolean> {
|
||||
return self._proxy.$startSession(handle, sessionId, sessionName);
|
||||
},
|
||||
stopSession(sessionId: string): Thenable<boolean> {
|
||||
return self._proxy.$stopSession(handle, sessionId);
|
||||
},
|
||||
pauseSession(sessionId: string): Thenable<boolean> {
|
||||
return self._proxy.$pauseSession(handle, sessionId);
|
||||
},
|
||||
getXEventSessions(sessionId: string): Thenable<string[]> {
|
||||
return self._proxy.$getXEventSessions(handle, sessionId);
|
||||
},
|
||||
connectSession(sessionId: string): Thenable<boolean> {
|
||||
return Promise.resolve(true);
|
||||
},
|
||||
disconnectSession(sessionId: string): Thenable<boolean> {
|
||||
return self._proxy.$disconnectSession(handle, sessionId);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $registerAdminServicesProvider(providerId: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._adminService.registerProvider(providerId, <azdata.AdminServicesProvider>{
|
||||
createDatabase(connectionUri: string, database: azdata.DatabaseInfo): Thenable<azdata.CreateDatabaseResponse> {
|
||||
return self._proxy.$createDatabase(handle, connectionUri, database);
|
||||
},
|
||||
getDefaultDatabaseInfo(connectionUri: string): Thenable<azdata.DatabaseInfo> {
|
||||
return self._proxy.$getDefaultDatabaseInfo(handle, connectionUri);
|
||||
},
|
||||
getDatabaseInfo(connectionUri: string): Thenable<azdata.DatabaseInfo> {
|
||||
return self._proxy.$getDatabaseInfo(handle, connectionUri);
|
||||
},
|
||||
createLogin(connectionUri: string, login: azdata.LoginInfo): Thenable<azdata.CreateLoginResponse> {
|
||||
return self._proxy.$createLogin(handle, connectionUri, login);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $registerAgentServicesProvider(providerId: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._jobManagementService.registerProvider(providerId, <azdata.AgentServicesProvider>{
|
||||
providerId: providerId,
|
||||
getJobs(connectionUri: string): Thenable<azdata.AgentJobsResult> {
|
||||
return self._proxy.$getJobs(handle, connectionUri);
|
||||
},
|
||||
getJobHistory(connectionUri: string, jobID: string, jobName: string): Thenable<azdata.AgentJobHistoryResult> {
|
||||
return self._proxy.$getJobHistory(handle, connectionUri, jobID, jobName);
|
||||
},
|
||||
jobAction(connectionUri: string, jobName: string, action: string): Thenable<azdata.ResultStatus> {
|
||||
return self._proxy.$jobAction(handle, connectionUri, jobName, action);
|
||||
},
|
||||
deleteJob(connectionUri: string, jobInfo: azdata.AgentJobInfo): Thenable<azdata.ResultStatus> {
|
||||
return self._proxy.$deleteJob(handle, connectionUri, jobInfo);
|
||||
},
|
||||
deleteJobStep(connectionUri: string, stepInfo: azdata.AgentJobStepInfo): Thenable<azdata.ResultStatus> {
|
||||
return self._proxy.$deleteJobStep(handle, connectionUri, stepInfo);
|
||||
},
|
||||
getAlerts(connectionUri: string): Thenable<azdata.AgentAlertsResult> {
|
||||
return self._proxy.$getAlerts(handle, connectionUri);
|
||||
},
|
||||
deleteAlert(connectionUri: string, alertInfo: azdata.AgentAlertInfo): Thenable<azdata.ResultStatus> {
|
||||
return self._proxy.$deleteAlert(handle, connectionUri, alertInfo);
|
||||
},
|
||||
getOperators(connectionUri: string): Thenable<azdata.AgentOperatorsResult> {
|
||||
return self._proxy.$getOperators(handle, connectionUri);
|
||||
},
|
||||
deleteOperator(connectionUri: string, operatorInfo: azdata.AgentOperatorInfo): Thenable<azdata.ResultStatus> {
|
||||
return self._proxy.$deleteOperator(handle, connectionUri, operatorInfo);
|
||||
},
|
||||
getProxies(connectionUri: string): Thenable<azdata.AgentProxiesResult> {
|
||||
return self._proxy.$getProxies(handle, connectionUri);
|
||||
},
|
||||
deleteProxy(connectionUri: string, proxyInfo: azdata.AgentProxyInfo): Thenable<azdata.ResultStatus> {
|
||||
return self._proxy.$deleteProxy(handle, connectionUri, proxyInfo);
|
||||
},
|
||||
getCredentials(connectionUri: string): Thenable<azdata.GetCredentialsResult> {
|
||||
return self._proxy.$getCredentials(handle, connectionUri);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $registerCapabilitiesServiceProvider(providerId: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._capabilitiesService.registerProvider(<azdata.CapabilitiesProvider>{
|
||||
getServerCapabilities(client: azdata.DataProtocolClientCapabilities): Thenable<azdata.DataProtocolServerCapabilities> {
|
||||
return self._proxy.$getServerCapabilities(handle, client);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $registerDacFxServicesProvider(providerId: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._dacFxService.registerProvider(providerId, <azdata.DacFxServicesProvider>{
|
||||
exportBacpac(databaseName: string, packageFilePath: string, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.DacFxResult> {
|
||||
return self._proxy.$exportBacpac(handle, databaseName, packageFilePath, ownerUri, taskExecutionMode);
|
||||
},
|
||||
importBacpac(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.DacFxResult> {
|
||||
return self._proxy.$importBacpac(handle, packageFilePath, databaseName, ownerUri, taskExecutionMode);
|
||||
},
|
||||
extractDacpac(databaseName: string, packageFilePath: string, applicationName: string, applicationVersion: string, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.DacFxResult> {
|
||||
return self._proxy.$extractDacpac(handle, databaseName, packageFilePath, applicationName, applicationVersion, ownerUri, taskExecutionMode);
|
||||
},
|
||||
deployDacpac(packageFilePath: string, databaseName: string, upgradeExisting: boolean, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.DacFxResult> {
|
||||
return self._proxy.$deployDacpac(handle, packageFilePath, databaseName, upgradeExisting, ownerUri, taskExecutionMode);
|
||||
},
|
||||
generateDeployScript(packageFilePath: string, databaseName: string, scriptFilePath: string, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.DacFxResult> {
|
||||
return self._proxy.$generateDeployScript(handle, packageFilePath, databaseName, scriptFilePath, ownerUri, taskExecutionMode);
|
||||
},
|
||||
generateDeployPlan(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.GenerateDeployPlanResult> {
|
||||
return self._proxy.$generateDeployPlan(handle, packageFilePath, databaseName, ownerUri, taskExecutionMode);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $registerSchemaCompareServicesProvider(providerId: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._schemaCompareService.registerProvider(providerId, <azdata.SchemaCompareServicesProvider>{
|
||||
schemaCompare(sourceEndpointInfo: azdata.SchemaCompareEndpointInfo, targetEndpointInfo: azdata.SchemaCompareEndpointInfo, taskExecutionMode: azdata.TaskExecutionMode, schemaComapareOptions: azdata.DeploymentOptions): Thenable<azdata.SchemaCompareResult> {
|
||||
return self._proxy.$schemaCompare(handle, sourceEndpointInfo, targetEndpointInfo, taskExecutionMode, schemaComapareOptions);
|
||||
},
|
||||
schemaCompareGenerateScript(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus> {
|
||||
return self._proxy.$schemaCompareGenerateScript(handle, operationId, targetServerName, targetDatabaseName, taskExecutionMode);
|
||||
},
|
||||
schemaComparePublishChanges(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus> {
|
||||
return self._proxy.$schemaComparePublishChanges(handle, operationId, targetServerName, targetDatabaseName, taskExecutionMode);
|
||||
},
|
||||
schemaCompareGetDefaultOptions(): Thenable<azdata.SchemaCompareOptionsResult> {
|
||||
return self._proxy.$schemaCompareGetDefaultOptions(handle);
|
||||
},
|
||||
schemaCompareIncludeExcludeNode(operationId: string, diffEntry: azdata.DiffEntry, includeRequest: boolean, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus> {
|
||||
return self._proxy.$schemaCompareIncludeExcludeNode(handle, operationId, diffEntry, includeRequest, taskExecutionMode);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Connection Management handlers
|
||||
public $onConnectionComplete(handle: number, connectionInfoSummary: azdata.ConnectionInfoSummary): void {
|
||||
this._connectionManagementService.onConnectionComplete(handle, connectionInfoSummary);
|
||||
}
|
||||
|
||||
public $onIntelliSenseCacheComplete(handle: number, connectionUri: string): void {
|
||||
this._connectionManagementService.onIntelliSenseCacheComplete(handle, connectionUri);
|
||||
}
|
||||
|
||||
public $onConnectionChangeNotification(handle: number, changedConnInfo: azdata.ChangedConnectionInfo): void {
|
||||
this._connectionManagementService.onConnectionChangedNotification(handle, changedConnInfo);
|
||||
}
|
||||
|
||||
// Query Management handlers
|
||||
public $onQueryComplete(handle: number, result: azdata.QueryExecuteCompleteNotificationResult): void {
|
||||
this._queryManagementService.onQueryComplete(result);
|
||||
}
|
||||
public $onBatchStart(handle: number, batchInfo: azdata.QueryExecuteBatchNotificationParams): void {
|
||||
this._queryManagementService.onBatchStart(batchInfo);
|
||||
}
|
||||
public $onBatchComplete(handle: number, batchInfo: azdata.QueryExecuteBatchNotificationParams): void {
|
||||
this._queryManagementService.onBatchComplete(batchInfo);
|
||||
}
|
||||
public $onResultSetAvailable(handle: number, resultSetInfo: azdata.QueryExecuteResultSetNotificationParams): void {
|
||||
this._queryManagementService.onResultSetAvailable(resultSetInfo);
|
||||
}
|
||||
public $onResultSetUpdated(handle: number, resultSetInfo: azdata.QueryExecuteResultSetNotificationParams): void {
|
||||
this._queryManagementService.onResultSetUpdated(resultSetInfo);
|
||||
}
|
||||
public $onQueryMessage(handle: number, message: azdata.QueryExecuteMessageParams): void {
|
||||
this._queryManagementService.onMessage(message);
|
||||
}
|
||||
public $onEditSessionReady(handle: number, ownerUri: string, success: boolean, message: string): void {
|
||||
this._queryManagementService.onEditSessionReady(ownerUri, success, message);
|
||||
}
|
||||
|
||||
// Script Handlers
|
||||
public $onScriptingComplete(handle: number, scriptingCompleteResult: azdata.ScriptingCompleteResult): void {
|
||||
this._scriptingService.onScriptingComplete(handle, scriptingCompleteResult);
|
||||
}
|
||||
|
||||
//OE handlers
|
||||
public $onObjectExplorerSessionCreated(handle: number, sessionResponse: azdata.ObjectExplorerSession): void {
|
||||
this._objectExplorerService.onSessionCreated(handle, sessionResponse);
|
||||
}
|
||||
|
||||
public $onObjectExplorerSessionDisconnected(handle: number, sessionResponse: azdata.ObjectExplorerSession): void {
|
||||
this._objectExplorerService.onSessionDisconnected(handle, sessionResponse);
|
||||
}
|
||||
|
||||
public $onObjectExplorerNodeExpanded(providerId: string, expandResponse: azdata.ObjectExplorerExpandInfo): void {
|
||||
let expandInfo: NodeExpandInfoWithProviderId = Object.assign({ providerId: providerId }, expandResponse);
|
||||
this._objectExplorerService.onNodeExpanded(expandInfo);
|
||||
}
|
||||
|
||||
//Tasks handlers
|
||||
public $onTaskCreated(handle: number, taskInfo: azdata.TaskInfo): void {
|
||||
this._taskService.onNewTaskCreated(handle, taskInfo);
|
||||
}
|
||||
|
||||
public $onTaskStatusChanged(handle: number, taskProgressInfo: azdata.TaskProgressInfo): void {
|
||||
this._taskService.onTaskStatusChanged(handle, taskProgressInfo);
|
||||
}
|
||||
|
||||
//File browser handlers
|
||||
public $onFileBrowserOpened(handle: number, response: azdata.FileBrowserOpenedParams): void {
|
||||
this._fileBrowserService.onFileBrowserOpened(handle, response);
|
||||
}
|
||||
|
||||
public $onFolderNodeExpanded(handle: number, response: azdata.FileBrowserExpandedParams): void {
|
||||
this._fileBrowserService.onFolderNodeExpanded(handle, response);
|
||||
}
|
||||
|
||||
public $onFilePathsValidated(handle: number, response: azdata.FileBrowserValidatedParams): void {
|
||||
this._fileBrowserService.onFilePathsValidated(handle, response);
|
||||
}
|
||||
|
||||
// Profiler handlers
|
||||
public $onSessionEventsAvailable(handle: number, response: azdata.ProfilerSessionEvents): void {
|
||||
this._profilerService.onMoreRows(response);
|
||||
}
|
||||
|
||||
public $onSessionStopped(handle: number, response: azdata.ProfilerSessionStoppedParams): void {
|
||||
this._profilerService.onSessionStopped(response);
|
||||
}
|
||||
|
||||
public $onProfilerSessionCreated(handle: number, response: azdata.ProfilerSessionCreatedParams): void {
|
||||
this._profilerService.onProfilerSessionCreated(response);
|
||||
}
|
||||
|
||||
// SQL Server Agent handlers
|
||||
public $onJobDataUpdated(handle: Number): void {
|
||||
this._jobManagementService.fireOnDidChange();
|
||||
}
|
||||
|
||||
public $unregisterProvider(handle: number): Promise<any> {
|
||||
let capabilitiesRegistration = this._capabilitiesRegistrations[handle];
|
||||
if (capabilitiesRegistration) {
|
||||
capabilitiesRegistration.dispose();
|
||||
delete this._capabilitiesRegistrations[handle];
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { SqlMainContext, MainThreadExtensionManagementShape } from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IExtensionManagementService, IExtensionIdentifier } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
@extHostNamedCustomer(SqlMainContext.MainThreadExtensionManagement)
|
||||
export class MainThreadExtensionManagement implements MainThreadExtensionManagementShape {
|
||||
|
||||
private _toDispose: IDisposable[];
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@IExtensionManagementService private _extensionService: IExtensionManagementService
|
||||
) {
|
||||
this._toDispose = [];
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._toDispose = dispose(this._toDispose);
|
||||
}
|
||||
|
||||
public $install(vsixPath: string): Thenable<string> {
|
||||
return this._extensionService.install(URI.parse(vsixPath)).then((value: IExtensionIdentifier) => { return undefined; }, (reason: any) => { return reason ? reason.toString() : undefined; });
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { MainThreadModelViewShape, SqlMainContext, ExtHostModelViewShape, SqlExtHostContext } from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
|
||||
import { IModelViewService } from 'sql/platform/modelComponents/common/modelViewService';
|
||||
import { IItemConfig, IComponentShape } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||
import { IModelView } from 'sql/platform/model/common/modelViewService';
|
||||
|
||||
|
||||
@extHostNamedCustomer(SqlMainContext.MainThreadModelView)
|
||||
export class MainThreadModelView extends Disposable implements MainThreadModelViewShape {
|
||||
|
||||
private static _handlePool = 0;
|
||||
private readonly _proxy: ExtHostModelViewShape;
|
||||
private readonly _dialogs = new Map<number, IModelView>();
|
||||
private knownWidgets = new Array<string>();
|
||||
|
||||
constructor(
|
||||
private _context: IExtHostContext,
|
||||
@IModelViewService viewService: IModelViewService
|
||||
) {
|
||||
super();
|
||||
this._proxy = _context.getProxy(SqlExtHostContext.ExtHostModelView);
|
||||
viewService.onRegisteredModelView(view => {
|
||||
if (this.knownWidgets.includes(view.id)) {
|
||||
let handle = MainThreadModelView._handlePool++;
|
||||
this._dialogs.set(handle, view);
|
||||
this._proxy.$registerWidget(handle, view.id, view.connection, view.serverInfo);
|
||||
view.onDestroy(() => this._proxy.$onClosed(handle));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$registerProvider(id: string) {
|
||||
this.knownWidgets.push(id);
|
||||
}
|
||||
|
||||
$initializeModel(handle: number, rootComponent: IComponentShape): Thenable<void> {
|
||||
return this.execModelViewAction(handle, (modelView) => {
|
||||
modelView.initializeModel(rootComponent, (componentId) => this.runCustomValidations(handle, componentId));
|
||||
});
|
||||
}
|
||||
|
||||
$clearContainer(handle: number, componentId: string): Thenable<void> {
|
||||
return this.execModelViewAction(handle, (modelView) => modelView.clearContainer(componentId));
|
||||
}
|
||||
|
||||
$addToContainer(handle: number, containerId: string, item: IItemConfig, index?: number): Thenable<void> {
|
||||
return this.execModelViewAction(handle,
|
||||
(modelView) => modelView.addToContainer(containerId, item, index));
|
||||
}
|
||||
|
||||
$removeFromContainer(handle: number, containerId: string, item: IItemConfig): Thenable<void> {
|
||||
return this.execModelViewAction(handle,
|
||||
(modelView) => modelView.removeFromContainer(containerId, item));
|
||||
}
|
||||
|
||||
$setLayout(handle: number, componentId: string, layout: any): Thenable<void> {
|
||||
return this.execModelViewAction(handle, (modelView) => modelView.setLayout(componentId, layout));
|
||||
}
|
||||
|
||||
private onEvent(handle: number, componentId: string, eventArgs: any) {
|
||||
this._proxy.$handleEvent(handle, componentId, eventArgs);
|
||||
}
|
||||
|
||||
$registerEvent(handle: number, componentId: string): Thenable<void> {
|
||||
let properties: { [key: string]: any; } = { eventName: this.onEvent };
|
||||
return this.execModelViewAction(handle, (modelView) => {
|
||||
this._register(modelView.onEvent(e => {
|
||||
if (e.componentId && e.componentId === componentId) {
|
||||
this.onEvent(handle, componentId, e);
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
$setDataProvider(handle: number, componentId: string): Thenable<void> {
|
||||
return this.execModelViewAction(handle, (modelView) => modelView.setDataProvider(handle, componentId, this._context));
|
||||
}
|
||||
|
||||
$refreshDataProvider(handle: number, componentId: string, item?: any): Thenable<void> {
|
||||
return this.execModelViewAction(handle, (modelView) => modelView.refreshDataProvider(componentId, item));
|
||||
}
|
||||
|
||||
$setProperties(handle: number, componentId: string, properties: { [key: string]: any; }): Thenable<void> {
|
||||
return this.execModelViewAction(handle, (modelView) => modelView.setProperties(componentId, properties));
|
||||
}
|
||||
|
||||
$validate(handle: number, componentId: string): Thenable<boolean> {
|
||||
return new Promise(resolve => this.execModelViewAction(handle, (modelView) => resolve(modelView.validate(componentId))));
|
||||
}
|
||||
|
||||
private runCustomValidations(handle: number, componentId: string): Thenable<boolean> {
|
||||
return this._proxy.$runCustomValidations(handle, componentId);
|
||||
}
|
||||
|
||||
private execModelViewAction<T>(handle: number, action: (m: IModelView) => T): Thenable<T> {
|
||||
let modelView: IModelView = this._dialogs.get(handle);
|
||||
let result = action(modelView);
|
||||
return Promise.resolve(result);
|
||||
}
|
||||
}
|
||||
@@ -1,296 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
import { MainThreadModelViewDialogShape, SqlMainContext, ExtHostModelViewDialogShape, SqlExtHostContext } from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||
import { Dialog, DialogTab, DialogButton, WizardPage, Wizard } from 'sql/platform/dialog/dialogTypes';
|
||||
import { CustomDialogService } from 'sql/platform/dialog/customDialogService';
|
||||
import { IModelViewDialogDetails, IModelViewTabDetails, IModelViewButtonDetails, IModelViewWizardPageDetails, IModelViewWizardDetails } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||
import { ModelViewInput, ModelViewInputModel, ModeViewSaveHandler } from 'sql/workbench/electron-browser/modelComponents/modelViewInput';
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as azdata from 'azdata';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
||||
@extHostNamedCustomer(SqlMainContext.MainThreadModelViewDialog)
|
||||
export class MainThreadModelViewDialog implements MainThreadModelViewDialogShape {
|
||||
private readonly _proxy: ExtHostModelViewDialogShape;
|
||||
private readonly _dialogs = new Map<number, Dialog>();
|
||||
private readonly _tabs = new Map<number, DialogTab>();
|
||||
private readonly _buttons = new Map<number, DialogButton>();
|
||||
private readonly _wizardPages = new Map<number, WizardPage>();
|
||||
private readonly _wizardPageHandles = new Map<WizardPage, number>();
|
||||
private readonly _wizards = new Map<number, Wizard>();
|
||||
private readonly _editorInputModels = new Map<number, ModelViewInputModel>();
|
||||
private _dialogService: CustomDialogService;
|
||||
|
||||
constructor(
|
||||
context: IExtHostContext,
|
||||
@IInstantiationService private _instatiationService: IInstantiationService,
|
||||
@IEditorService private _editorService: IEditorService,
|
||||
@ITelemetryService private _telemetryService: ITelemetryService
|
||||
) {
|
||||
this._proxy = context.getProxy(SqlExtHostContext.ExtHostModelViewDialog);
|
||||
this._dialogService = new CustomDialogService(_instatiationService);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
public $openEditor(handle: number, modelViewId: string, title: string, options?: azdata.ModelViewEditorOptions, position?: vscode.ViewColumn): Thenable<void> {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
let saveHandler: ModeViewSaveHandler = options && options.supportsSave ? (h) => this.handleSave(h) : undefined;
|
||||
let model = new ModelViewInputModel(modelViewId, handle, saveHandler);
|
||||
let input = this._instatiationService.createInstance(ModelViewInput, title, model, options);
|
||||
let editorOptions = {
|
||||
preserveFocus: true,
|
||||
pinned: true
|
||||
};
|
||||
|
||||
this._editorService.openEditor(input, editorOptions, position as any).then((editor) => {
|
||||
this._editorInputModels.set(handle, model);
|
||||
resolve();
|
||||
}, error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private handleSave(handle: number): Thenable<boolean> {
|
||||
return this._proxy.$handleSave(handle);
|
||||
}
|
||||
|
||||
public $openDialog(handle: number, dialogName?: string): Thenable<void> {
|
||||
let dialog = this.getDialog(handle);
|
||||
this._dialogService.showDialog(dialog, dialogName, { hasBackButton: false, isWide: dialog.isWide, hasErrors: true });
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public $closeDialog(handle: number): Thenable<void> {
|
||||
let dialog = this.getDialog(handle);
|
||||
this._dialogService.closeDialog(dialog);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public $setDialogDetails(handle: number, details: IModelViewDialogDetails): Thenable<void> {
|
||||
let dialog = this._dialogs.get(handle);
|
||||
if (!dialog) {
|
||||
dialog = new Dialog(details.title);
|
||||
let okButton = this.getButton(details.okButton);
|
||||
let cancelButton = this.getButton(details.cancelButton);
|
||||
dialog.okButton = okButton;
|
||||
dialog.cancelButton = cancelButton;
|
||||
dialog.onValidityChanged(valid => this._proxy.$onPanelValidityChanged(handle, valid));
|
||||
dialog.registerCloseValidator(() => this.validateDialogClose(handle));
|
||||
this._dialogs.set(handle, dialog);
|
||||
}
|
||||
|
||||
dialog.title = details.title;
|
||||
dialog.isWide = details.isWide;
|
||||
if (details.content && typeof details.content !== 'string') {
|
||||
dialog.content = details.content.map(tabHandle => this.getTab(tabHandle));
|
||||
} else {
|
||||
dialog.content = details.content as string;
|
||||
}
|
||||
|
||||
if (details.customButtons) {
|
||||
dialog.customButtons = details.customButtons.map(buttonHandle => this.getButton(buttonHandle));
|
||||
}
|
||||
|
||||
dialog.message = details.message;
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public $setTabDetails(handle: number, details: IModelViewTabDetails): Thenable<void> {
|
||||
let tab = this._tabs.get(handle);
|
||||
if (!tab) {
|
||||
tab = new DialogTab(details.title);
|
||||
tab.onValidityChanged(valid => this._proxy.$onPanelValidityChanged(handle, valid));
|
||||
this._tabs.set(handle, tab);
|
||||
}
|
||||
|
||||
tab.title = details.title;
|
||||
tab.content = details.content;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public $setButtonDetails(handle: number, details: IModelViewButtonDetails): Thenable<void> {
|
||||
let button = this._buttons.get(handle);
|
||||
if (!button) {
|
||||
button = new DialogButton(details.label, details.enabled);
|
||||
button.hidden = details.hidden;
|
||||
button.onClick(() => this.onButtonClick(handle));
|
||||
this._buttons.set(handle, button);
|
||||
} else {
|
||||
button.label = details.label;
|
||||
button.enabled = details.enabled;
|
||||
button.hidden = details.hidden;
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public $setWizardPageDetails(handle: number, details: IModelViewWizardPageDetails): Thenable<void> {
|
||||
let page = this._wizardPages.get(handle);
|
||||
if (!page) {
|
||||
page = new WizardPage(details.title, details.content);
|
||||
page.onValidityChanged(valid => this._proxy.$onPanelValidityChanged(handle, valid));
|
||||
this._wizardPages.set(handle, page);
|
||||
this._wizardPageHandles.set(page, handle);
|
||||
}
|
||||
|
||||
page.title = details.title;
|
||||
page.content = details.content;
|
||||
page.enabled = details.enabled;
|
||||
page.description = details.description;
|
||||
if (details.customButtons !== undefined) {
|
||||
page.customButtons = details.customButtons.map(buttonHandle => this.getButton(buttonHandle));
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public $setWizardDetails(handle: number, details: IModelViewWizardDetails): Thenable<void> {
|
||||
let wizard = this._wizards.get(handle);
|
||||
if (!wizard) {
|
||||
wizard = new Wizard(details.title);
|
||||
wizard.backButton = this.getButton(details.backButton);
|
||||
wizard.cancelButton = this.getButton(details.cancelButton);
|
||||
wizard.generateScriptButton = this.getButton(details.generateScriptButton);
|
||||
wizard.doneButton = this.getButton(details.doneButton);
|
||||
wizard.nextButton = this.getButton(details.nextButton);
|
||||
wizard.onPageChanged(info => this._proxy.$onWizardPageChanged(handle, info));
|
||||
wizard.onPageAdded(() => this.handleWizardPageAddedOrRemoved(handle));
|
||||
wizard.onPageRemoved(() => this.handleWizardPageAddedOrRemoved(handle));
|
||||
wizard.registerNavigationValidator(info => this.validateNavigation(handle, info));
|
||||
this._wizards.set(handle, wizard);
|
||||
}
|
||||
|
||||
wizard.title = details.title;
|
||||
wizard.displayPageTitles = details.displayPageTitles;
|
||||
wizard.pages = details.pages.map(handle => this.getWizardPage(handle));
|
||||
if (details.currentPage !== undefined) {
|
||||
wizard.setCurrentPage(details.currentPage);
|
||||
}
|
||||
if (details.customButtons !== undefined) {
|
||||
wizard.customButtons = details.customButtons.map(buttonHandle => this.getButton(buttonHandle));
|
||||
}
|
||||
wizard.message = details.message;
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public $addWizardPage(wizardHandle: number, pageHandle: number, pageIndex?: number): Thenable<void> {
|
||||
if (pageIndex === null) {
|
||||
pageIndex = undefined;
|
||||
}
|
||||
let wizard = this.getWizard(wizardHandle);
|
||||
let page = this.getWizardPage(pageHandle);
|
||||
wizard.addPage(page, pageIndex);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public $removeWizardPage(wizardHandle: number, pageIndex: number): Thenable<void> {
|
||||
let wizard = this.getWizard(wizardHandle);
|
||||
wizard.removePage(pageIndex);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public $setWizardPage(wizardHandle: number, pageIndex: number): Thenable<void> {
|
||||
let wizard = this.getWizard(wizardHandle);
|
||||
wizard.setCurrentPage(pageIndex);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public $openWizard(handle: number): Thenable<void> {
|
||||
let wizard = this.getWizard(handle);
|
||||
this._dialogService.showWizard(wizard);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public $closeWizard(handle: number): Thenable<void> {
|
||||
let wizard = this.getWizard(handle);
|
||||
this._dialogService.closeWizard(wizard);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
$setDirty(handle: number, isDirty: boolean): void {
|
||||
let model = this.getEditor(handle);
|
||||
if (model) {
|
||||
model.setDirty(isDirty);
|
||||
}
|
||||
}
|
||||
|
||||
private getEditor(handle: number): ModelViewInputModel {
|
||||
let model = this._editorInputModels.get(handle);
|
||||
if (!model) {
|
||||
throw new Error('No editor matching the given handle');
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
private getDialog(handle: number): Dialog {
|
||||
let dialog = this._dialogs.get(handle);
|
||||
if (!dialog) {
|
||||
throw new Error('No dialog matching the given handle');
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
||||
private getTab(handle: number): DialogTab {
|
||||
let tab = this._tabs.get(handle);
|
||||
if (!tab) {
|
||||
throw new Error('No tab matching the given handle');
|
||||
}
|
||||
return tab;
|
||||
}
|
||||
|
||||
private getButton(handle: number): DialogButton {
|
||||
let button = this._buttons.get(handle);
|
||||
if (!button) {
|
||||
throw new Error('No button matching the given handle');
|
||||
}
|
||||
return button;
|
||||
}
|
||||
|
||||
private onButtonClick(handle: number): void {
|
||||
this._proxy.$onButtonClick(handle);
|
||||
}
|
||||
|
||||
private getWizardPage(handle: number): WizardPage {
|
||||
let page = this._wizardPages.get(handle);
|
||||
if (!page) {
|
||||
throw new Error('No page matching the given handle');
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
private getWizard(handle: number): Wizard {
|
||||
let wizard = this._wizards.get(handle);
|
||||
if (!wizard) {
|
||||
throw new Error('No wizard matching the given handle');
|
||||
}
|
||||
return wizard;
|
||||
}
|
||||
|
||||
private handleWizardPageAddedOrRemoved(handle: number): void {
|
||||
let wizard = this._wizards.get(handle);
|
||||
this._proxy.$updateWizardPageInfo(handle, wizard.pages.map(page => this._wizardPageHandles.get(page)), wizard.currentPage);
|
||||
}
|
||||
|
||||
private validateNavigation(handle: number, info: azdata.window.WizardPageChangeInfo): Thenable<boolean> {
|
||||
return this._proxy.$validateNavigation(handle, info);
|
||||
}
|
||||
|
||||
private validateDialogClose(handle: number): Thenable<boolean> {
|
||||
return this._proxy.$validateDialogClose(handle);
|
||||
}
|
||||
}
|
||||
@@ -1,478 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import { SqlExtHostContext, SqlMainContext, ExtHostNotebookShape, MainThreadNotebookShape } from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
import { INotebookService, INotebookProvider, INotebookManager } from 'sql/workbench/services/notebook/common/notebookService';
|
||||
import { INotebookManagerDetails, INotebookSessionDetails, INotebookKernelDetails, FutureMessageType, INotebookFutureDetails, INotebookFutureDone } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||
import { LocalContentManager } from 'sql/workbench/services/notebook/node/localContentManager';
|
||||
import { Deferred } from 'sql/base/common/promise';
|
||||
import { FutureInternal } from 'sql/workbench/parts/notebook/models/modelInterfaces';
|
||||
|
||||
@extHostNamedCustomer(SqlMainContext.MainThreadNotebook)
|
||||
export class MainThreadNotebook extends Disposable implements MainThreadNotebookShape {
|
||||
|
||||
private _proxy: ExtHostNotebookShape;
|
||||
private _providers = new Map<number, NotebookProviderWrapper>();
|
||||
private _futures = new Map<number, FutureWrapper>();
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@INotebookService private notebookService: INotebookService
|
||||
) {
|
||||
super();
|
||||
if (extHostContext) {
|
||||
this._proxy = extHostContext.getProxy(SqlExtHostContext.ExtHostNotebook);
|
||||
}
|
||||
}
|
||||
|
||||
public addFuture(futureId: number, future: FutureWrapper): void {
|
||||
this._futures.set(futureId, future);
|
||||
}
|
||||
|
||||
public disposeFuture(futureId: number): void {
|
||||
this._futures.delete(futureId);
|
||||
}
|
||||
|
||||
//#region Extension host callable methods
|
||||
public $registerNotebookProvider(providerId: string, handle: number): void {
|
||||
let proxy: Proxies = {
|
||||
main: this,
|
||||
ext: this._proxy
|
||||
};
|
||||
let notebookProvider = new NotebookProviderWrapper(proxy, providerId, handle);
|
||||
this._providers.set(handle, notebookProvider);
|
||||
this.notebookService.registerProvider(providerId, notebookProvider);
|
||||
}
|
||||
|
||||
public $unregisterNotebookProvider(handle: number): void {
|
||||
let registration = this._providers.get(handle);
|
||||
if (registration) {
|
||||
this.notebookService.unregisterProvider(registration.providerId);
|
||||
registration.dispose();
|
||||
this._providers.delete(handle);
|
||||
}
|
||||
}
|
||||
|
||||
public $onFutureMessage(futureId: number, type: FutureMessageType, payload: azdata.nb.IMessage): void {
|
||||
let future = this._futures.get(futureId);
|
||||
if (future) {
|
||||
future.onMessage(type, payload);
|
||||
}
|
||||
}
|
||||
|
||||
public $onFutureDone(futureId: number, done: INotebookFutureDone): void {
|
||||
let future = this._futures.get(futureId);
|
||||
if (future) {
|
||||
future.onDone(done);
|
||||
}
|
||||
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
|
||||
interface Proxies {
|
||||
main: MainThreadNotebook;
|
||||
ext: ExtHostNotebookShape;
|
||||
}
|
||||
|
||||
class NotebookProviderWrapper extends Disposable implements INotebookProvider {
|
||||
private _notebookUriToManagerMap = new Map<string, NotebookManagerWrapper>();
|
||||
|
||||
constructor(private _proxy: Proxies, public readonly providerId, public readonly providerHandle: number) {
|
||||
super();
|
||||
}
|
||||
|
||||
getNotebookManager(notebookUri: URI): Thenable<INotebookManager> {
|
||||
// TODO must call through to setup in the extension host
|
||||
return this.doGetNotebookManager(notebookUri);
|
||||
}
|
||||
|
||||
private async doGetNotebookManager(notebookUri: URI): Promise<INotebookManager> {
|
||||
let uriString = notebookUri.toString();
|
||||
let manager = this._notebookUriToManagerMap.get(uriString);
|
||||
if (!manager) {
|
||||
manager = new NotebookManagerWrapper(this._proxy, this.providerId, notebookUri);
|
||||
await manager.initialize(this.providerHandle);
|
||||
this._notebookUriToManagerMap.set(uriString, manager);
|
||||
}
|
||||
return manager;
|
||||
}
|
||||
|
||||
handleNotebookClosed(notebookUri: URI): void {
|
||||
this._notebookUriToManagerMap.delete(notebookUri.toString());
|
||||
this._proxy.ext.$handleNotebookClosed(notebookUri);
|
||||
}
|
||||
}
|
||||
|
||||
class NotebookManagerWrapper implements INotebookManager {
|
||||
private _sessionManager: azdata.nb.SessionManager;
|
||||
private _contentManager: azdata.nb.ContentManager;
|
||||
private _serverManager: azdata.nb.ServerManager;
|
||||
private managerDetails: INotebookManagerDetails;
|
||||
|
||||
constructor(private _proxy: Proxies,
|
||||
public readonly providerId,
|
||||
private notebookUri: URI
|
||||
) { }
|
||||
|
||||
public async initialize(providerHandle: number): Promise<NotebookManagerWrapper> {
|
||||
this.managerDetails = await this._proxy.ext.$getNotebookManager(providerHandle, this.notebookUri);
|
||||
let managerHandle = this.managerDetails.handle;
|
||||
this._contentManager = this.managerDetails.hasContentManager ? new ContentManagerWrapper(managerHandle, this._proxy) : new LocalContentManager();
|
||||
this._serverManager = this.managerDetails.hasServerManager ? new ServerManagerWrapper(managerHandle, this._proxy) : undefined;
|
||||
this._sessionManager = new SessionManagerWrapper(managerHandle, this._proxy);
|
||||
return this;
|
||||
}
|
||||
|
||||
public get sessionManager(): azdata.nb.SessionManager {
|
||||
return this._sessionManager;
|
||||
}
|
||||
public get contentManager(): azdata.nb.ContentManager {
|
||||
return this._contentManager;
|
||||
}
|
||||
public get serverManager(): azdata.nb.ServerManager {
|
||||
return this._serverManager;
|
||||
}
|
||||
|
||||
public get managerHandle(): number {
|
||||
return this.managerDetails.handle;
|
||||
}
|
||||
}
|
||||
|
||||
class ContentManagerWrapper implements azdata.nb.ContentManager {
|
||||
|
||||
constructor(private handle: number, private _proxy: Proxies) {
|
||||
}
|
||||
getNotebookContents(notebookUri: URI): Thenable<azdata.nb.INotebookContents> {
|
||||
return this._proxy.ext.$getNotebookContents(this.handle, notebookUri);
|
||||
}
|
||||
|
||||
save(path: URI, notebook: azdata.nb.INotebookContents): Thenable<azdata.nb.INotebookContents> {
|
||||
return this._proxy.ext.$save(this.handle, path, notebook);
|
||||
}
|
||||
}
|
||||
|
||||
class ServerManagerWrapper implements azdata.nb.ServerManager {
|
||||
private onServerStartedEmitter = new Emitter<void>();
|
||||
private _isStarted: boolean;
|
||||
constructor(private handle: number, private _proxy: Proxies) {
|
||||
this._isStarted = false;
|
||||
}
|
||||
|
||||
get isStarted(): boolean {
|
||||
return this._isStarted;
|
||||
}
|
||||
|
||||
get onServerStarted(): Event<void> {
|
||||
return this.onServerStartedEmitter.event;
|
||||
}
|
||||
|
||||
startServer(): Thenable<void> {
|
||||
return this.doStartServer();
|
||||
}
|
||||
|
||||
private async doStartServer(): Promise<void> {
|
||||
await this._proxy.ext.$doStartServer(this.handle);
|
||||
this._isStarted = true;
|
||||
this.onServerStartedEmitter.fire();
|
||||
}
|
||||
|
||||
stopServer(): Thenable<void> {
|
||||
return this.doStopServer();
|
||||
}
|
||||
|
||||
private async doStopServer(): Promise<void> {
|
||||
try {
|
||||
await this._proxy.ext.$doStopServer(this.handle);
|
||||
} finally {
|
||||
// Always consider this a stopping event, even if a failure occurred.
|
||||
this._isStarted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SessionManagerWrapper implements azdata.nb.SessionManager {
|
||||
private readyPromise: Promise<void>;
|
||||
private _isReady: boolean;
|
||||
private _specs: azdata.nb.IAllKernels;
|
||||
constructor(private managerHandle: number, private _proxy: Proxies) {
|
||||
this._isReady = false;
|
||||
this.readyPromise = this.initializeSessionManager();
|
||||
}
|
||||
|
||||
get isReady(): boolean {
|
||||
return this._isReady;
|
||||
}
|
||||
|
||||
get ready(): Thenable<void> {
|
||||
return this.readyPromise;
|
||||
}
|
||||
|
||||
get specs(): azdata.nb.IAllKernels {
|
||||
return this._specs;
|
||||
}
|
||||
|
||||
startNew(options: azdata.nb.ISessionOptions): Thenable<azdata.nb.ISession> {
|
||||
return this.doStartNew(options);
|
||||
}
|
||||
|
||||
private async doStartNew(options: azdata.nb.ISessionOptions): Promise<azdata.nb.ISession> {
|
||||
let sessionDetails = await this._proxy.ext.$startNewSession(this.managerHandle, options);
|
||||
return new SessionWrapper(this._proxy, sessionDetails);
|
||||
}
|
||||
|
||||
shutdown(id: string): Thenable<void> {
|
||||
return this._proxy.ext.$shutdownSession(this.managerHandle, id);
|
||||
}
|
||||
|
||||
private async initializeSessionManager(): Promise<void> {
|
||||
await this.refreshSpecs();
|
||||
this._isReady = true;
|
||||
}
|
||||
|
||||
private async refreshSpecs(): Promise<void> {
|
||||
let specs = await this._proxy.ext.$refreshSpecs(this.managerHandle);
|
||||
if (specs) {
|
||||
this._specs = specs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SessionWrapper implements azdata.nb.ISession {
|
||||
private _kernel: KernelWrapper;
|
||||
constructor(private _proxy: Proxies, private sessionDetails: INotebookSessionDetails) {
|
||||
if (sessionDetails && sessionDetails.kernelDetails) {
|
||||
this._kernel = new KernelWrapper(_proxy, sessionDetails.kernelDetails);
|
||||
}
|
||||
}
|
||||
|
||||
get canChangeKernels(): boolean {
|
||||
return this.sessionDetails.canChangeKernels;
|
||||
}
|
||||
|
||||
get id(): string {
|
||||
return this.sessionDetails.id;
|
||||
}
|
||||
|
||||
get path(): string {
|
||||
return this.sessionDetails.path;
|
||||
}
|
||||
|
||||
get name(): string {
|
||||
return this.sessionDetails.name;
|
||||
}
|
||||
|
||||
get type(): string {
|
||||
return this.sessionDetails.type;
|
||||
}
|
||||
|
||||
get status(): azdata.nb.KernelStatus {
|
||||
return this.sessionDetails.status as azdata.nb.KernelStatus;
|
||||
}
|
||||
|
||||
get kernel(): azdata.nb.IKernel {
|
||||
return this._kernel;
|
||||
}
|
||||
|
||||
changeKernel(kernelInfo: azdata.nb.IKernelSpec): Thenable<azdata.nb.IKernel> {
|
||||
return this.doChangeKernel(kernelInfo);
|
||||
}
|
||||
|
||||
configureKernel(kernelInfo: azdata.nb.IKernelSpec): Thenable<void> {
|
||||
return this.doConfigureKernel(kernelInfo);
|
||||
}
|
||||
|
||||
configureConnection(connection: azdata.IConnectionProfile): Thenable<void> {
|
||||
if (connection['capabilitiesService'] !== undefined) {
|
||||
connection['capabilitiesService'] = undefined;
|
||||
}
|
||||
return this.doConfigureConnection(connection);
|
||||
}
|
||||
|
||||
private async doChangeKernel(kernelInfo: azdata.nb.IKernelSpec): Promise<azdata.nb.IKernel> {
|
||||
let kernelDetails = await this._proxy.ext.$changeKernel(this.sessionDetails.sessionId, kernelInfo);
|
||||
this._kernel = new KernelWrapper(this._proxy, kernelDetails);
|
||||
return this._kernel;
|
||||
}
|
||||
|
||||
private async doConfigureKernel(kernelInfo: azdata.nb.IKernelSpec): Promise<void> {
|
||||
await this._proxy.ext.$configureKernel(this.sessionDetails.sessionId, kernelInfo);
|
||||
}
|
||||
|
||||
private async doConfigureConnection(connection: azdata.IConnectionProfile): Promise<void> {
|
||||
await this._proxy.ext.$configureConnection(this.sessionDetails.sessionId, connection);
|
||||
}
|
||||
}
|
||||
|
||||
class KernelWrapper implements azdata.nb.IKernel {
|
||||
private _isReady: boolean = false;
|
||||
private _ready = new Deferred<void>();
|
||||
private _info: azdata.nb.IInfoReply;
|
||||
constructor(private _proxy: Proxies, private kernelDetails: INotebookKernelDetails) {
|
||||
this.initialize(kernelDetails);
|
||||
}
|
||||
|
||||
private async initialize(kernelDetails: INotebookKernelDetails): Promise<void> {
|
||||
try {
|
||||
this._info = await this._proxy.ext.$getKernelReadyStatus(kernelDetails.kernelId);
|
||||
this._isReady = true;
|
||||
this._ready.resolve();
|
||||
} catch (error) {
|
||||
this._isReady = false;
|
||||
this._ready.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
get isReady(): boolean {
|
||||
return this._isReady;
|
||||
}
|
||||
get ready(): Thenable<void> {
|
||||
return this._ready.promise;
|
||||
}
|
||||
|
||||
get id(): string {
|
||||
return this.kernelDetails.id;
|
||||
}
|
||||
|
||||
get name(): string {
|
||||
return this.kernelDetails.name;
|
||||
}
|
||||
|
||||
get supportsIntellisense(): boolean {
|
||||
return this.kernelDetails.supportsIntellisense;
|
||||
}
|
||||
|
||||
get requiresConnection(): boolean {
|
||||
return this.kernelDetails.requiresConnection;
|
||||
}
|
||||
|
||||
get info(): azdata.nb.IInfoReply {
|
||||
return this._info;
|
||||
}
|
||||
|
||||
getSpec(): Thenable<azdata.nb.IKernelSpec> {
|
||||
return this._proxy.ext.$getKernelSpec(this.kernelDetails.kernelId);
|
||||
}
|
||||
|
||||
requestComplete(content: azdata.nb.ICompleteRequest): Thenable<azdata.nb.ICompleteReplyMsg> {
|
||||
return this._proxy.ext.$requestComplete(this.kernelDetails.kernelId, content);
|
||||
}
|
||||
|
||||
requestExecute(content: azdata.nb.IExecuteRequest, disposeOnDone?: boolean): azdata.nb.IFuture {
|
||||
let future = new FutureWrapper(this._proxy);
|
||||
this._proxy.ext.$requestExecute(this.kernelDetails.kernelId, content, disposeOnDone)
|
||||
.then(details => {
|
||||
future.setDetails(details);
|
||||
// Save the future in the main thread notebook so extension can call through and reference it
|
||||
this._proxy.main.addFuture(details.futureId, future);
|
||||
}, error => future.setError(error));
|
||||
return future;
|
||||
}
|
||||
|
||||
interrupt(): Thenable<void> {
|
||||
return this._proxy.ext.$interruptKernel(this.kernelDetails.kernelId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class FutureWrapper implements FutureInternal {
|
||||
private _futureId: number;
|
||||
private _done = new Deferred<azdata.nb.IShellMessage>();
|
||||
private _messageHandlers = new Map<FutureMessageType, azdata.nb.MessageHandler<azdata.nb.IMessage>>();
|
||||
private _msg: azdata.nb.IMessage;
|
||||
private _inProgress: boolean;
|
||||
|
||||
constructor(private _proxy: Proxies) {
|
||||
this._inProgress = true;
|
||||
}
|
||||
|
||||
public setDetails(details: INotebookFutureDetails): void {
|
||||
this._futureId = details.futureId;
|
||||
this._msg = details.msg;
|
||||
}
|
||||
|
||||
public setError(error: Error | string): void {
|
||||
this._done.reject(error);
|
||||
}
|
||||
|
||||
public onMessage(type: FutureMessageType, payload: azdata.nb.IMessage): void {
|
||||
let handler = this._messageHandlers.get(type);
|
||||
if (handler) {
|
||||
try {
|
||||
handler.handle(payload);
|
||||
} catch (error) {
|
||||
// TODO log errors from the handler
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public onDone(done: INotebookFutureDone): void {
|
||||
this._inProgress = false;
|
||||
if (done.succeeded) {
|
||||
this._done.resolve(done.message);
|
||||
} else {
|
||||
this._done.reject(new Error(done.rejectReason));
|
||||
}
|
||||
}
|
||||
|
||||
private addMessageHandler(type: FutureMessageType, handler: azdata.nb.MessageHandler<azdata.nb.IMessage>): void {
|
||||
// Note: there can only be 1 message handler according to the Jupyter Notebook spec.
|
||||
// You can use a message hook to override this / add additional side-processors
|
||||
this._messageHandlers.set(type, handler);
|
||||
}
|
||||
|
||||
//#region Public APIs
|
||||
get inProgress(): boolean {
|
||||
return this._inProgress;
|
||||
}
|
||||
|
||||
set inProgress(value: boolean) {
|
||||
this._inProgress = value;
|
||||
}
|
||||
|
||||
get msg(): azdata.nb.IMessage {
|
||||
return this._msg;
|
||||
}
|
||||
|
||||
get done(): Thenable<azdata.nb.IShellMessage> {
|
||||
return this._done.promise;
|
||||
}
|
||||
|
||||
setReplyHandler(handler: azdata.nb.MessageHandler<azdata.nb.IShellMessage>): void {
|
||||
this.addMessageHandler(FutureMessageType.Reply, handler);
|
||||
}
|
||||
|
||||
setStdInHandler(handler: azdata.nb.MessageHandler<azdata.nb.IStdinMessage>): void {
|
||||
this.addMessageHandler(FutureMessageType.StdIn, handler);
|
||||
}
|
||||
|
||||
setIOPubHandler(handler: azdata.nb.MessageHandler<azdata.nb.IIOPubMessage>): void {
|
||||
this.addMessageHandler(FutureMessageType.IOPub, handler);
|
||||
}
|
||||
|
||||
sendInputReply(content: azdata.nb.IInputReply): void {
|
||||
this._proxy.ext.$sendInputReply(this._futureId, content);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._proxy.main.disposeFuture(this._futureId);
|
||||
this._proxy.ext.$disposeFuture(this._futureId);
|
||||
}
|
||||
|
||||
registerMessageHook(hook: (msg: azdata.nb.IIOPubMessage) => boolean | Thenable<boolean>): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
removeMessageHook(hook: (msg: azdata.nb.IIOPubMessage) => boolean | Thenable<boolean>): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
@@ -1,642 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import * as path from 'path';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IExtHostContext, IUndoStopOptions } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ITextEditorOptions } from 'vs/platform/editor/common/editor';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||
|
||||
import {
|
||||
SqlMainContext, MainThreadNotebookDocumentsAndEditorsShape, SqlExtHostContext, ExtHostNotebookDocumentsAndEditorsShape,
|
||||
INotebookDocumentsAndEditorsDelta, INotebookEditorAddData, INotebookShowOptions, INotebookModelAddedData, INotebookModelChangedData
|
||||
} from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||
import { NotebookInput } from 'sql/workbench/parts/notebook/notebookInput';
|
||||
import { INotebookService, INotebookEditor, IProviderInfo } from 'sql/workbench/services/notebook/common/notebookService';
|
||||
import { ISingleNotebookEditOperation, NotebookChangeKind } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||
import { disposed } from 'vs/base/common/errors';
|
||||
import { ICellModel, NotebookContentChange, INotebookModel } from 'sql/workbench/parts/notebook/models/modelInterfaces';
|
||||
import { NotebookChangeType, CellTypes } from 'sql/workbench/parts/notebook/models/contracts';
|
||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { viewColumnToEditorGroup } from 'vs/workbench/api/common/shared/editor';
|
||||
import { notebookModeId } from 'sql/workbench/common/customInputConverter';
|
||||
import { localize } from 'vs/nls';
|
||||
|
||||
class MainThreadNotebookEditor extends Disposable {
|
||||
private _contentChangedEmitter = new Emitter<NotebookContentChange>();
|
||||
public readonly contentChanged: Event<NotebookContentChange> = this._contentChangedEmitter.event;
|
||||
private _providerId: string = '';
|
||||
private _providers: string[] = [];
|
||||
|
||||
constructor(public readonly editor: INotebookEditor) {
|
||||
super();
|
||||
editor.modelReady.then(model => {
|
||||
this._providerId = model.providerId;
|
||||
|
||||
this._register(model.contentChanged((e) => this._contentChangedEmitter.fire(e)));
|
||||
this._register(model.kernelChanged((e) => {
|
||||
let changeEvent: NotebookContentChange = {
|
||||
changeType: NotebookChangeType.KernelChanged
|
||||
};
|
||||
this._contentChangedEmitter.fire(changeEvent);
|
||||
}));
|
||||
this._register(model.onProviderIdChange((provider) => {
|
||||
this._providerId = provider;
|
||||
}));
|
||||
});
|
||||
editor.notebookParams.providerInfo.then(info => {
|
||||
this._providers = info.providers;
|
||||
});
|
||||
}
|
||||
|
||||
public get uri(): URI {
|
||||
return this.editor.notebookParams.notebookUri;
|
||||
}
|
||||
|
||||
public get id(): string {
|
||||
return this.editor.id;
|
||||
}
|
||||
|
||||
public get isDirty(): boolean {
|
||||
return this.editor.isDirty();
|
||||
}
|
||||
|
||||
public get providerId(): string {
|
||||
return this._providerId;
|
||||
}
|
||||
|
||||
public get providers(): string[] {
|
||||
return this._providers;
|
||||
}
|
||||
|
||||
public get cells(): ICellModel[] {
|
||||
return this.editor.cells;
|
||||
}
|
||||
|
||||
public get model(): INotebookModel | null {
|
||||
return this.editor.model;
|
||||
}
|
||||
|
||||
public save(): Thenable<boolean> {
|
||||
return this.editor.notebookParams.input.save();
|
||||
}
|
||||
|
||||
public matches(input: NotebookInput): boolean {
|
||||
if (!input) {
|
||||
return false;
|
||||
}
|
||||
return input === this.editor.notebookParams.input;
|
||||
}
|
||||
|
||||
public applyEdits(versionIdCheck: number, edits: ISingleNotebookEditOperation[], opts: IUndoStopOptions): boolean {
|
||||
// TODO Handle version tracking
|
||||
// if (this._model.getVersionId() !== versionIdCheck) {
|
||||
// // throw new Error('Model has changed in the meantime!');
|
||||
// // model changed in the meantime
|
||||
// return false;
|
||||
// }
|
||||
|
||||
if (!this.editor) {
|
||||
// console.warn('applyEdits on invisible editor');
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO handle undo tracking
|
||||
// if (opts.undoStopBefore) {
|
||||
// this._codeEditor.pushUndoStop();
|
||||
// }
|
||||
|
||||
this.editor.executeEdits(edits);
|
||||
// if (opts.undoStopAfter) {
|
||||
// this._codeEditor.pushUndoStop();
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
public runCell(cell: ICellModel): Promise<boolean> {
|
||||
if (!this.editor) {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
return this.editor.runCell(cell);
|
||||
}
|
||||
|
||||
public runAllCells(): Promise<boolean> {
|
||||
if (!this.editor) {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
return this.editor.runAllCells();
|
||||
}
|
||||
|
||||
public clearAllOutputs(): Promise<boolean> {
|
||||
if (!this.editor) {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
return this.editor.clearAllOutputs();
|
||||
}
|
||||
}
|
||||
|
||||
function wait(timeMs: number): Promise<void> {
|
||||
return new Promise((resolve: Function) => setTimeout(resolve, timeMs));
|
||||
}
|
||||
|
||||
|
||||
namespace mapset {
|
||||
|
||||
export function setValues<T>(set: Set<T>): T[] {
|
||||
// return Array.from(set);
|
||||
let ret: T[] = [];
|
||||
set.forEach(v => ret.push(v));
|
||||
return ret;
|
||||
}
|
||||
|
||||
export function mapValues<T>(map: Map<any, T>): T[] {
|
||||
// return Array.from(map.values());
|
||||
let ret: T[] = [];
|
||||
map.forEach(v => ret.push(v));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
namespace delta {
|
||||
|
||||
export function ofSets<T>(before: Set<T>, after: Set<T>): { removed: T[], added: T[] } {
|
||||
const removed: T[] = [];
|
||||
const added: T[] = [];
|
||||
before.forEach(element => {
|
||||
if (!after.has(element)) {
|
||||
removed.push(element);
|
||||
}
|
||||
});
|
||||
after.forEach(element => {
|
||||
if (!before.has(element)) {
|
||||
added.push(element);
|
||||
}
|
||||
});
|
||||
return { removed, added };
|
||||
}
|
||||
|
||||
export function ofMaps<K, V>(before: Map<K, V>, after: Map<K, V>): { removed: V[], added: V[] } {
|
||||
const removed: V[] = [];
|
||||
const added: V[] = [];
|
||||
before.forEach((value, index) => {
|
||||
if (!after.has(index)) {
|
||||
removed.push(value);
|
||||
}
|
||||
});
|
||||
after.forEach((value, index) => {
|
||||
if (!before.has(index)) {
|
||||
added.push(value);
|
||||
}
|
||||
});
|
||||
return { removed, added };
|
||||
}
|
||||
}
|
||||
|
||||
class NotebookEditorStateDelta {
|
||||
|
||||
readonly isEmpty: boolean;
|
||||
|
||||
constructor(
|
||||
readonly removedEditors: INotebookEditor[],
|
||||
readonly addedEditors: INotebookEditor[],
|
||||
readonly oldActiveEditor: string,
|
||||
readonly newActiveEditor: string,
|
||||
) {
|
||||
this.isEmpty =
|
||||
this.removedEditors.length === 0
|
||||
&& this.addedEditors.length === 0
|
||||
&& oldActiveEditor === newActiveEditor;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
let ret = 'NotebookEditorStateDelta\n';
|
||||
ret += `\tRemoved Editors: [${this.removedEditors.map(e => e.id).join(', ')}]\n`;
|
||||
ret += `\tAdded Editors: [${this.addedEditors.map(e => e.id).join(', ')}]\n`;
|
||||
ret += `\tNew Active Editor: ${this.newActiveEditor}\n`;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
class NotebookEditorState {
|
||||
|
||||
static compute(before: NotebookEditorState, after: NotebookEditorState): NotebookEditorStateDelta {
|
||||
if (!before) {
|
||||
return new NotebookEditorStateDelta(
|
||||
[], mapset.mapValues(after.textEditors),
|
||||
undefined, after.activeEditor
|
||||
);
|
||||
}
|
||||
const editorDelta = delta.ofMaps(before.textEditors, after.textEditors);
|
||||
const oldActiveEditor = before.activeEditor !== after.activeEditor ? before.activeEditor : undefined;
|
||||
const newActiveEditor = before.activeEditor !== after.activeEditor ? after.activeEditor : undefined;
|
||||
|
||||
return new NotebookEditorStateDelta(
|
||||
editorDelta.removed, editorDelta.added,
|
||||
oldActiveEditor, newActiveEditor
|
||||
);
|
||||
}
|
||||
|
||||
constructor(
|
||||
readonly textEditors: Map<string, INotebookEditor>,
|
||||
readonly activeEditor: string) { }
|
||||
}
|
||||
|
||||
class MainThreadNotebookDocumentAndEditorStateComputer extends Disposable {
|
||||
|
||||
private _currentState: NotebookEditorState;
|
||||
|
||||
constructor(
|
||||
private readonly _onDidChangeState: (delta: NotebookEditorStateDelta) => void,
|
||||
@IEditorService private readonly _editorService: IEditorService,
|
||||
@INotebookService private readonly _notebookService: INotebookService
|
||||
) {
|
||||
super();
|
||||
this._register(this._editorService.onDidActiveEditorChange(this._updateState, this));
|
||||
this._register(this._editorService.onDidVisibleEditorsChange(this._updateState, this));
|
||||
this._register(this._notebookService.onNotebookEditorAdd(this._onDidAddEditor, this));
|
||||
this._register(this._notebookService.onNotebookEditorRemove(this._onDidRemoveEditor, this));
|
||||
this._register(this._notebookService.onNotebookEditorRename(this._onDidRenameEditor, this));
|
||||
|
||||
this._updateState();
|
||||
}
|
||||
|
||||
private _onDidAddEditor(e: INotebookEditor): void {
|
||||
// TODO hook to cell change and other events
|
||||
this._updateState();
|
||||
}
|
||||
|
||||
private _onDidRemoveEditor(e: INotebookEditor): void {
|
||||
// TODO remove event listeners
|
||||
this._updateState();
|
||||
}
|
||||
|
||||
private _onDidRenameEditor(e: INotebookEditor): void {
|
||||
this._updateState();
|
||||
//TODO: Close editor and open it
|
||||
}
|
||||
|
||||
private _updateState(): void {
|
||||
// editor
|
||||
const editors = new Map<string, INotebookEditor>();
|
||||
let activeEditor: string = undefined;
|
||||
|
||||
for (const editor of this._notebookService.listNotebookEditors()) {
|
||||
editors.set(editor.id, editor);
|
||||
if (editor.isActive()) {
|
||||
activeEditor = editor.id;
|
||||
}
|
||||
}
|
||||
|
||||
// compute new state and compare against old
|
||||
const newState = new NotebookEditorState(editors, activeEditor);
|
||||
const delta = NotebookEditorState.compute(this._currentState, newState);
|
||||
if (!delta.isEmpty) {
|
||||
this._currentState = newState;
|
||||
this._onDidChangeState(delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@extHostNamedCustomer(SqlMainContext.MainThreadNotebookDocumentsAndEditors)
|
||||
export class MainThreadNotebookDocumentsAndEditors extends Disposable implements MainThreadNotebookDocumentsAndEditorsShape {
|
||||
private _proxy: ExtHostNotebookDocumentsAndEditorsShape;
|
||||
private _notebookEditors = new Map<string, MainThreadNotebookEditor>();
|
||||
private _modelToDisposeMap = new Map<string, IDisposable[]>();
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@IUntitledEditorService private _untitledEditorService: IUntitledEditorService,
|
||||
@IInstantiationService private _instantiationService: IInstantiationService,
|
||||
@IEditorService private _editorService: IEditorService,
|
||||
@IEditorGroupsService private _editorGroupService: IEditorGroupsService,
|
||||
@ICapabilitiesService private _capabilitiesService: ICapabilitiesService
|
||||
) {
|
||||
super();
|
||||
if (extHostContext) {
|
||||
this._proxy = extHostContext.getProxy(SqlExtHostContext.ExtHostNotebookDocumentsAndEditors);
|
||||
}
|
||||
|
||||
// Create a state computer that actually tracks all required changes. This is hooked to onDelta which notifies extension host
|
||||
this._register(this._instantiationService.createInstance(MainThreadNotebookDocumentAndEditorStateComputer, delta => this._onDelta(delta)));
|
||||
}
|
||||
|
||||
//#region extension host callable APIs
|
||||
$trySaveDocument(uri: UriComponents): Thenable<boolean> {
|
||||
let uriString = URI.revive(uri).toString();
|
||||
let editor = this._notebookEditors.get(uriString);
|
||||
if (editor) {
|
||||
return editor.save();
|
||||
} else {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
}
|
||||
|
||||
$tryShowNotebookDocument(resource: UriComponents, options: INotebookShowOptions): Promise<string> {
|
||||
return Promise.resolve(this.doOpenEditor(resource, options));
|
||||
}
|
||||
|
||||
$tryApplyEdits(id: string, modelVersionId: number, edits: ISingleNotebookEditOperation[], opts: IUndoStopOptions): Promise<boolean> {
|
||||
let editor = this.getEditor(id);
|
||||
if (!editor) {
|
||||
return Promise.reject(disposed(`TextEditor(${id})`));
|
||||
}
|
||||
return Promise.resolve(editor.applyEdits(modelVersionId, edits, opts));
|
||||
}
|
||||
|
||||
$runCell(id: string, cellUri: UriComponents): Promise<boolean> {
|
||||
// Requires an editor and the matching cell in that editor
|
||||
let editor = this.getEditor(id);
|
||||
if (!editor) {
|
||||
return Promise.reject(disposed(`TextEditor(${id})`));
|
||||
}
|
||||
let cell: ICellModel;
|
||||
if (cellUri) {
|
||||
let uriString = URI.revive(cellUri).toString();
|
||||
cell = editor.cells.find(c => c.cellUri.toString() === uriString);
|
||||
// If it's markdown what should we do? Show notification??
|
||||
} else {
|
||||
// Use the active cell in this case, or 1st cell if there's none active
|
||||
cell = editor.model.activeCell;
|
||||
}
|
||||
if (!cell || (cell && cell.cellType !== CellTypes.Code)) {
|
||||
return Promise.reject(new Error(localize('runActiveCell', "F5 shortcut key requires a code cell to be selected. Please select a code cell to run.")));
|
||||
}
|
||||
|
||||
return editor.runCell(cell);
|
||||
}
|
||||
|
||||
$runAllCells(id: string): Promise<boolean> {
|
||||
let editor = this.getEditor(id);
|
||||
if (!editor) {
|
||||
return Promise.reject(disposed(`TextEditor(${id})`));
|
||||
}
|
||||
return editor.runAllCells();
|
||||
}
|
||||
|
||||
$clearAllOutputs(id: string): Promise<boolean> {
|
||||
let editor = this.getEditor(id);
|
||||
if (!editor) {
|
||||
return Promise.reject(disposed(`TextEditor(${id})`));
|
||||
}
|
||||
return editor.clearAllOutputs();
|
||||
}
|
||||
|
||||
$changeKernel(id: string, kernel: azdata.nb.IKernelSpec): Promise<boolean> {
|
||||
let editor = this.getEditor(id);
|
||||
if (!editor) {
|
||||
return Promise.reject(disposed(`TextEditor(${id})`));
|
||||
}
|
||||
return this.doChangeKernel(editor, kernel.display_name);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
private async doOpenEditor(resource: UriComponents, options: INotebookShowOptions): Promise<string> {
|
||||
const uri = URI.revive(resource);
|
||||
|
||||
const editorOptions: ITextEditorOptions = {
|
||||
preserveFocus: options.preserveFocus,
|
||||
pinned: !options.preview
|
||||
};
|
||||
let isUntitled: boolean = uri.scheme === Schemas.untitled;
|
||||
|
||||
const fileInput = isUntitled ? this._untitledEditorService.createOrGet(uri, notebookModeId, options.initialContent) :
|
||||
this._editorService.createInput({ resource: uri, mode: notebookModeId });
|
||||
let input = this._instantiationService.createInstance(NotebookInput, path.basename(uri.fsPath), uri, fileInput);
|
||||
input.defaultKernel = options.defaultKernel;
|
||||
input.connectionProfile = new ConnectionProfile(this._capabilitiesService, options.connectionProfile);
|
||||
if (isUntitled) {
|
||||
let untitledModel = await input.textInput.resolve();
|
||||
await untitledModel.load();
|
||||
input.untitledEditorModel = untitledModel;
|
||||
}
|
||||
let editor = await this._editorService.openEditor(input, editorOptions, viewColumnToEditorGroup(this._editorGroupService, options.position));
|
||||
if (!editor) {
|
||||
return undefined;
|
||||
}
|
||||
return this.waitOnEditor(input);
|
||||
}
|
||||
|
||||
private async waitOnEditor(input: NotebookInput): Promise<string> {
|
||||
let id: string = undefined;
|
||||
let attemptsLeft = 10;
|
||||
let timeoutMs = 20;
|
||||
while (!id && attemptsLeft > 0) {
|
||||
id = this.findNotebookEditorIdFor(input);
|
||||
if (!id) {
|
||||
await wait(timeoutMs);
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
findNotebookEditorIdFor(input: NotebookInput): string {
|
||||
let foundId: string = undefined;
|
||||
this._notebookEditors.forEach(e => {
|
||||
if (e.matches(input)) {
|
||||
foundId = e.id;
|
||||
}
|
||||
});
|
||||
return foundId;
|
||||
}
|
||||
|
||||
getEditor(id: string): MainThreadNotebookEditor {
|
||||
return this._notebookEditors.get(id);
|
||||
}
|
||||
|
||||
private _onDelta(delta: NotebookEditorStateDelta): void {
|
||||
let removedEditors: string[] = [];
|
||||
let removedDocuments: URI[] = [];
|
||||
let addedEditors: MainThreadNotebookEditor[] = [];
|
||||
|
||||
// added editors
|
||||
for (const editor of delta.addedEditors) {
|
||||
const mainThreadEditor = new MainThreadNotebookEditor(editor);
|
||||
|
||||
this._notebookEditors.set(editor.id, mainThreadEditor);
|
||||
addedEditors.push(mainThreadEditor);
|
||||
}
|
||||
|
||||
// removed editors
|
||||
for (const { id } of delta.removedEditors) {
|
||||
const mainThreadEditor = this._notebookEditors.get(id);
|
||||
if (mainThreadEditor) {
|
||||
removedDocuments.push(mainThreadEditor.uri);
|
||||
mainThreadEditor.dispose();
|
||||
this._notebookEditors.delete(id);
|
||||
removedEditors.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
let extHostDelta: INotebookDocumentsAndEditorsDelta = Object.create(null);
|
||||
let empty = true;
|
||||
if (delta.newActiveEditor !== undefined) {
|
||||
empty = false;
|
||||
extHostDelta.newActiveEditor = delta.newActiveEditor;
|
||||
}
|
||||
if (removedDocuments.length > 0) {
|
||||
empty = false;
|
||||
extHostDelta.removedDocuments = removedDocuments;
|
||||
}
|
||||
if (removedEditors.length > 0) {
|
||||
empty = false;
|
||||
extHostDelta.removedEditors = removedEditors;
|
||||
}
|
||||
if (delta.addedEditors.length > 0) {
|
||||
empty = false;
|
||||
extHostDelta.addedDocuments = [];
|
||||
extHostDelta.addedEditors = [];
|
||||
for (let editor of addedEditors) {
|
||||
extHostDelta.addedEditors.push(this._toNotebookEditorAddData(editor));
|
||||
// For now, add 1 document for each editor. In the future these may be trackable independently
|
||||
extHostDelta.addedDocuments.push(this._toNotebookModelAddData(editor));
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty) {
|
||||
this._proxy.$acceptDocumentsAndEditorsDelta(extHostDelta);
|
||||
this.processRemovedDocs(removedDocuments);
|
||||
this.processAddedDocs(addedEditors);
|
||||
}
|
||||
}
|
||||
processRemovedDocs(removedDocuments: URI[]): void {
|
||||
if (!removedDocuments) {
|
||||
return;
|
||||
}
|
||||
removedDocuments.forEach(removedDoc => {
|
||||
let listeners = this._modelToDisposeMap.get(removedDoc.toString());
|
||||
if (listeners && listeners.length) {
|
||||
listeners.forEach(listener => {
|
||||
listener.dispose();
|
||||
});
|
||||
this._modelToDisposeMap.delete(removedDoc.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
processAddedDocs(addedEditors: MainThreadNotebookEditor[]): any {
|
||||
if (!addedEditors) {
|
||||
return;
|
||||
}
|
||||
addedEditors.forEach(editor => {
|
||||
let modelUrl = editor.uri;
|
||||
this._modelToDisposeMap.set(editor.uri.toString(), [editor.contentChanged((e) => {
|
||||
this._proxy.$acceptModelChanged(modelUrl, this._toNotebookChangeData(e, editor));
|
||||
})]);
|
||||
});
|
||||
}
|
||||
|
||||
private _toNotebookEditorAddData(editor: MainThreadNotebookEditor): INotebookEditorAddData {
|
||||
let addData: INotebookEditorAddData = {
|
||||
documentUri: editor.uri,
|
||||
editorPosition: undefined,
|
||||
id: editor.editor.id
|
||||
};
|
||||
return addData;
|
||||
}
|
||||
|
||||
private _toNotebookModelAddData(editor: MainThreadNotebookEditor): INotebookModelAddedData {
|
||||
let addData: INotebookModelAddedData = {
|
||||
uri: editor.uri,
|
||||
isDirty: editor.isDirty,
|
||||
providerId: editor.providerId,
|
||||
providers: editor.providers,
|
||||
cells: this.convertCellModelToNotebookCell(editor.cells)
|
||||
};
|
||||
return addData;
|
||||
}
|
||||
|
||||
private _toNotebookChangeData(e: NotebookContentChange, editor: MainThreadNotebookEditor): INotebookModelChangedData {
|
||||
let changeData: INotebookModelChangedData = {
|
||||
// Note: we just send all cells for now, not a diff
|
||||
cells: this.convertCellModelToNotebookCell(editor.cells),
|
||||
isDirty: e.isDirty,
|
||||
providerId: editor.providerId,
|
||||
providers: editor.providers,
|
||||
uri: editor.uri,
|
||||
kernelSpec: this.getKernelSpec(editor),
|
||||
changeKind: this.mapChangeKind(e.changeType)
|
||||
};
|
||||
return changeData;
|
||||
}
|
||||
|
||||
mapChangeKind(changeType: NotebookChangeType): NotebookChangeKind {
|
||||
switch (changeType) {
|
||||
case NotebookChangeType.CellDeleted:
|
||||
case NotebookChangeType.CellsAdded:
|
||||
case NotebookChangeType.CellOutputUpdated:
|
||||
case NotebookChangeType.CellSourceUpdated:
|
||||
case NotebookChangeType.DirtyStateChanged:
|
||||
return NotebookChangeKind.ContentUpdated;
|
||||
case NotebookChangeType.KernelChanged:
|
||||
case NotebookChangeType.TrustChanged:
|
||||
return NotebookChangeKind.MetadataUpdated;
|
||||
case NotebookChangeType.Saved:
|
||||
return NotebookChangeKind.Save;
|
||||
case NotebookChangeType.CellExecuted:
|
||||
return NotebookChangeKind.CellExecuted;
|
||||
default:
|
||||
return NotebookChangeKind.ContentUpdated;
|
||||
}
|
||||
}
|
||||
|
||||
private getKernelSpec(editor: MainThreadNotebookEditor): azdata.nb.IKernelSpec {
|
||||
let spec = editor && editor.model && editor.model.clientSession ? editor.model.clientSession.cachedKernelSpec : undefined;
|
||||
return spec;
|
||||
}
|
||||
|
||||
private convertCellModelToNotebookCell(cells: ICellModel | ICellModel[]): azdata.nb.NotebookCell[] {
|
||||
let notebookCells: azdata.nb.NotebookCell[] = [];
|
||||
if (Array.isArray(cells)) {
|
||||
for (let cell of cells) {
|
||||
notebookCells.push({
|
||||
uri: cell.cellUri,
|
||||
contents: {
|
||||
cell_type: cell.cellType,
|
||||
execution_count: cell.executionCount,
|
||||
metadata: {
|
||||
language: cell.language
|
||||
},
|
||||
source: undefined,
|
||||
outputs: [...cell.outputs]
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
notebookCells.push({
|
||||
uri: cells.cellUri,
|
||||
contents: {
|
||||
cell_type: cells.cellType,
|
||||
execution_count: undefined,
|
||||
metadata: {
|
||||
language: cells.language
|
||||
},
|
||||
source: undefined
|
||||
}
|
||||
});
|
||||
}
|
||||
return notebookCells;
|
||||
}
|
||||
|
||||
private async doChangeKernel(editor: MainThreadNotebookEditor, displayName: string): Promise<boolean> {
|
||||
let listeners = this._modelToDisposeMap.get(editor.id);
|
||||
editor.model.changeKernel(displayName);
|
||||
return new Promise((resolve) => {
|
||||
listeners.push(editor.model.kernelChanged((kernel) => {
|
||||
resolve(true);
|
||||
}));
|
||||
this._modelToDisposeMap.set(editor.id, listeners);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { SqlExtHostContext, SqlMainContext, ExtHostObjectExplorerShape, MainThreadObjectExplorerShape } from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||
import * as azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { IObjectExplorerService, NodeInfoWithConnection } from 'sql/workbench/services/objectExplorer/common/objectExplorerService';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import * as TaskUtilities from 'sql/workbench/common/taskUtilities';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { TreeItemCollapsibleState } from 'sql/workbench/parts/objectExplorer/common/treeNode';
|
||||
|
||||
@extHostNamedCustomer(SqlMainContext.MainThreadObjectExplorer)
|
||||
export class MainThreadObjectExplorer implements MainThreadObjectExplorerShape {
|
||||
|
||||
private _proxy: ExtHostObjectExplorerShape;
|
||||
private _toDispose: IDisposable[];
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
|
||||
@IObjectExplorerService private _objectExplorerService: IObjectExplorerService,
|
||||
@IEditorService private _workbenchEditorService: IEditorService
|
||||
) {
|
||||
if (extHostContext) {
|
||||
this._proxy = extHostContext.getProxy(SqlExtHostContext.ExtHostObjectExplorer);
|
||||
}
|
||||
this._toDispose = [];
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._toDispose = dispose(this._toDispose);
|
||||
}
|
||||
|
||||
public $getNode(connectionId: string, nodePath?: string): Thenable<azdata.NodeInfo> {
|
||||
return this._objectExplorerService.getTreeNode(connectionId, nodePath).then(treeNode => {
|
||||
if (!treeNode) {
|
||||
return undefined;
|
||||
}
|
||||
return treeNode.toNodeInfo();
|
||||
});
|
||||
}
|
||||
|
||||
public $getActiveConnectionNodes(): Thenable<NodeInfoWithConnection[]> {
|
||||
let connectionNodes = this._objectExplorerService.getActiveConnectionNodes();
|
||||
return Promise.resolve(connectionNodes.map(node => {
|
||||
return { connectionId: node.connection.id, nodeInfo: node.toNodeInfo() };
|
||||
}));
|
||||
}
|
||||
|
||||
public $setExpandedState(connectionId: string, nodePath: string, expandedState: vscode.TreeItemCollapsibleState): Thenable<void> {
|
||||
return this._objectExplorerService.getTreeNode(connectionId, nodePath).then(treeNode => treeNode.setExpandedState(expandedState));
|
||||
}
|
||||
|
||||
public $setSelected(connectionId: string, nodePath: string, selected: boolean, clearOtherSelections: boolean = undefined): Thenable<void> {
|
||||
return this._objectExplorerService.getTreeNode(connectionId, nodePath).then(treeNode => treeNode.setSelected(selected, clearOtherSelections));
|
||||
}
|
||||
|
||||
public $getChildren(connectionId: string, nodePath: string): Thenable<azdata.NodeInfo[]> {
|
||||
return this._objectExplorerService.getTreeNode(connectionId, nodePath).then(treeNode => treeNode.getChildren().then(children => children.map(node => node.toNodeInfo())));
|
||||
}
|
||||
|
||||
public $isExpanded(connectionId: string, nodePath: string): Thenable<boolean> {
|
||||
return this._objectExplorerService.getTreeNode(connectionId, nodePath).then(treeNode => treeNode.isExpanded());
|
||||
}
|
||||
|
||||
public $findNodes(connectionId: string, type: string, schema: string, name: string, database: string, parentObjectNames: string[]): Thenable<azdata.NodeInfo[]> {
|
||||
return this._objectExplorerService.findNodes(connectionId, type, schema, name, database, parentObjectNames);
|
||||
}
|
||||
|
||||
public $refresh(connectionId: string, nodePath: string): Thenable<azdata.NodeInfo> {
|
||||
return this._objectExplorerService.refreshNodeInView(connectionId, nodePath).then(node => node.toNodeInfo());
|
||||
}
|
||||
|
||||
public $getNodeActions(connectionId: string, nodePath: string): Thenable<string[]> {
|
||||
return this._objectExplorerService.getNodeActions(connectionId, nodePath);
|
||||
}
|
||||
|
||||
public $getSessionConnectionProfile(sessionId: string): Thenable<azdata.IConnectionProfile> {
|
||||
return Promise.resolve(this._objectExplorerService.getSessionConnectionProfile(sessionId));
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { SqlExtHostContext, SqlMainContext, ExtHostQueryEditorShape, MainThreadQueryEditorShape } from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { IConnectionManagementService, IConnectionCompletionOptions, ConnectionType, RunQueryOnConnectionMode } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { QueryEditor } from 'sql/workbench/parts/query/browser/queryEditor';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IQueryModelService } from 'sql/platform/query/common/queryModel';
|
||||
import * as azdata from 'azdata';
|
||||
import { IQueryManagementService } from 'sql/platform/query/common/queryManagement';
|
||||
|
||||
@extHostNamedCustomer(SqlMainContext.MainThreadQueryEditor)
|
||||
export class MainThreadQueryEditor implements MainThreadQueryEditorShape {
|
||||
|
||||
private _proxy: ExtHostQueryEditorShape;
|
||||
private _toDispose: IDisposable[];
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
|
||||
@IQueryModelService private _queryModelService: IQueryModelService,
|
||||
@IEditorService private _editorService: IEditorService,
|
||||
@IQueryManagementService private _queryManagementService: IQueryManagementService
|
||||
) {
|
||||
if (extHostContext) {
|
||||
this._proxy = extHostContext.getProxy(SqlExtHostContext.ExtHostQueryEditor);
|
||||
}
|
||||
this._toDispose = [];
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._toDispose = dispose(this._toDispose);
|
||||
}
|
||||
|
||||
public $connect(fileUri: string, connectionId: string): Thenable<void> {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
let editors = this._editorService.visibleControls.filter(resource => {
|
||||
return !!resource && resource.input.getResource().toString() === fileUri;
|
||||
});
|
||||
let editor = editors && editors.length > 0 ? editors[0] : undefined;
|
||||
let options: IConnectionCompletionOptions = {
|
||||
params: { connectionType: ConnectionType.editor, runQueryOnCompletion: RunQueryOnConnectionMode.none, input: editor ? editor.input as any : undefined },
|
||||
saveTheConnection: false,
|
||||
showDashboard: false,
|
||||
showConnectionDialogOnError: true,
|
||||
showFirewallRuleOnError: true,
|
||||
};
|
||||
if (connectionId) {
|
||||
let connection = this._connectionManagementService.getActiveConnections().filter(c => c.id === connectionId);
|
||||
if (connection && connection.length > 0) {
|
||||
this._connectionManagementService.connect(connection[0], fileUri, options).then(() => {
|
||||
resolve();
|
||||
}).catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public $runQuery(fileUri: string): void {
|
||||
let filteredEditors = this._editorService.visibleControls.filter(editor => editor.input.getResource().toString() === fileUri);
|
||||
if (filteredEditors && filteredEditors.length > 0) {
|
||||
let editor = filteredEditors[0];
|
||||
if (editor instanceof QueryEditor) {
|
||||
let queryEditor: QueryEditor = editor;
|
||||
queryEditor.runCurrentQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public $registerQueryInfoListener(handle: number, providerId: string): void {
|
||||
this._toDispose.push(this._queryModelService.onQueryEvent(event => {
|
||||
this._proxy.$onQueryEvent(handle, event.uri, event);
|
||||
}));
|
||||
}
|
||||
|
||||
public $createQueryTab(fileUri: string, title: string, componentId: string): void {
|
||||
let editors = this._editorService.visibleControls.filter(resource => {
|
||||
return !!resource && resource.input.getResource().toString() === fileUri;
|
||||
});
|
||||
|
||||
let editor = editors && editors.length > 0 ? editors[0] : undefined;
|
||||
if (editor) {
|
||||
let queryEditor = editor as QueryEditor;
|
||||
if (queryEditor) {
|
||||
queryEditor.registerQueryModelViewTab(title, componentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public $setQueryExecutionOptions(fileUri: string, options: azdata.QueryExecutionOptions): Thenable<void> {
|
||||
return this._queryManagementService.setQueryExecutionOptions(fileUri, options);
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import { IResourceProviderService } from 'sql/workbench/services/resourceProvider/common/resourceProviderService';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import {
|
||||
ExtHostResourceProviderShape,
|
||||
MainThreadResourceProviderShape,
|
||||
SqlExtHostContext,
|
||||
SqlMainContext
|
||||
} from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
|
||||
|
||||
@extHostNamedCustomer(SqlMainContext.MainThreadResourceProvider)
|
||||
export class MainThreadResourceProvider implements MainThreadResourceProviderShape {
|
||||
private _providerMetadata: { [handle: number]: azdata.AccountProviderMetadata };
|
||||
private _proxy: ExtHostResourceProviderShape;
|
||||
private _toDispose: IDisposable[];
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@IResourceProviderService private _resourceProviderService: IResourceProviderService
|
||||
) {
|
||||
this._providerMetadata = {};
|
||||
if (extHostContext) {
|
||||
this._proxy = extHostContext.getProxy(SqlExtHostContext.ExtHostResourceProvider);
|
||||
}
|
||||
this._toDispose = [];
|
||||
}
|
||||
|
||||
public $registerResourceProvider(providerMetadata: azdata.ResourceProviderMetadata, handle: number): Thenable<any> {
|
||||
let self = this;
|
||||
|
||||
// Create the account provider that interfaces with the extension via the proxy and register it
|
||||
let resourceProvider: azdata.ResourceProvider = {
|
||||
createFirewallRule(account: azdata.Account, firewallruleInfo: azdata.FirewallRuleInfo): Thenable<azdata.CreateFirewallRuleResponse> {
|
||||
return self._proxy.$createFirewallRule(handle, account, firewallruleInfo);
|
||||
},
|
||||
handleFirewallRule(errorCode: number, errorMessage: string, connectionTypeId: string): Thenable<azdata.HandleFirewallRuleResponse> {
|
||||
return self._proxy.$handleFirewallRule(handle, errorCode, errorMessage, connectionTypeId);
|
||||
}
|
||||
};
|
||||
this._resourceProviderService.registerProvider(providerMetadata.id, resourceProvider);
|
||||
this._providerMetadata[handle] = providerMetadata;
|
||||
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
public $unregisterResourceProvider(handle: number): Thenable<any> {
|
||||
this._resourceProviderService.unregisterProvider(this._providerMetadata[handle].id);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._toDispose = dispose(this._toDispose);
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import {
|
||||
SqlExtHostContext, ExtHostSerializationProviderShape,
|
||||
MainThreadSerializationProviderShape, SqlMainContext
|
||||
} from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||
import { ISerializationService } from 'sql/platform/serialization/common/serializationService';
|
||||
import * as azdata from 'azdata';
|
||||
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
|
||||
@extHostNamedCustomer(SqlMainContext.MainThreadSerializationProvider)
|
||||
export class MainThreadSerializationProvider implements MainThreadSerializationProviderShape {
|
||||
|
||||
private _proxy: ExtHostSerializationProviderShape;
|
||||
|
||||
private _toDispose: IDisposable[];
|
||||
|
||||
private _registrations: { [handle: number]: IDisposable; } = Object.create(null);
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@ISerializationService private serializationService: ISerializationService
|
||||
|
||||
) {
|
||||
if (extHostContext) {
|
||||
this._proxy = extHostContext.getProxy(SqlExtHostContext.ExtHostSerializationProvider);
|
||||
}
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._toDispose = dispose(this._toDispose);
|
||||
}
|
||||
|
||||
public $registerSerializationProvider(handle: number): Promise<any> {
|
||||
let self = this;
|
||||
|
||||
this._registrations[handle] = this.serializationService.addEventListener(handle, {
|
||||
onSaveAs(saveFormat: string, savePath: string, results: string, appendToFile: boolean): Thenable<azdata.SaveResultRequestResult> {
|
||||
return self._proxy.$saveAs(saveFormat, savePath, results, appendToFile);
|
||||
}
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $unregisterSerializationProvider(handle: number): Promise<any> {
|
||||
let registration = this._registrations[handle];
|
||||
if (registration) {
|
||||
registration.dispose();
|
||||
delete this._registrations[handle];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -40,8 +40,7 @@ import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
|
||||
import { ExtHostConfiguration, ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration';
|
||||
import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage';
|
||||
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
|
||||
import { ISchemeTransformer } from 'vs/workbench/api/common/extHostLanguageFeatures';
|
||||
import { AzureResource } from 'sql/platform/accounts/common/interfaces';
|
||||
import { IURITransformer } from 'vs/base/common/uriIpc';
|
||||
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
|
||||
|
||||
export interface ISqlExtensionApiFactory {
|
||||
@@ -61,10 +60,9 @@ export function createApiFactory(
|
||||
extensionService: ExtHostExtensionService,
|
||||
logService: ExtHostLogService,
|
||||
extHostStorage: ExtHostStorage,
|
||||
schemeTransformer: ISchemeTransformer | null,
|
||||
outputChannelName: string
|
||||
uriTransformer: IURITransformer | null
|
||||
): ISqlExtensionApiFactory {
|
||||
let vsCodeFactory = extHostApi.createApiFactory(initData, rpcProtocol, extHostWorkspace, extHostConfiguration, extensionService, logService, extHostStorage, schemeTransformer, outputChannelName);
|
||||
let vsCodeFactory = extHostApi.createApiFactory(initData, rpcProtocol, extHostWorkspace, extHostConfiguration, extensionService, logService, extHostStorage, uriTransformer);
|
||||
|
||||
// Addressable instances
|
||||
const extHostAccountManagement = rpcProtocol.set(SqlExtHostContext.ExtHostAccountManagement, new ExtHostAccountManagement(rpcProtocol));
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
// --- SQL contributions
|
||||
import 'sql/workbench/api/node/mainThreadConnectionManagement';
|
||||
import 'sql/workbench/api/node/mainThreadCredentialManagement';
|
||||
import 'sql/workbench/api/node/mainThreadDataProtocol';
|
||||
import 'sql/workbench/api/node/mainThreadObjectExplorer';
|
||||
import 'sql/workbench/api/node/mainThreadBackgroundTaskManagement';
|
||||
import 'sql/workbench/api/node/mainThreadSerializationProvider';
|
||||
import 'sql/workbench/api/node/mainThreadResourceProvider';
|
||||
import 'sql/workbench/api/electron-browser/mainThreadTasks';
|
||||
import 'sql/workbench/api/electron-browser/mainThreadDashboard';
|
||||
import 'sql/workbench/api/node/mainThreadDashboardWebview';
|
||||
import 'sql/workbench/api/node/mainThreadQueryEditor';
|
||||
import 'sql/workbench/api/node/mainThreadModelView';
|
||||
import 'sql/workbench/api/node/mainThreadModelViewDialog';
|
||||
import 'sql/workbench/api/node/mainThreadNotebook';
|
||||
import 'sql/workbench/api/node/mainThreadNotebookDocumentsAndEditors';
|
||||
import 'sql/workbench/api/node/mainThreadAccountManagement';
|
||||
import 'sql/workbench/api/node/mainThreadExtensionManagement';
|
||||
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
|
||||
export class SqlExtHostContribution implements IWorkbenchContribution {
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private instantiationService: IInstantiationService
|
||||
) {
|
||||
}
|
||||
|
||||
public getId(): string {
|
||||
return 'sql.api.sqlExtHost';
|
||||
}
|
||||
}
|
||||
|
||||
// Register File Tracker
|
||||
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(
|
||||
SqlExtHostContribution,
|
||||
LifecyclePhase.Restored
|
||||
);
|
||||
Reference in New Issue
Block a user