Files
azuredatastudio/extensions/mssql/src/main.ts
Alan Ren abe54a2b92 initial PR for table designer feature (#17200)
* wip

* wire up e2e

* hook up styler and add as dataprotocal feature

* designer child component rendering

* table component updates

* styler and selectbox column editor

* fix editor size and dupe component creation issue

* fix checkbox column and add more testing data

* properties pane

* only rerender when needed

* properties pane update

* update commands

* cleanup for PR

* revert unwanted changes

* Adding a few tests for Add SQL binding (#17079)

* initial changes

* add a couple more tests

* LEGO: check in for main to temporary branch. (#17089)

* LEGO: check in for main to temporary branch. (#17091)

Co-authored-by: kburtram <karlb@microsoft.com>

* Adds autorest-based SQL Project generation to SQL Database Projects extension (#17078)

* Initial changes

* checkpoint

* Constructing project with post deployment script

* Correcting to intentionally read from cached list of projects

* Adding activation event, fixing fresh workspace bug

* Convert netcoreTool and autorestHelper to share a helper class for streamed command

* Include npm package version to force update

* test checkpoint

* Unit tests

* Added contextual quickpicks for autorest dialogs

* Adding projectController test

* Added projectController test, some refactoring for testability

* Merge branch 'main' into benjin/autorest

* Fixing 'which' import

* PR feedback

* Fixing tests

* Adding additional information for when project provider tests fail

* Hopefully fixing failing tests (unable to repro locally)

* Adding Generate Project item to workspace menu

* PR feedback

* LEGO: check in for main to temporary branch. (#17097)

* added sql database projects strings (#17100)

* Set kernelAlias in startSession when isValidConnection is truthy (#17102)

* PR follow-up comments (#17113)

* Change recompare message after changing options to modal (#17103)

* Change recompare message to modal

* change options to yes and no

* Remove commented code block in git extension (#17116)

* Remove commented code block in git extension

* Add SQL CARBON EDIT tag

* [Loc] Small change to generatingProjectFailed (#17118)

* Add Null Shortcut and added NULL text for default NULL value. (#17085)

* added test key event

* added null function to tryHandleKeyEvent

* added null formatting

* added working null insert.

* added editDataGridPanel string null support

* Bump nth-check from 2.0.0 to 2.0.1 in /build (#17115)

Bumps [nth-check](https://github.com/fb55/nth-check) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/fb55/nth-check/releases)
- [Commits](https://github.com/fb55/nth-check/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: nth-check
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Add excludeFlags to extenson marketplace query (#17121)

* Add excludeFlags to extenson marketplace query

* Remove dead code

* Remove extraneous blank line

* Address code review feedback

* Adding Derived Columns to ADS Flatfile Import (#16795)

* Adding derived column boilerplate

* brandan preliminary frontend changes

* empty commit

* added new param

* updating contracts, dialogue changes

* utils changes, saving timeout attempt

* pushing for aasim

* Cleaning up code and fixing the issue in theory

* changing button, did not solve independent scroll

* Fixing the scroll bar issue

* updating flat file service

* adding override keyword to overrriden method

* improving UI

* pushing changes associated with resolved comments

* localizing strings, editing comments

* all comments resolved

* Fixing a test

* updating import package
Updating azure MFA bug

* Clearing navigation validator
Fixing broken table name change

* fixed prose test

* removing unused code from tests

* Fixed PR comments

* Fixing some PR comments

* WIP

* Fixing transformation code and create derived column dialog styling

* removing unused code

* Adding comment for console log

* fixed table styling

* Adding some aria labels

* Fixed some code cleanup issues

* update import service

Co-authored-by: Aasim Khan <aasimkhan30@gmail.com>
Co-authored-by: bnhoule <t-bhoule@microsoft.com>

* Change keybindings for copying query with Results (#17127)

Co-authored-by: Monica Gupta <mogupt@microsoft.com>

* sql proj - publish to docker improvements  (#17124)

* Add AAD token expiration handling for query runner (#17117)

* Add AAD token refresh for notebook

* move token refresh to query management and remove previous refresh calls

* Add guids to RunAll and RunCell events (#17123)

Add guids to RunAll and RunCell events

* add error banner for failed migration cutover and cancel migration (#17106)

* [Loc] update to sql migration, database projects and import extension strings (#17130)

* Apply optional storage class settings in sql mi create command (#17129)

* Make storage classes optional

* Fix notebook to use storage class options

Co-authored-by: Charmaine Chan <chachan@microsoft.com>

* Add support for adding new setting in local.settings.json in add SQL binding quickpick (#17093)

* be able to add new setting in local.settings.json

* cleanup

* addressing comments

* remove todo comment

* addressing comments

* update some strings to uris

* bump version of sqltoolsservice (#17133)

* mark schema compare tests as unstable (#17140)

* [Loc] Update for arc and sql-database-projects (#17148)

* ML extension vbump (#17143)

* Configure docker image and web smoke tests for ADSWeb. (#17136)

* Adjusts timeout period

* Revert "Adjusts timeout period"

This reverts commit 0f372eae2a4611554093b6c09f1ff6c451132e19.

* Adds firefox as browser option

* Corrects yaml smoke test script

* Resets args array to original values

* Corrects build path

* Resolves ignoring browser option error

* continue even after writing to stderr

* Adjusts smoke test (browser) script

* More adjustments to smoke test script

* Corrects server path

* Uses build variable directly in build path

* Specifies browser type since cannot be ignored error

* Adds browser option

* Updates web build image and corrects smoke test exe command

* Removes commented out task

* Updates dockerfile to support web smoketests

* Removes failOnStderr flag

* Use curl instead of wget in Dockerfile

* Fixed a bug with cancling publish (#17160)

* Save And Close Functionality (#17000)

* save and close

* wip

* working save and close

* cleanup

* pr changes

* pr changes

* fix capitalization

* fix build

* pr fix

* Added dynamic options for SQL MIAA Deployment Wizard and updated checkbox field (#17119)

* Dynamic enablement

* Added new package.json field for dynamic options and corresponding functions and classes.

* Enabled dynamic options non-generalized and changed formatting of checkbox to have label on the left.

* Added setOptions under InputComponentInfo for generalization, comments under checkbox component, and changed Replicas to High Availability to reflect parity in portal.

* fix unit test

Co-authored-by: Candice Ye <canye@microsoft.com>
Co-authored-by: Alan Ren <alanren@microsoft.com>

* LEGO: check in for main to temporary branch. (#17168)

* [Loc] added new arc strings and fix for sql-database-projects lcl file for Japanese (#17171)

* [Loc] added new arc strings and fix for sql-database-projects xlf

* removed newline

* Port of Vscode fix for colors too close (#17146)

* default light colors list.focusHighlightForeground too close to list.activeSelectionBackground. Fixes #127597

* remove activeSelectionBackground from theme-carbon as it conflicts with vscode.

* remove dark carbon background

Co-authored-by: Martin Aeschlimann <martinae@microsoft.com>

* Markdown Horizontal Scrollbar Fix (#17083)

* dynamically change horizontal scrollbar

* working horizontal scrollbar

* created new event to handle both scrollbar and mouse wheel

* only show scrollbar when needed

* LEGO: check in for main to temporary branch. (#17181)

* Bump axios to 0.21.4 (#17161)

* Kusto version bump to 0.5.6 (#17114)

* Bumped Kusto toolsservice version to 125 and bumped version to 0.5.6

* Changed netcoreapp3.1 to net5.0 in Kusto config.json

* AzureMonitor bump ToolService version and extension version. (#17174)

* Bump concat-with-sourcemaps from 1.0.4 to 1.1.0 (#17158)

Bumps [concat-with-sourcemaps](https://github.com/floridoo/concat-with-sourcemaps) from 1.0.4 to 1.1.0.
- [Release notes](https://github.com/floridoo/concat-with-sourcemaps/releases)
- [Commits](https://github.com/floridoo/concat-with-sourcemaps/commits)

---
updated-dependencies:
- dependency-name: concat-with-sourcemaps
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Update service downloader to 0.2.3 (#17186)

* Notebook Views grid fixes (#17170)

* update data workspace restart ADS to open workspace message (#17188)

* update message

* update string

* Add back "Remove Project" (#17178)

* remove project working with full paths

* use relative paths

* const

* addressing comments

* Bump github-auth axios to 0.21.4 (#17189)

* LEGO: check in for main to temporary branch. (#17192)

* LEGO: check in for main to temporary branch. (#17190)

Co-authored-by: kburtram <karlb@microsoft.com>

* [Loc] Add a small change to dataworkspace (#17194)

* added bump to sqltoolsservice version (#17195)

* Check if file is dirty before adding sql binding (#17175)

* check if file is dirty before adding sql binding

* Addressing comments

* Add vertical scroll bar to Preview in Split View (#17164)

* reset max height

* add editor height

* set md editor height

* Split up NotebookProvider into separate providers for handling file serialization and cell execution. (#17176)

* fix floating promises

* pr comments

* reuse component definition

* comments

* fix error

Co-authored-by: Kim Santiago <31145923+kisantia@users.noreply.github.com>
Co-authored-by: csigs <csigs@users.noreply.github.com>
Co-authored-by: kburtram <karlb@microsoft.com>
Co-authored-by: Benjin Dubishar <benjin.dubishar@gmail.com>
Co-authored-by: Alex Ma <alma1@microsoft.com>
Co-authored-by: Justin M <63619224+JustinMDotNet@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: bnhoule <52506119+bnhoule@users.noreply.github.com>
Co-authored-by: Aasim Khan <aasimkhan30@gmail.com>
Co-authored-by: bnhoule <t-bhoule@microsoft.com>
Co-authored-by: Monica Gupta <scorpio90m@gmail.com>
Co-authored-by: Monica Gupta <mogupt@microsoft.com>
Co-authored-by: Leila Lali <llali@microsoft.com>
Co-authored-by: Hai Cao <hacao@microsoft.com>
Co-authored-by: Daniel Grajeda <dagrajed@microsoft.com>
Co-authored-by: brian-harris <61598682+brian-harris@users.noreply.github.com>
Co-authored-by: Charmaine Chan <69230572+charmainewkchan@users.noreply.github.com>
Co-authored-by: Charmaine Chan <chachan@microsoft.com>
Co-authored-by: Lewis Sanchez <87730006+lewis-sanchez@users.noreply.github.com>
Co-authored-by: Christopher Suh <chsuh@microsoft.com>
Co-authored-by: Candice Ye <candiceye@berkeley.edu>
Co-authored-by: Candice Ye <canye@microsoft.com>
Co-authored-by: Martin Aeschlimann <martinae@microsoft.com>
Co-authored-by: Vasu Bhog <vabhog@microsoft.com>
Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
Co-authored-by: Barbara Valdez <34872381+barbaravaldez@users.noreply.github.com>
Co-authored-by: Cory Rivera <corivera@microsoft.com>
2021-10-08 19:24:31 -07:00

252 lines
12 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as azdata from 'azdata';
import * as path from 'path';
import * as os from 'os';
import * as Constants from './constants';
import ContextProvider from './contextProvider';
import * as Utils from './utils';
import { AppContext } from './appContext';
import { UploadFilesCommand, MkDirCommand, SaveFileCommand, PreviewFileCommand, CopyPathCommand, DeleteFilesCommand, ManageAccessCommand } from './objectExplorerNodeProvider/hdfsCommands';
import { IPrompter } from './prompts/question';
import CodeAdapter from './prompts/adapter';
import { IExtension } from './mssql';
import { OpenSparkJobSubmissionDialogCommand, OpenSparkJobSubmissionDialogFromFileCommand, OpenSparkJobSubmissionDialogTask } from './sparkFeature/dialog/dialogCommands';
import { OpenSparkYarnHistoryTask } from './sparkFeature/historyTask';
import { MssqlObjectExplorerNodeProvider, mssqlOutputChannel } from './objectExplorerNodeProvider/objectExplorerNodeProvider';
import { registerSearchServerCommand } from './objectExplorerNodeProvider/command';
import { MssqlIconProvider } from './iconProvider';
import { registerServiceEndpoints, Endpoint } from './dashboard/serviceEndpoints';
import { getBookExtensionContributions } from './dashboard/bookExtensions';
import { registerBooksWidget } from './dashboard/bookWidget';
import { createMssqlApi } from './mssqlApiFactory';
import { AuthType } from './util/auth';
import { SqlToolsServer } from './sqlToolsServer';
import { promises as fs } from 'fs';
import { IconPathHelper } from './iconHelper';
import * as nls from 'vscode-nls';
import { INotebookConvertService } from './notebookConvert/notebookConvertService';
import { registerTableDesignerCommands } from './tableDesigner/tableDesigner';
const localize = nls.loadMessageBundle();
const msgSampleCodeDataFrame = localize('msgSampleCodeDataFrame', "This sample code loads the file into a data frame and shows the first 10 results.");
export async function activate(context: vscode.ExtensionContext): Promise<IExtension> {
// lets make sure we support this platform first
let supported = await Utils.verifyPlatform();
if (!supported) {
void vscode.window.showErrorMessage('Unsupported platform');
return undefined;
}
// ensure our log path exists
if (!(await Utils.exists(context.logPath))) {
await fs.mkdir(context.logPath);
}
IconPathHelper.setExtensionContext(context);
let prompter: IPrompter = new CodeAdapter();
let appContext = new AppContext(context);
let nodeProvider = new MssqlObjectExplorerNodeProvider(prompter, appContext);
azdata.dataprotocol.registerObjectExplorerNodeProvider(nodeProvider);
let iconProvider = new MssqlIconProvider();
azdata.dataprotocol.registerIconProvider(iconProvider);
activateSparkFeatures(appContext);
activateNotebookTask(appContext);
registerSearchServerCommand(appContext);
context.subscriptions.push(new ContextProvider());
registerHdfsCommands(context, prompter, appContext);
registerLogCommand(context);
registerServiceEndpoints(context);
// Get book contributions - in the future this will be integrated with the Books/Notebook widget to show as a dashboard widget
const bookContributionProvider = getBookExtensionContributions(context);
context.subscriptions.push(bookContributionProvider);
registerBooksWidget(bookContributionProvider);
// initialize client last so we don't have features stuck behind it
const server = new SqlToolsServer();
context.subscriptions.push(server);
await server.start(appContext);
vscode.commands.registerCommand('mssql.exportSqlAsNotebook', async (uri: vscode.Uri) => {
try {
const result = await appContext.getService<INotebookConvertService>(Constants.NotebookConvertService).convertSqlToNotebook(uri.toString());
const title = findNextUntitledEditorName();
const untitledUri = vscode.Uri.parse(`untitled:${title}`);
await azdata.nb.showNotebookDocument(untitledUri, { initialContent: result.content });
} catch (err) {
void vscode.window.showErrorMessage(localize('mssql.errorConvertingToNotebook', "An error occurred converting the SQL document to a Notebook. Error : {0}", err.toString()));
}
});
vscode.commands.registerCommand('mssql.exportNotebookToSql', async (uri: vscode.Uri) => {
try {
// SqlToolsService doesn't currently store anything about Notebook documents so we have to pass the raw JSON to it directly
// We use vscode.workspace.textDocuments here because the azdata.nb.notebookDocuments don't actually contain their contents
// (they're left out for perf purposes)
const doc = vscode.workspace.textDocuments.find(doc => doc.uri.toString() === uri.toString());
const result = await appContext.getService<INotebookConvertService>(Constants.NotebookConvertService).convertNotebookToSql(doc.getText());
await azdata.queryeditor.openQueryDocument({ content: result.content });
} catch (err) {
void vscode.window.showErrorMessage(localize('mssql.errorConvertingToSQL', "An error occurred converting the Notebook document to SQL. Error : {0}", err.toString()));
}
});
registerTableDesignerCommands(appContext);
return createMssqlApi(appContext, server);
}
const logFiles = ['resourceprovider.log', 'sqltools.log', 'credentialstore.log'];
function registerLogCommand(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.commands.registerCommand('mssql.showLogFile', async () => {
const choice = await vscode.window.showQuickPick(logFiles);
if (choice) {
const document = await vscode.workspace.openTextDocument(vscode.Uri.file(path.join(context.logPath, choice)));
if (document) {
void vscode.window.showTextDocument(document);
}
}
}));
}
function registerHdfsCommands(context: vscode.ExtensionContext, prompter: IPrompter, appContext: AppContext) {
context.subscriptions.push(new UploadFilesCommand(prompter, appContext));
context.subscriptions.push(new MkDirCommand(prompter, appContext));
context.subscriptions.push(new SaveFileCommand(prompter, appContext));
context.subscriptions.push(new PreviewFileCommand(prompter, appContext));
context.subscriptions.push(new CopyPathCommand(appContext));
context.subscriptions.push(new DeleteFilesCommand(prompter, appContext));
context.subscriptions.push(new ManageAccessCommand(appContext));
}
function activateSparkFeatures(appContext: AppContext): void {
let extensionContext = appContext.extensionContext;
let outputChannel: vscode.OutputChannel = mssqlOutputChannel;
extensionContext.subscriptions.push(new OpenSparkJobSubmissionDialogCommand(appContext, outputChannel));
extensionContext.subscriptions.push(new OpenSparkJobSubmissionDialogFromFileCommand(appContext, outputChannel));
azdata.tasks.registerTask(Constants.mssqlClusterLivySubmitSparkJobTask, async (profile: azdata.IConnectionProfile) => {
await new OpenSparkJobSubmissionDialogTask(appContext, outputChannel).execute(profile);
});
azdata.tasks.registerTask(Constants.mssqlClusterLivyOpenSparkHistory, async (profile: azdata.IConnectionProfile) => {
await new OpenSparkYarnHistoryTask(appContext).execute(profile, true);
});
azdata.tasks.registerTask(Constants.mssqlClusterLivyOpenYarnHistory, async (profile: azdata.IConnectionProfile) => {
await new OpenSparkYarnHistoryTask(appContext).execute(profile, false);
});
}
function activateNotebookTask(appContext: AppContext): void {
azdata.tasks.registerTask(Constants.mssqlClusterNewNotebookTask, (profile: azdata.IConnectionProfile) => {
return saveProfileAndCreateNotebook(profile);
});
azdata.tasks.registerTask(Constants.mssqlClusterOpenNotebookTask, (profile: azdata.IConnectionProfile) => {
return handleOpenNotebookTask(profile);
});
azdata.tasks.registerTask(Constants.mssqlOpenClusterDashboard, (profile: azdata.IConnectionProfile) => {
return handleOpenClusterDashboardTask(profile, appContext);
});
}
function saveProfileAndCreateNotebook(profile: azdata.IConnectionProfile): Promise<void> {
return handleNewNotebookTask(undefined, profile);
}
function findNextUntitledEditorName(): string {
let nextVal = 0;
// Note: this will go forever if it's coded wrong, or you have inifinite Untitled notebooks!
while (true) {
let title = `Notebook-${nextVal}`;
let hasNotebookDoc = azdata.nb.notebookDocuments.findIndex(doc => doc.isUntitled && doc.fileName === title) > -1;
if (!hasNotebookDoc) {
return title;
}
nextVal++;
}
}
async function handleNewNotebookTask(oeContext?: azdata.ObjectExplorerContext, profile?: azdata.IConnectionProfile): Promise<void> {
// Ensure we get a unique ID for the notebook. For now we're using a different prefix to the built-in untitled files
// to handle this. We should look into improving this in the future
let title = findNextUntitledEditorName();
let untitledUri = vscode.Uri.parse(`untitled:${title}`);
let editor = await azdata.nb.showNotebookDocument(untitledUri, {
connectionProfile: profile,
preview: false
});
if (oeContext && oeContext.nodeInfo && oeContext.nodeInfo.nodePath) {
// Get the file path after '/HDFS'
let hdfsPath: string = oeContext.nodeInfo.nodePath.substring(oeContext.nodeInfo.nodePath.indexOf('/HDFS') + '/HDFS'.length);
if (hdfsPath.length > 0) {
let analyzeCommand = '#' + msgSampleCodeDataFrame + os.EOL + 'df = (spark.read.option("inferSchema", "true")'
+ os.EOL + '.option("header", "true")' + os.EOL + '.csv("{0}"))' + os.EOL + 'df.show(10)';
await editor.edit(editBuilder => {
editBuilder.replace(0, {
cell_type: 'code',
source: analyzeCommand.replace('{0}', hdfsPath)
});
});
}
}
}
async function handleOpenNotebookTask(profile: azdata.IConnectionProfile): Promise<void> {
let notebookFileTypeName = localize('notebookFileType', "Notebooks");
let filter: { [key: string]: string[] } = {};
filter[notebookFileTypeName] = ['ipynb'];
let uris = await vscode.window.showOpenDialog({
filters: filter,
canSelectFiles: true,
canSelectMany: false
});
if (uris && uris.length > 0) {
let fileUri = uris[0];
// Verify this is a .ipynb file since this isn't actually filtered on Mac/Linux
if (path.extname(fileUri.fsPath) !== '.ipynb') {
// in the future might want additional supported types
void vscode.window.showErrorMessage(localize('unsupportedFileType', "Only .ipynb Notebooks are supported"));
} else {
await azdata.nb.showNotebookDocument(fileUri, {
connectionProfile: profile,
preview: false
});
}
}
}
async function handleOpenClusterDashboardTask(profile: azdata.IConnectionProfile, appContext: AppContext): Promise<void> {
const serverInfo = await azdata.connection.getServerInfo(profile.id);
const controller = Utils.getClusterEndpoints(serverInfo).find(e => e.name === Endpoint.controller);
if (!controller) {
void vscode.window.showErrorMessage(localize('noController', "Could not find the controller endpoint for this instance"));
return;
}
void vscode.commands.executeCommand('bigDataClusters.command.manageController',
{
url: controller.endpoint,
auth: profile.authenticationType === 'Integrated' ? AuthType.Integrated : AuthType.Basic,
username: 'admin', // Default to admin as a best-guess, we'll prompt for re-entering credentials if that fails
password: profile.password,
rememberPassword: true
}, /*addOrUpdateController*/true);
}
// this method is called when your extension is deactivated
export function deactivate(): void {
}