Merge master

This commit is contained in:
Kevin Cunnane
2018-11-04 15:15:27 -08:00
41 changed files with 655 additions and 327 deletions

View File

@@ -2,7 +2,7 @@
"name": "agent", "name": "agent",
"displayName": "SQL Server Agent", "displayName": "SQL Server Agent",
"description": "Manage and troubleshoot SQL Server Agent jobs", "description": "Manage and troubleshoot SQL Server Agent jobs",
"version": "0.34.0", "version": "0.35.0",
"publisher": "Microsoft", "publisher": "Microsoft",
"preview": true, "preview": true,
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt", "license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt",

View File

@@ -9,6 +9,7 @@ import * as vscode from 'vscode';
import * as sqlops from 'sqlops'; import * as sqlops from 'sqlops';
import { AgentUtils } from '../agentUtils'; import { AgentUtils } from '../agentUtils';
import { IAgentDialogData, AgentDialogMode } from '../interfaces'; import { IAgentDialogData, AgentDialogMode } from '../interfaces';
import { JobData } from './jobData';
const localize = nls.loadMessageBundle(); const localize = nls.loadMessageBundle();
@@ -45,8 +46,19 @@ export class AlertData implements IAgentDialogData {
wmiEventNamespace: string; wmiEventNamespace: string;
wmiEventQuery: string; wmiEventQuery: string;
constructor(ownerUri:string, alertInfo: sqlops.AgentAlertInfo) { private viaJobDialog: boolean;
private jobModel: JobData;
constructor(
ownerUri:string,
alertInfo: sqlops.AgentAlertInfo,
jobModel?: JobData,
viaJobDialog: boolean = false
) {
this.ownerUri = ownerUri; this.ownerUri = ownerUri;
this.viaJobDialog = viaJobDialog;
this.jobModel = jobModel;
this.jobName = this.jobName ? this.jobName : this.jobModel.name;
if (alertInfo) { if (alertInfo) {
this.dialogMode = AgentDialogMode.EDIT; this.dialogMode = AgentDialogMode.EDIT;
@@ -60,7 +72,6 @@ export class AlertData implements IAgentDialogData {
this.includeEventDescription = alertInfo.includeEventDescription.toString(); this.includeEventDescription = alertInfo.includeEventDescription.toString();
this.isEnabled = alertInfo.isEnabled; this.isEnabled = alertInfo.isEnabled;
this.jobId = alertInfo.jobId; this.jobId = alertInfo.jobId;
this.jobName = alertInfo.jobName;
this.lastOccurrenceDate = alertInfo.lastOccurrenceDate; this.lastOccurrenceDate = alertInfo.lastOccurrenceDate;
this.lastResponseDate = alertInfo.lastResponseDate; this.lastResponseDate = alertInfo.lastResponseDate;
this.messageId = alertInfo.messageId; this.messageId = alertInfo.messageId;
@@ -82,10 +93,18 @@ export class AlertData implements IAgentDialogData {
public async save() { public async save() {
let agentService = await AgentUtils.getAgentService(); let agentService = await AgentUtils.getAgentService();
let result = this.dialogMode === AgentDialogMode.CREATE let result: any;
? await agentService.createAlert(this.ownerUri, this.toAgentAlertInfo()) // if it's called via the job dialog, add it to the
: await agentService.updateAlert(this.ownerUri, this.originalName, this.toAgentAlertInfo()); // job model
if (this.viaJobDialog) {
if (this.jobModel) {
Promise.resolve(this);
return;
}
} else {
// has to be a create alert
result = await agentService.createAlert(this.ownerUri, this.toAgentAlertInfo());
}
if (!result || !result.success) { if (!result || !result.success) {
vscode.window.showErrorMessage( vscode.window.showErrorMessage(
localize('alertData.saveErrorMessage', "Alert update failed '{0}'", result.errorMessage ? result.errorMessage : 'Unknown')); localize('alertData.saveErrorMessage', "Alert update failed '{0}'", result.errorMessage ? result.errorMessage : 'Unknown'));

View File

@@ -44,6 +44,7 @@ export class JobData implements IAgentDialogData {
public jobSteps: sqlops.AgentJobStepInfo[]; public jobSteps: sqlops.AgentJobStepInfo[];
public jobSchedules: sqlops.AgentJobScheduleInfo[]; public jobSchedules: sqlops.AgentJobScheduleInfo[];
public alerts: sqlops.AgentAlertInfo[]; public alerts: sqlops.AgentAlertInfo[];
public jobId: string;
constructor( constructor(
ownerUri: string, ownerUri: string,
@@ -62,6 +63,7 @@ export class JobData implements IAgentDialogData {
this.jobSteps = jobInfo.JobSteps; this.jobSteps = jobInfo.JobSteps;
this.jobSchedules = jobInfo.JobSchedules; this.jobSchedules = jobInfo.JobSchedules;
this.alerts = jobInfo.Alerts; this.alerts = jobInfo.Alerts;
this.jobId = jobInfo.jobId;
} }
} }
@@ -115,7 +117,6 @@ export class JobData implements IAgentDialogData {
let result = this.dialogMode === AgentDialogMode.CREATE let result = this.dialogMode === AgentDialogMode.CREATE
? await this._agentService.createJob(this.ownerUri, jobInfo) ? await this._agentService.createJob(this.ownerUri, jobInfo)
: await this._agentService.updateJob(this.ownerUri, this.originalName, jobInfo); : await this._agentService.updateJob(this.ownerUri, this.originalName, jobInfo);
if (!result || !result.success) { if (!result || !result.success) {
vscode.window.showErrorMessage( vscode.window.showErrorMessage(
localize('jobData.saveErrorMessage', "Job update failed '{0}'", result.errorMessage ? result.errorMessage : 'Unknown')); localize('jobData.saveErrorMessage', "Job update failed '{0}'", result.errorMessage ? result.errorMessage : 'Unknown'));
@@ -135,18 +136,6 @@ export class JobData implements IAgentDialogData {
}; };
} }
public addJobSchedule(schedule: sqlops.AgentJobScheduleInfo) {
if (this.jobSchedules) {
let existingSchedule = this.jobSchedules.find(item => item.name === schedule.name);
if (!existingSchedule) {
this.jobSchedules.push(schedule);
}
} else {
this.jobSchedules = [];
this.jobSchedules.push(schedule);
}
}
public toAgentJobInfo(): sqlops.AgentJobInfo { public toAgentJobInfo(): sqlops.AgentJobInfo {
return { return {
name: this.name, name: this.name,
@@ -177,7 +166,7 @@ export class JobData implements IAgentDialogData {
categoryType: 1, // LocalJob, hard-coding the value, corresponds to the target tab in SSMS categoryType: 1, // LocalJob, hard-coding the value, corresponds to the target tab in SSMS
lastRun: '', lastRun: '',
nextRun: '', nextRun: '',
jobId: '' jobId: this.jobId
}; };
} }
} }

View File

@@ -46,11 +46,13 @@ export class JobStepData implements IAgentDialogData {
public retryInterval: number; public retryInterval: number;
public proxyName: string; public proxyName: string;
private jobModel: JobData; private jobModel: JobData;
private viaJobDialog: boolean;
constructor(ownerUri:string, jobModel?: JobData) { constructor(ownerUri:string, jobModel?: JobData, viaJobDialog: boolean = false) {
this.ownerUri = ownerUri; this.ownerUri = ownerUri;
this.jobName = jobModel.name; this.jobName = jobModel.name;
this.jobModel = jobModel; this.jobModel = jobModel;
this.viaJobDialog = viaJobDialog;
} }
public async initialize() { public async initialize() {
@@ -59,18 +61,16 @@ export class JobStepData implements IAgentDialogData {
public async save() { public async save() {
let agentService = await AgentUtils.getAgentService(); let agentService = await AgentUtils.getAgentService();
let result: any; let result: any;
if (this.dialogMode === AgentDialogMode.CREATE) { // if it's called via the job dialog, add it to the
if (this.jobModel && this.jobModel.dialogMode === AgentDialogMode.CREATE) { // job model
// create job -> create step if (this.viaJobDialog) {
if (this.jobModel) {
Promise.resolve(this); Promise.resolve(this);
return; return;
} else {
// edit job -> create step
result = await agentService.createJobStep(this.ownerUri, JobStepData.convertToAgentJobStepInfo(this));
} }
} else if (this.jobModel && this.jobModel.dialogMode === AgentDialogMode.EDIT) { } else {
// edit job -> edit step // has to be a create step
result = await agentService.updateJobStep(this.ownerUri, this.stepName, JobStepData.convertToAgentJobStepInfo(this)); result = await agentService.createJobStep(this.ownerUri, JobStepData.convertToAgentJobStepInfo(this));
} }
if (!result || !result.success) { if (!result || !result.success) {
vscode.window.showErrorMessage( vscode.window.showErrorMessage(

View File

@@ -29,8 +29,6 @@ export class PickScheduleData implements IAgentDialogData {
} }
public async save() { public async save() {
let agentService = await AgentUtils.getAgentService();
this.selectedSchedule.jobName = this.jobName; this.selectedSchedule.jobName = this.jobName;
let result = await agentService.createJobSchedule(this.ownerUri, this.selectedSchedule);
} }
} }

View File

@@ -12,6 +12,7 @@ import { AgentUtils } from '../agentUtils';
import { AlertData } from '../data/alertData'; import { AlertData } from '../data/alertData';
import { OperatorDialog } from './operatorDialog'; import { OperatorDialog } from './operatorDialog';
import { JobDialog } from './jobDialog'; import { JobDialog } from './jobDialog';
import { JobData } from '../data/jobData';
const localize = nls.loadMessageBundle(); const localize = nls.loadMessageBundle();
@@ -148,14 +149,23 @@ export class AlertDialog extends AgentDialog<AlertData> {
private delayMinutesTextBox: sqlops.InputBoxComponent; private delayMinutesTextBox: sqlops.InputBoxComponent;
private delaySecondsTextBox: sqlops.InputBoxComponent; private delaySecondsTextBox: sqlops.InputBoxComponent;
private jobs: string[];
private databases: string[]; private databases: string[];
private jobModel: JobData;
public jobId: string;
public jobName: string;
constructor(ownerUri: string, alertInfo: sqlops.AgentAlertInfo = undefined, jobs: string[]) { constructor(
ownerUri: string,
jobModel: JobData,
alertInfo: sqlops.AgentAlertInfo = undefined,
viaJobDialog: boolean = false
) {
super(ownerUri, super(ownerUri,
new AlertData(ownerUri, alertInfo), new AlertData(ownerUri, alertInfo, jobModel, viaJobDialog),
alertInfo ? AlertDialog.EditDialogTitle : AlertDialog.CreateDialogTitle); alertInfo ? AlertDialog.EditDialogTitle : AlertDialog.CreateDialogTitle);
this.jobs = jobs; this.jobModel = jobModel;
this.jobId = this.jobId ? this.jobId : this.jobModel.jobId;
this.jobName = this.jobName ? this.jobName : this.jobModel.name;
} }
protected async initializeDialog(dialog: sqlops.window.modelviewdialog.Dialog) { protected async initializeDialog(dialog: sqlops.window.modelviewdialog.Dialog) {
@@ -512,7 +522,8 @@ export class AlertDialog extends AgentDialog<AlertData> {
protected updateModel() { protected updateModel() {
this.model.name = this.nameTextBox.value; this.model.name = this.nameTextBox.value;
this.model.isEnabled = this.enabledCheckBox.checked; this.model.isEnabled = this.enabledCheckBox.checked;
this.model.jobId = this.jobId;
this.model.jobName = this.jobName;
this.model.alertType = this.getDropdownValue(this.typeDropDown); this.model.alertType = this.getDropdownValue(this.typeDropDown);
let databaseName = this.getDropdownValue(this.databaseDropDown); let databaseName = this.getDropdownValue(this.databaseDropDown);
this.model.databaseName = (databaseName !== AlertDialog.AllDatabases) ? databaseName : undefined; this.model.databaseName = (databaseName !== AlertDialog.AllDatabases) ? databaseName : undefined;

View File

@@ -11,6 +11,7 @@ import { PickScheduleDialog } from './pickScheduleDialog';
import { AlertDialog } from './alertDialog'; import { AlertDialog } from './alertDialog';
import { AgentDialog } from './agentDialog'; import { AgentDialog } from './agentDialog';
import { AgentUtils } from '../agentUtils'; import { AgentUtils } from '../agentUtils';
import { JobStepData } from '../data/jobStepData';
const localize = nls.loadMessageBundle(); const localize = nls.loadMessageBundle();
@@ -110,11 +111,19 @@ export class JobDialog extends AgentDialog<JobData> {
private newAlertButton: sqlops.ButtonComponent; private newAlertButton: sqlops.ButtonComponent;
private isEdit: boolean = false; private isEdit: boolean = false;
// Job objects
private steps: sqlops.AgentJobStepInfo[];
private schedules: sqlops.AgentJobScheduleInfo[];
private alerts: sqlops.AgentAlertInfo[] = [];
constructor(ownerUri: string, jobInfo: sqlops.AgentJobInfo = undefined) { constructor(ownerUri: string, jobInfo: sqlops.AgentJobInfo = undefined) {
super( super(
ownerUri, ownerUri,
new JobData(ownerUri, jobInfo), new JobData(ownerUri, jobInfo),
jobInfo ? JobDialog.EditDialogTitle : JobDialog.CreateDialogTitle); jobInfo ? JobDialog.EditDialogTitle : JobDialog.CreateDialogTitle);
this.steps = this.model.jobSteps ? this.model.jobSteps : [];
this.schedules = this.model.jobSchedules ? this.model.jobSchedules : [];
this.alerts = this.model.alerts ? this.model.alerts : [];
this.isEdit = jobInfo ? true : false; this.isEdit = jobInfo ? true : false;
} }
@@ -198,12 +207,7 @@ export class JobDialog extends AgentDialog<JobData> {
private initializeStepsTab() { private initializeStepsTab() {
this.stepsTab.registerContent(async view => { this.stepsTab.registerContent(async view => {
let previewTag = view.modelBuilder.text() let data = this.steps ? this.convertStepsToData(this.steps) : [];
.withProperties({
value: 'Feature Preview'
}).component();
let steps = this.model.jobSteps ? this.model.jobSteps : [];
let data = this.convertStepsToData(steps);
this.stepsTable = view.modelBuilder.table() this.stepsTable = view.modelBuilder.table()
.withProperties({ .withProperties({
columns: [ columns: [
@@ -237,13 +241,11 @@ export class JobDialog extends AgentDialog<JobData> {
width: 80 width: 80
}).component(); }).component();
let stepDialog = new JobStepDialog(this.model.ownerUri, '' , this.model); let stepDialog = new JobStepDialog(this.model.ownerUri, '' , this.model, null, true);
stepDialog.onSuccess((step) => { stepDialog.onSuccess((step) => {
if (!this.model.jobSteps) { let stepInfo = JobStepData.convertToAgentJobStepInfo(step);
this.model.jobSteps = []; this.steps.push(stepInfo);
} this.stepsTable.data = this.convertStepsToData(this.steps);
this.model.jobSteps.push(step);
this.stepsTable.data = this.convertStepsToData(this.model.jobSteps);
}); });
this.newStepButton.onDidClick((e)=>{ this.newStepButton.onDidClick((e)=>{
if (this.nameTextBox.value && this.nameTextBox.value.length > 0) { if (this.nameTextBox.value && this.nameTextBox.value.length > 0) {
@@ -277,7 +279,7 @@ export class JobDialog extends AgentDialog<JobData> {
this.deleteStepButton.enabled = true; this.deleteStepButton.enabled = true;
this.editStepButton.enabled = true; this.editStepButton.enabled = true;
this.editStepButton.onDidClick(() => { this.editStepButton.onDidClick(() => {
let stepDialog = new JobStepDialog(this.model.ownerUri, '' , this.model, stepData); let stepDialog = new JobStepDialog(this.model.ownerUri, '' , this.model, stepData, true);
stepDialog.openDialog(); stepDialog.openDialog();
}); });
@@ -287,7 +289,6 @@ export class JobDialog extends AgentDialog<JobData> {
agentService.deleteJobStep(this.ownerUri, stepData).then((result) => { agentService.deleteJobStep(this.ownerUri, stepData).then((result) => {
if (result && result.success) { if (result && result.success) {
delete steps[rowNumber]; delete steps[rowNumber];
this.model.jobSteps = steps;
let data = this.convertStepsToData(steps); let data = this.convertStepsToData(steps);
this.stepsTable.data = data; this.stepsTable.data = data;
} }
@@ -299,10 +300,6 @@ export class JobDialog extends AgentDialog<JobData> {
let formModel = view.modelBuilder.formContainer() let formModel = view.modelBuilder.formContainer()
.withFormItems([{ .withFormItems([{
component: previewTag,
title: ''
},
{
component: this.stepsTable, component: this.stepsTable,
title: this.JobStepsTopLabelString, title: this.JobStepsTopLabelString,
actions: [this.moveStepUpButton, this.moveStepDownButton, this.newStepButton, this.editStepButton, this.deleteStepButton] actions: [this.moveStepUpButton, this.moveStepDownButton, this.newStepButton, this.editStepButton, this.deleteStepButton]
@@ -313,10 +310,6 @@ export class JobDialog extends AgentDialog<JobData> {
private initializeAlertsTab() { private initializeAlertsTab() {
this.alertsTab.registerContent(async view => { this.alertsTab.registerContent(async view => {
let previewTag = view.modelBuilder.text()
.withProperties({
value: 'Feature Preview'
}).component();
let alerts = this.model.alerts ? this.model.alerts : []; let alerts = this.model.alerts ? this.model.alerts : [];
let data = this.convertAlertsToData(alerts); let data = this.convertAlertsToData(alerts);
this.alertsTable = view.modelBuilder.table() this.alertsTable = view.modelBuilder.table()
@@ -327,7 +320,7 @@ export class JobDialog extends AgentDialog<JobData> {
this.AlertTypeLabelString this.AlertTypeLabelString
], ],
data: data, data: data,
height: 430, height: 750,
width: 400 width: 400
}).component(); }).component();
@@ -336,18 +329,24 @@ export class JobDialog extends AgentDialog<JobData> {
width: 80 width: 80
}).component(); }).component();
this.newAlertButton.onDidClick((e)=>{ let alertDialog = new AlertDialog(this.model.ownerUri, this.model, null, true);
let alertDialog = new AlertDialog(this.model.ownerUri, null, []); alertDialog.onSuccess((alert) => {
alertDialog.onSuccess((dialogModel) => { let alertInfo = alert.toAgentAlertInfo();
this.alerts.push(alertInfo);
this.alertsTable.data = this.convertAlertsToData(this.alerts);
}); });
this.newAlertButton.onDidClick(()=>{
if (this.nameTextBox.value && this.nameTextBox.value.length > 0) {
alertDialog.jobId = this.model.jobId;
alertDialog.jobName = this.model.name ? this.model.name : this.nameTextBox.value;
alertDialog.openDialog(); alertDialog.openDialog();
} else {
this.dialog.message = { text: this.BlankJobNameErrorText };
}
}); });
let formModel = view.modelBuilder.formContainer() let formModel = view.modelBuilder.formContainer()
.withFormItems([{ .withFormItems([{
component: previewTag,
title: ''
}, {
component: this.alertsTable, component: this.alertsTable,
title: this.AlertsTopLabelString, title: this.AlertsTopLabelString,
actions: [this.newAlertButton] actions: [this.newAlertButton]
@@ -380,8 +379,11 @@ export class JobDialog extends AgentDialog<JobData> {
pickScheduleDialog.onSuccess((dialogModel) => { pickScheduleDialog.onSuccess((dialogModel) => {
let selectedSchedule = dialogModel.selectedSchedule; let selectedSchedule = dialogModel.selectedSchedule;
if (selectedSchedule) { if (selectedSchedule) {
selectedSchedule.jobName = this.model.name; let existingSchedule = this.schedules.find(item => item.name === selectedSchedule.name);
this.model.addJobSchedule(selectedSchedule); if (!existingSchedule) {
selectedSchedule.jobName = this.model.name ? this.model.name : this.nameTextBox.value;
this.schedules.push(selectedSchedule);
}
this.populateScheduleTable(); this.populateScheduleTable();
} }
}); });
@@ -402,8 +404,7 @@ export class JobDialog extends AgentDialog<JobData> {
} }
private populateScheduleTable() { private populateScheduleTable() {
let schedules = this.model.jobSchedules ? this.model.jobSchedules : []; let data = this.convertSchedulesToData(this.schedules);
let data = this.convertSchedulesToData(schedules);
if (data.length > 0) { if (data.length > 0) {
this.schedulesTable.data = data; this.schedulesTable.data = data;
this.schedulesTable.height = 750; this.schedulesTable.height = 750;
@@ -566,5 +567,17 @@ export class JobDialog extends AgentDialog<JobData> {
this.model.pageLevel = this.getActualConditionValue(this.pagerCheckBox, this.pagerConditionDropdown); this.model.pageLevel = this.getActualConditionValue(this.pagerCheckBox, this.pagerConditionDropdown);
this.model.eventLogLevel = this.getActualConditionValue(this.eventLogCheckBox, this.eventLogConditionDropdown); this.model.eventLogLevel = this.getActualConditionValue(this.eventLogCheckBox, this.eventLogConditionDropdown);
this.model.deleteLevel = this.getActualConditionValue(this.deleteJobCheckBox, this.deleteJobConditionDropdown); this.model.deleteLevel = this.getActualConditionValue(this.deleteJobCheckBox, this.deleteJobConditionDropdown);
if (!this.model.jobSteps) {
this.model.jobSteps = [];
}
this.model.jobSteps = this.steps;
if (!this.model.jobSchedules) {
this.model.jobSchedules = [];
}
this.model.jobSchedules = this.schedules;
if (!this.model.alerts) {
this.model.alerts = [];
}
this.model.alerts = this.alerts;
} }
} }

View File

@@ -118,9 +118,10 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
server: string, server: string,
jobModel: JobData, jobModel: JobData,
jobStepInfo?: sqlops.AgentJobStepInfo, jobStepInfo?: sqlops.AgentJobStepInfo,
viaJobDialog: boolean = false
) { ) {
super(ownerUri, super(ownerUri,
jobStepInfo ? JobStepData.convertToJobStepData(jobStepInfo, jobModel) : new JobStepData(ownerUri, jobModel), jobStepInfo ? JobStepData.convertToJobStepData(jobStepInfo, jobModel) : new JobStepData(ownerUri, jobModel, viaJobDialog),
jobStepInfo ? JobStepDialog.EditDialogTitle : JobStepDialog.NewDialogTitle); jobStepInfo ? JobStepDialog.EditDialogTitle : JobStepDialog.NewDialogTitle);
this.stepId = jobStepInfo ? this.stepId = jobStepInfo ?
jobStepInfo.id : jobModel.jobSteps ? jobStepInfo.id : jobModel.jobSteps ?

View File

@@ -14,6 +14,7 @@ import { ProxyDialog } from './dialogs/proxyDialog';
import { JobStepDialog } from './dialogs/jobStepDialog'; import { JobStepDialog } from './dialogs/jobStepDialog';
import { PickScheduleDialog } from './dialogs/pickScheduleDialog'; import { PickScheduleDialog } from './dialogs/pickScheduleDialog';
import { JobData } from './data/jobData'; import { JobData } from './data/jobData';
import { AgentUtils } from './agentUtils';
const localize = nls.loadMessageBundle(); const localize = nls.loadMessageBundle();
@@ -41,18 +42,24 @@ export class MainController {
let dialog = new JobDialog(ownerUri, jobInfo); let dialog = new JobDialog(ownerUri, jobInfo);
dialog.openDialog(); dialog.openDialog();
}); });
vscode.commands.registerCommand('agent.openNewStepDialog', (ownerUri: string, server: string, jobData: JobData, jobStepInfo: sqlops.AgentJobStepInfo) => { vscode.commands.registerCommand('agent.openNewStepDialog', (ownerUri: string, server: string, jobInfo: sqlops.AgentJobInfo, jobStepInfo: sqlops.AgentJobStepInfo) => {
let dialog = new JobStepDialog(ownerUri, server, jobData, jobStepInfo); AgentUtils.getAgentService().then((agentService) => {
let jobData: JobData = new JobData(ownerUri, jobInfo, agentService);
let dialog = new JobStepDialog(ownerUri, server, jobData, jobStepInfo, false);
dialog.openDialog(); dialog.openDialog();
}); });
});
vscode.commands.registerCommand('agent.openPickScheduleDialog', (ownerUri: string, jobName: string) => { vscode.commands.registerCommand('agent.openPickScheduleDialog', (ownerUri: string, jobName: string) => {
let dialog = new PickScheduleDialog(ownerUri, jobName); let dialog = new PickScheduleDialog(ownerUri, jobName);
dialog.showDialog(); dialog.showDialog();
}); });
vscode.commands.registerCommand('agent.openAlertDialog', (ownerUri: string, alertInfo: sqlops.AgentAlertInfo, jobs: string[]) => { vscode.commands.registerCommand('agent.openAlertDialog', (ownerUri: string, jobInfo: sqlops.AgentJobInfo, alertInfo: sqlops.AgentAlertInfo) => {
let dialog = new AlertDialog(ownerUri, alertInfo, jobs); AgentUtils.getAgentService().then((agentService) => {
let jobData: JobData = new JobData(ownerUri, jobInfo, agentService);
let dialog = new AlertDialog(ownerUri, jobData, alertInfo, false);
dialog.openDialog(); dialog.openDialog();
}); });
});
vscode.commands.registerCommand('agent.openOperatorDialog', (ownerUri: string, operatorInfo: sqlops.AgentOperatorInfo) => { vscode.commands.registerCommand('agent.openOperatorDialog', (ownerUri: string, operatorInfo: sqlops.AgentOperatorInfo) => {
let dialog = new OperatorDialog(ownerUri, operatorInfo); let dialog = new OperatorDialog(ownerUri, operatorInfo);
dialog.openDialog(); dialog.openDialog();

View File

@@ -2,7 +2,7 @@
"name": "import", "name": "import",
"displayName": "SQL Server Import", "displayName": "SQL Server Import",
"description": "SQL Server Import for Azure Data Studio supports importing CSV or JSON files into SQL Server.", "description": "SQL Server Import for Azure Data Studio supports importing CSV or JSON files into SQL Server.",
"version": "0.3.0", "version": "0.4.0",
"publisher": "Microsoft", "publisher": "Microsoft",
"preview": true, "preview": true,
"engines": { "engines": {
@@ -42,33 +42,6 @@
"mac": "ctrl+i" "mac": "ctrl+i"
} }
], ],
"dashboard.tabs": [
{
"id": "flat-file-import",
"title": "Flat File Import",
"description": "The flat file importer.",
"container": {
"flat-file-import-container": {}
}
}
],
"dashboard.containers": [
{
"id": "flat-file-import-container",
"container": {
"widgets-container": [
{
"name": "Tasks",
"widget": {
"tasks-widget": [
"flatFileImport.start"
]
}
}
]
}
}
],
"menus": { "menus": {
"objectExplorer/item/context": [ "objectExplorer/item/context": [
{ {

View File

@@ -31,7 +31,7 @@ export class FlatFileWizard {
public async start(p: any, ...args: any[]) { public async start(p: any, ...args: any[]) {
let model = <ImportDataModel>{}; let model = <ImportDataModel>{};
let profile = <sqlops.IConnectionProfile>p.connectionProfile; let profile = p ? <sqlops.IConnectionProfile>p.connectionProfile : null;
if (profile) { if (profile) {
model.serverId = profile.id; model.serverId = profile.id;
model.database = profile.databaseName; model.database = profile.databaseName;

View File

@@ -42,18 +42,18 @@
"Create a new Table": { "Create a new Table": {
"prefix": "sqlCreateTable", "prefix": "sqlCreateTable",
"body": [ "body": [
"-- Create a new table called '[${1:TableName}]' in schema '[${2:SchemaName}]' in database '[${3:DatabaseName}]'", "-- Create a new table called '[${1:TableName}]' in schema '[${2:dbo}]'",
"-- Drop the table if it already exists", "-- Drop the table if it already exists",
"IF OBJECT_ID('[${3:DatabaseName}].[${2:SchemaName}].[${1:TableName}]', 'U') IS NOT NULL", "IF OBJECT_ID('[${2:dbo}].[${1:TableName}]', 'U') IS NOT NULL",
"DROP TABLE [${3:DatabaseName}].[${2:SchemaName}].[${1:TableName}]", "DROP TABLE [${2:dbo}].[${1:TableName}]",
"GO", "GO",
"-- Create the table in the specified database and schema", "-- Create the table in the specified schema",
"CREATE TABLE [${3:DatabaseName}].[${2:SchemaName}].[${1:TableName}]", "CREATE TABLE [${2:dbo}].[${1:TableName}]",
"(", "(",
"\t[${4:ColumnName}]Id INT NOT NULL PRIMARY KEY, -- Primary Key column", "\t[${3:Id}] INT NOT NULL PRIMARY KEY, -- Primary Key column",
"\t[${5:ColumnName1}] [NVARCHAR](50) NOT NULL,", "\t[${4:ColumnName2}] ${5:NVARCHAR(50)} NOT NULL,",
"\t[${6:ColumnName2}] [NVARCHAR](50) NOT NULL", "\t[${6:ColumnName3}] ${7:NVARCHAR(50)} NOT NULL",
"\t-- Specify more columns here", "\t$0-- Specify more columns here",
");", ");",
"GO" "GO"
], ],
@@ -64,10 +64,10 @@
"Drop a Table": { "Drop a Table": {
"prefix": "sqlDropTable", "prefix": "sqlDropTable",
"body": [ "body": [
"-- Drop a table called '${3:TableName}' in schema '${2:SchemaName}' in Database '${1:DatabaseName}'", "-- Drop a table called '${1:TableName}' in schema '${2:dbo}'",
"-- Drop the table if it already exists", "-- Drop the table if it already exists",
"IF OBJECT_ID('[${1:DatabaseName}].[${2:SchemaName}].[${3:TableName}]', 'U') IS NOT NULL", "IF OBJECT_ID('[${2:dbo}].[${1:TableName}]', 'U') IS NOT NULL",
"DROP TABLE [${1:DatabaseName}].[${2:SchemaName}].[${3:TableName}]", "DROP TABLE [${2:dbo}].[${1:TableName}]",
"GO" "GO"
], ],
"description": "Drop a Table" "description": "Drop a Table"
@@ -76,9 +76,9 @@
"Add a new column to a Table": { "Add a new column to a Table": {
"prefix": "sqlAddColumn", "prefix": "sqlAddColumn",
"body": [ "body": [
"-- Add a new column '[${1:NewColumnName}]' to table '[${2:TableName}]' in schema '[${3:SchemaName}]' in database '[${4:DatabaseName}]'", "-- Add a new column '[${1:NewColumnName}]' to table '[${2:TableName}]' in schema '[${3:dbo}]'",
"ALTER TABLE [${4:DatabaseName}].[${3:SchemaName}].[${2:TableName}]", "ALTER TABLE [${3:dbo}].[${2:TableName}]",
"\tADD [${1:NewColumnName}] /*new_column_name*/ ${5:int} /*new_column_datatype*/ ${6:NULL} /*new_column_nullability*/", "\tADD [${1:NewColumnName}] /*new_column_name*/ ${4:int} /*new_column_datatype*/ ${5:NULL} /*new_column_nullability*/",
"GO" "GO"
], ],
"description": "Add a new column to a Table" "description": "Add a new column to a Table"
@@ -87,8 +87,8 @@
"Drop a column from a Table": { "Drop a column from a Table": {
"prefix": "sqlDropColumn", "prefix": "sqlDropColumn",
"body": [ "body": [
"-- Drop '[${1:ColumnName}]' from table '[${2:TableName}]' in schema '[${3:SchemaName}]' in database '[${4:DatabaseName}]'", "-- Drop '[${1:ColumnName}]' from table '[${2:TableName}]' in schema '[${3:dbo}]'",
"ALTER TABLE [${4:DatabaseName}].[${3:SchemaName}].[${2:TableName}]", "ALTER TABLE [${3:dbo}].[${2:TableName}]",
"\tDROP COLUMN [${1:ColumnName}]", "\tDROP COLUMN [${1:ColumnName}]",
"GO" "GO"
], ],
@@ -98,9 +98,9 @@
"Select rows from a Table or a View": { "Select rows from a Table or a View": {
"prefix": "sqlSelect", "prefix": "sqlSelect",
"body": [ "body": [
"-- Select rows from a Table or View '[${1:TableOrViewName}]' in schema '[${2:SchemaName}]' in database '[${3:DatabaseName}]'", "-- Select rows from a Table or View '[${1:TableOrViewName}]' in schema '[${2:dbo}]'",
"SELECT * FROM [${3:DatabaseName}].[${2:SchemaName}].[${1:TableOrViewName}]", "SELECT * FROM [${2:dbo}].[${1:TableOrViewName}]",
"WHERE ${4:/* add search conditions here */}", "WHERE ${3:/* add search conditions here */}",
"GO" "GO"
], ],
"description": "Select rows from a Table or a View" "description": "Select rows from a Table or a View"
@@ -109,17 +109,17 @@
"Insert rows into a Table": { "Insert rows into a Table": {
"prefix": "sqlInsertRows", "prefix": "sqlInsertRows",
"body": [ "body": [
"-- Insert rows into table '${1:TableName}' in schema '[${2:SchemaName}]' in database '[${3:DatabaseName}]'", "-- Insert rows into table '${1:TableName}' in schema '[${2:dbo}]'",
"INSERT INTO [${3:DatabaseName}].[${2:SchemaName}].[${1:TableName}]", "INSERT INTO [${2:dbo}].[${1:TableName}]",
"( -- Columns to insert data into", "( -- Columns to insert data into",
" ${4:[ColumnName1], [ColumnName2], [ColumnName3]}", " ${3:[ColumnName1], [ColumnName2], [ColumnName3]}",
")", ")",
"VALUES", "VALUES",
"( -- First row: values for the columns in the list above", "( -- First row: values for the columns in the list above",
" ${5:ColumnValue1, ColumnValue2, ColumnValue3}", " ${4:ColumnValue1, ColumnValue2, ColumnValue3}",
"),", "),",
"( -- Second row: values for the columns in the list above", "( -- Second row: values for the columns in the list above",
" ${6:ColumnValue1, ColumnValue2, ColumnValue3}", " ${5:ColumnValue1, ColumnValue2, ColumnValue3}",
")", ")",
"-- Add more rows here", "-- Add more rows here",
"GO" "GO"
@@ -130,9 +130,9 @@
"Delete rows from a Table": { "Delete rows from a Table": {
"prefix": "sqlDeleteRows", "prefix": "sqlDeleteRows",
"body": [ "body": [
"-- Delete rows from table '[${1:TableName}]' in schema '[${2:SchemaName}]' in database '[${3:DatabaseName}]'", "-- Delete rows from table '[${1:TableName}]' in schema '[${2:dbo}]'",
"DELETE FROM [${3:DatabaseName}].[${2:SchemaName}].[${1:TableName}]", "DELETE FROM [${2:dbo}].[${1:TableName}]",
"WHERE ${4:/* add search conditions here */}", "WHERE ${3:/* add search conditions here */}",
"GO" "GO"
], ],
"description": "Delete rows from a Table" "description": "Delete rows from a Table"
@@ -141,13 +141,13 @@
"Update rows in a Table": { "Update rows in a Table": {
"prefix": "sqlUpdateRows", "prefix": "sqlUpdateRows",
"body": [ "body": [
"-- Update rows in table '[${1:TableName}]' in schema '[${2:SchemaName}]' in database '[${3:DatabaseName}]'", "-- Update rows in table '[${1:TableName}]' in schema '[${2:dbo}]'",
"UPDATE [${3:DatabaseName}].[${2:SchemaName}].[${1:TableName}]", "UPDATE [${2:dbo}].[${1:TableName}]",
"SET", "SET",
"\t[${4:ColumnName1}] = ${5:ColumnValue1},", "\t[${3:ColumnName1}] = ${4:ColumnValue1},",
"\t[${6:ColumnName2}] = ${7:ColumnValue2}", "\t[${5:ColumnName2}] = ${6:ColumnValue2}",
"\t-- Add more columns and values here", "\t-- Add more columns and values here",
"WHERE ${8:/* add search conditions here */}", "WHERE ${7:/* add search conditions here */}",
"GO" "GO"
], ],
"description": "Update rows in a Table" "description": "Update rows in a Table"
@@ -156,27 +156,27 @@
"Create a stored procedure": { "Create a stored procedure": {
"prefix": "sqlCreateStoredProc", "prefix": "sqlCreateStoredProc",
"body": [ "body": [
"-- Create a new stored procedure called '${1:StoredProcedureName}' in schema '${2:SchemaName}'", "-- Create a new stored procedure called '${1:StoredProcedureName}' in schema '${2:dbo}'",
"-- Drop the stored procedure if it already exists", "-- Drop the stored procedure if it already exists",
"IF EXISTS (", "IF EXISTS (",
"SELECT *", "SELECT *",
"\tFROM INFORMATION_SCHEMA.ROUTINES", "\tFROM INFORMATION_SCHEMA.ROUTINES",
"WHERE SPECIFIC_SCHEMA = N'${2:SchemaName}'", "WHERE SPECIFIC_SCHEMA = N'${2:dbo}'",
"\tAND SPECIFIC_NAME = N'${1:StoredProcedureName}'", "\tAND SPECIFIC_NAME = N'${1:StoredProcedureName}'",
")", ")",
"DROP PROCEDURE ${2:SchemaName}.${1:StoredProcedureName}", "DROP PROCEDURE ${2:dbo}.${1:StoredProcedureName}",
"GO", "GO",
"-- Create the stored procedure in the specified schema", "-- Create the stored procedure in the specified schema",
"CREATE PROCEDURE ${2:SchemaName}.${1:StoredProcedureName}", "CREATE PROCEDURE ${2:dbo}.${1:StoredProcedureName}",
"\t$3@param1 /*parameter name*/ int /*datatype_for_param1*/ = 0, /*default_value_for_param1*/", "\t$3@param1 /*parameter name*/ $4int /*datatype_for_param1*/ = 0, /*default_value_for_param1*/",
"\t$4@param2 /*parameter name*/ int /*datatype_for_param1*/ = 0 /*default_value_for_param2*/", "\t$5@param2 /*parameter name*/ $6int /*datatype_for_param1*/ = 0 /*default_value_for_param2*/",
"-- add more stored procedure parameters here", "-- add more stored procedure parameters here",
"AS", "AS",
"\t-- body of the stored procedure", "\t-- body of the stored procedure",
"\tSELECT @param1, @param2", "\tSELECT @param1, @param2",
"GO", "GO",
"-- example to execute the stored procedure we just created", "-- example to execute the stored procedure we just created",
"EXECUTE ${2:SchemaName}.${1:StoredProcedureName} 1 /*value_for_param1*/, 2 /*value_for_param2*/", "EXECUTE ${2:dbo}.${1:StoredProcedureName} 1 /*value_for_param1*/, 2 /*value_for_param2*/",
"GO" "GO"
], ],
"description": "Create a stored procedure" "description": "Create a stored procedure"
@@ -185,14 +185,14 @@
"Drop a stored procedure": { "Drop a stored procedure": {
"prefix": "sqlDropStoredProc", "prefix": "sqlDropStoredProc",
"body": [ "body": [
"-- Drop the stored procedure called '${1:StoredProcedureName}' in schema '${2:SchemaName}'", "-- Drop the stored procedure called '${1:StoredProcedureName}' in schema '${2:dbo}'",
"IF EXISTS (", "IF EXISTS (",
"SELECT *", "SELECT *",
"\tFROM INFORMATION_SCHEMA.ROUTINES", "\tFROM INFORMATION_SCHEMA.ROUTINES",
"WHERE SPECIFIC_SCHEMA = N'${2:SchemaName}'", "WHERE SPECIFIC_SCHEMA = N'${2:dbo}'",
"\tAND SPECIFIC_NAME = N'${1:StoredProcedureName}'", "\tAND SPECIFIC_NAME = N'${1:StoredProcedureName}'",
")", ")",
"DROP PROCEDURE ${2:SchemaName}.${1:StoredProcedureName}", "DROP PROCEDURE ${2:dbo}.${1:StoredProcedureName}",
"GO" "GO"
], ],
"description": "Drop a stored procedure" "description": "Drop a stored procedure"
@@ -241,7 +241,7 @@
"Declare a cursor": { "Declare a cursor": {
"prefix": "sqlCursor", "prefix": "sqlCursor",
"body": [ "body": [
"-- Declare a cursor for a Table or a View '${1:TableOrViewName}' in schema '${2:SchemaName}'", "-- Declare a cursor for a Table or a View '${1:TableOrViewName}' in schema '${2:dbo}'",
"DECLARE @ColumnName1 NVARCHAR(50), @ColumnName2 NVARCHAR(50)", "DECLARE @ColumnName1 NVARCHAR(50), @ColumnName2 NVARCHAR(50)",
"", "",
"DECLARE db_cursor CURSOR FOR", "DECLARE db_cursor CURSOR FOR",
@@ -304,8 +304,8 @@
"prefix": "sqlCreateIndex", "prefix": "sqlCreateIndex",
"body": [ "body": [
"-- Create a nonclustered index with or without a unique constraint", "-- Create a nonclustered index with or without a unique constraint",
"-- Or create a clustered index on table '[${1:TableName}]' in schema '[${2:SchemaName}]' in database '[${3:DatabaseName}]'", "-- Or create a clustered index on table '[${1:TableName}]' in schema '[${2:dbo}]' in database '[${3:DatabaseName}]'",
"CREATE ${5:/*UNIQUE or CLUSTERED*/} INDEX IX_${4:IndexName} ON [${3:DatabaseName}].[${2:SchemaName}].[${1:TableName}] ([${6:ColumnName1}] DESC /*Change sort order as needed*/", "CREATE ${5:/*UNIQUE or CLUSTERED*/} INDEX IX_${4:IndexName} ON [${3:DatabaseName}].[${2:dbo}].[${1:TableName}] ([${6:ColumnName1}] DESC /*Change sort order as needed*/",
"GO" "GO"
], ],
"description": "Create a new Index" "description": "Create a new Index"
@@ -319,13 +319,13 @@
"IF OBJECT_ID('tempDB..#${1:TableName}', 'U') IS NOT NULL", "IF OBJECT_ID('tempDB..#${1:TableName}', 'U') IS NOT NULL",
"DROP TABLE #${1:TableName}", "DROP TABLE #${1:TableName}",
"GO", "GO",
"-- Create the temporary table from a physical table called '${4:TableName}' in schema '${3:SchemaName}' in database '${2:DatabaseName}'", "-- Create the temporary table from a physical table called '${4:TableName}' in schema '${3:dbo}' in database '${2:DatabaseName}'",
"SELECT *", "SELECT *",
"INTO #${1:TableName}", "INTO #${1:TableName}",
"FROM [${2:DatabaseName}].[${3:[SchemaName}].[${4:TableName}]", "FROM [${2:DatabaseName}].[${3:[dbo}].[${4:TableName}]",
"WHERE ${5:/* add search conditions here */}" "WHERE ${5:/* add search conditions here */}"
], ],
"description": "Create a new Temporary Table" "description": "Create a new Temporary Table"
}, }
} }

View File

@@ -1,6 +1,6 @@
{ {
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}", "downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
"version": "1.5.0-alpha.48", "version": "1.5.0-alpha.52",
"downloadFileNames": { "downloadFileNames": {
"Windows_86": "win-x86-netcoreapp2.2.zip", "Windows_86": "win-x86-netcoreapp2.2.zip",
"Windows_64": "win-x64-netcoreapp2.2.zip", "Windows_64": "win-x64-netcoreapp2.2.zip",

View File

@@ -2,7 +2,7 @@
"name": "profiler", "name": "profiler",
"displayName": "SQL Server Profiler", "displayName": "SQL Server Profiler",
"description": "SQL Server Profiler for Azure Data Studio", "description": "SQL Server Profiler for Azure Data Studio",
"version": "0.2.0", "version": "0.3.0",
"publisher": "Microsoft", "publisher": "Microsoft",
"preview": true, "preview": true,
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt", "license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt",

View File

@@ -6,17 +6,17 @@
// base // base
"foreground": "#fffffe", "foreground": "#fffffe",
"focusBorder": "#0E639C", "focusBorder": "#0078d7",
"selection.background": "#3062d6", "selection.background": "#3062d6",
//text colors //text colors
"textLinkForeground": "#30B4FF", "textLinkForeground": "#30b4ff",
"textLinkActiveForeground": "#30B4FF", "textLinkActiveForeground": "#30b4ff",
//Button control //Button control
"button.background": "#00BCF2", "button.background": "#0078d7cc",
"button.foreground": "#212121", "button.foreground": "#ffffff",
"button.hoverBackground": "#0099BC", "button.hoverBackground": "#0078d7",
// TODO add support for these // TODO add support for these
// "button.secondaryBackground": "#c8c8c8", // "button.secondaryBackground": "#c8c8c8",
@@ -25,6 +25,9 @@
// "button.disabledBackground": "#444444" , // "button.disabledBackground": "#444444" ,
// "button.disabledForeground": "#888888" , // "button.disabledForeground": "#888888" ,
//Checkbox
"checkbox.disabled.foreground": "#888888",
//Dropdown Control //Dropdown Control
"dropdown.background": "#212121", "dropdown.background": "#212121",
"dropdown.foreground": "#fffffe", "dropdown.foreground": "#fffffe",
@@ -35,24 +38,24 @@
"input.border": "#888888", "input.border": "#888888",
"input.disabled.background": "#444444", "input.disabled.background": "#444444",
"input.disabled.foreground": "#888888", "input.disabled.foreground": "#888888",
"inputOption.activeBorder": "#007ACC", "inputOption.activeBorder": "#0078d7",
"input.placeholderForeground": "#888888", "input.placeholderForeground": "#888888",
"inputValidation.errorBackground": "#D02E00", "inputValidation.errorBackground": "#b62e00",
"inputValidation.errorBorder": "#D02E00", "inputValidation.errorBorder": "#b62e00",
//List and trees //List and trees
"list.activeSelectionBackground": "#3062d6", "list.activeSelectionBackground": "#3062d6",
"list.hoverBackground": "#444444", "list.hoverBackground": "#444444",
"pickerGroup.border": "#00BCF2", "pickerGroup.border": "#0078d7",
"activityBar.background": "#444444", "activityBar.background": "#444444",
"sideBar.background": "#333333", "sideBar.background": "#333333",
"sideBarTitle.foreground": "#BBBBBB", "sideBarTitle.foreground": "#bbbbbb",
"input.placeholderForeground": "#A6A6A6", "input.placeholderForeground": "#a6a6a6",
"editorGroupHeader.tabsBackground": "#444444", "editorGroupHeader.tabsBackground": "#444444",
"editor.background": "#212121", "editor.background": "#212121",
"editor.foreground": "#ffffff", "editor.foreground": "#ffffff",
"editorWidget.background": "#444444", "editorWidget.background": "#444444",
"editorLink.activeForeground": "#30B4FF", "editorLink.activeForeground": "#30b4ff",
"editorGroup.border": "#333333", "editorGroup.border": "#333333",
"editorGroup.background": "#212121", "editorGroup.background": "#212121",
"editorIndentGuide.activeBackground": "#707070", "editorIndentGuide.activeBackground": "#707070",

View File

@@ -5,18 +5,18 @@
"colors": { "colors": {
// base // base
"foreground": "#4a4a4a", "foreground": "#4a4a4a",
"focusBorder": "#00BCF2", "focusBorder": "#0078d7",
"selection.background": "#C9D0D9", "selection.background": "#c9d0d9",
"widget.shadow": "#666666", "widget.shadow": "#666666",
// text colors // text colors
"textLinkForeground": "#3062D6", "textLinkForeground": "#3062d6",
"textLinkActiveForeground": "#3062D6", "textLinkActiveForeground": "#3062d6",
//Button control //Button control
"button.background": "#00BCF2", "button.background": "#0078d7cc",
"button.foreground": "#212121", "button.foreground": "#ffffff",
"button.hoverBackground": "#0099BC", "button.hoverBackground": "#0078d7",
// TODO add support for these // TODO add support for these
// "button.secondaryBackground": "#c8c8c8", // "button.secondaryBackground": "#c8c8c8",
@@ -25,35 +25,38 @@
// "button.disabledBackground": "#eaeaea", // "button.disabledBackground": "#eaeaea",
// "button.disabledForeground": "#888888", // "button.disabledForeground": "#888888",
//Checkbox
"checkbox.disabled.foreground": "#888888",
//Dropdown Control //Dropdown Control
"dropdown.background": "#fffffe", "dropdown.background": "#ffffff",
"dropdown.foreground": "#4a4a4a", "dropdown.foreground": "#4a4a4a",
"dropdown.border": "#C8C8C8", "dropdown.border": "#c8c8c8",
//badge //badge
"badge.background": "#777777", "badge.background": "#777777",
"badge.foreground": "#ffffff", "badge.foreground": "#ffffff",
//Input Control //Input Control
"input.background": "#fffffe", "input.background": "#ffffff",
"input.border": "#c8c8c8", "input.border": "#c8c8c8",
"input.disabled.background": "#dcdcdc", "input.disabled.background": "#dcdcdc",
"input.disabled.foreground": "#888888", "input.disabled.foreground": "#888888",
"inputOption.activeBorder": "#666666", "inputOption.activeBorder": "#666666",
"input.placeholderForeground": "#767676", "input.placeholderForeground": "#767676",
"inputValidation.errorBackground": "#ffeaea", "inputValidation.errorBackground": "#ffeaea",
"inputValidation.errorBorder": "#f1897f", "inputValidation.errorBorder": "#b62e00",
//List and tree //List and tree
"list.activeSelectionBackground": "#3062d6", "list.activeSelectionBackground": "#3062d6",
"list.hoverBackground": "#dcdcdc", "list.hoverBackground": "#dcdcdc",
"pickerGroup.border": "#00BCF2", "pickerGroup.border": "#0078d7",
// Workbench: Activity Bar // Workbench: Activity Bar
"activityBar.background": "#212121", "activityBar.background": "#212121",
// Workbench: Side Bar // Workbench: Side Bar
"sideBar.background": "#EAEAEA", "sideBar.background": "#eaeaea",
"editorGroupHeader.tabsBackground": "#f4f4f4", "editorGroupHeader.tabsBackground": "#f4f4f4",
"editor.background": "#fffffe", "editor.background": "#fffffe",
"editor.foreground": "#212121", "editor.foreground": "#212121",
@@ -64,15 +67,15 @@
"editorIndentGuide.activeBackground": "#939393", "editorIndentGuide.activeBackground": "#939393",
// Workbench: Tabs // Workbench: Tabs
"tab.activeBackground": "#FFFFFE", "tab.activeBackground": "#ffffff",
"tab.activeForeground": "#4A4A4A", "tab.activeForeground": "#4a4a4a",
"tab.inactiveBackground": "#f4f4f4", "tab.inactiveBackground": "#f4f4f4",
"tab.inactiveForeground": "#707070", "tab.inactiveForeground": "#707070",
"tab.border": "#EAEAEA", "tab.border": "#eaeaea",
"tab.unfocusedInactiveForeground": "#888888", "tab.unfocusedInactiveForeground": "#888888",
"tab.unfocusedActiveForeground": "#212121", "tab.unfocusedActiveForeground": "#212121",
"panel.background": "#FFFFFE", "panel.background": "#ffffff",
"panel.border": "#C8C8C8", "panel.border": "#c8c8c8",
"panelTitle.activeForeground": "#212121", "panelTitle.activeForeground": "#212121",
"panelTitle.inactiveForeground": "#757575" "panelTitle.inactiveForeground": "#757575"
}, },

View File

@@ -1,6 +1,6 @@
{ {
"name": "azuredatastudio", "name": "azuredatastudio",
"version": "1.2.3", "version": "1.2.4",
"distro": "8c3e97e3425cc9814496472ab73e076de2ba99ee", "distro": "8c3e97e3425cc9814496472ab73e076de2ba99ee",
"author": { "author": {
"name": "Microsoft Corporation" "name": "Microsoft Corporation"

View File

@@ -3,6 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { Color } from 'vs/base/common/color';
import { Event, Emitter } from 'vs/base/common/event'; import { Event, Emitter } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes'; import { KeyCode } from 'vs/base/common/keyCodes';
import { Widget } from 'vs/base/browser/ui/widget'; import { Widget } from 'vs/base/browser/ui/widget';
@@ -15,9 +16,14 @@ export interface ICheckboxOptions {
ariaLabel?: string; ariaLabel?: string;
} }
export interface ICheckboxStyles {
disabledCheckboxForeground?: Color;
}
export class Checkbox extends Widget { export class Checkbox extends Widget {
private _el: HTMLInputElement; private _el: HTMLInputElement;
private _label: HTMLSpanElement; private _label: HTMLSpanElement;
private disabledCheckboxForeground: Color;
private _onChange = new Emitter<boolean>(); private _onChange = new Emitter<boolean>();
public readonly onChange: Event<boolean> = this._onChange.event; public readonly onChange: Event<boolean> = this._onChange.event;
@@ -65,6 +71,7 @@ export class Checkbox extends Widget {
public set enabled(val: boolean) { public set enabled(val: boolean) {
this._el.disabled = !val; this._el.disabled = !val;
this.updateStyle();
} }
public get enabled(): boolean { public get enabled(): boolean {
@@ -90,4 +97,13 @@ export class Checkbox extends Widget {
public enable(): void { public enable(): void {
this.enabled = true; this.enabled = true;
} }
public style(styles: ICheckboxStyles): void {
this.disabledCheckboxForeground = styles.disabledCheckboxForeground;
this.updateStyle();
}
private updateStyle(): void {
this._label.style.color = !this.enabled && this.disabledCheckboxForeground ? this.disabledCheckboxForeground.toString() : 'inherit';
}
} }

View File

@@ -66,14 +66,11 @@
} }
.monaco-shell .modal.flyout-dialog .modal-body, .monaco-shell .modal.flyout-dialog .modal-body,
.monaco-shell .modal.flyout-dialog .angular-modal-body { .monaco-shell .modal.flyout-dialog .angular-modal-body,
margin-bottom: auto;
height: 100%;
}
/* Style for body and footer in modal dialog. This should be applied to dialog created with angular component. */ /* Style for body and footer in modal dialog. This should be applied to dialog created with angular component. */
.monaco-shell .modal.flyout-dialog .modal-body-and-footer { .monaco-shell .modal.flyout-dialog .modal-body-and-footer {
height: 100%; flex: 1 1;
overflow: hidden;
} }
/* modl body content style(excluding dialogErrorMessage section) for angulr component dialog */ /* modl body content style(excluding dialogErrorMessage section) for angulr component dialog */
@@ -85,6 +82,8 @@
.modal.flyout-dialog .angular-form { .modal.flyout-dialog .angular-form {
height: 100%; height: 100%;
display: flex;
flex-direction: column;
} }
.modal.flyout-dialog .dialog-label { .modal.flyout-dialog .dialog-label {
@@ -105,10 +104,6 @@
padding-left: 4px; padding-left: 4px;
} }
.modal.flyout-dialog .modal-body {
overflow-y: auto;
}
.vs-dark.monaco-shell .modal.flyout-dialog .input { .vs-dark.monaco-shell .modal.flyout-dialog .input {
background-color: #3C3C3C; background-color: #3C3C3C;
} }
@@ -187,7 +182,6 @@
.modal.flyout-dialog .dialog-message-header { .modal.flyout-dialog .dialog-message-header {
overflow: hidden; overflow: hidden;
overflow-y: hidden;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
} }

View File

@@ -27,7 +27,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
export const MODAL_SHOWING_KEY = 'modalShowing'; export const MODAL_SHOWING_KEY = 'modalShowing';
export const MODAL_SHOWING_CONTEXT = new RawContextKey<Array<string>>(MODAL_SHOWING_KEY, []); export const MODAL_SHOWING_CONTEXT = new RawContextKey<Array<string>>(MODAL_SHOWING_KEY, []);
const INFO_ALT_TEXT = localize('infoAltText', 'Infomation'); const INFO_ALT_TEXT = localize('infoAltText', 'Information');
const WARNING_ALT_TEXT = localize('warningAltText', 'Warning'); const WARNING_ALT_TEXT = localize('warningAltText', 'Warning');
const ERROR_ALT_TEXT = localize('errorAltText', 'Error'); const ERROR_ALT_TEXT = localize('errorAltText', 'Error');
const SHOW_DETAILS_TEXT = localize('showMessageDetails', 'Show Details'); const SHOW_DETAILS_TEXT = localize('showMessageDetails', 'Show Details');

View File

@@ -89,10 +89,6 @@
-moz-transition-property: width; -moz-transition-property: width;
} }
.hc-black .split-view-view .action-label {
background: none;
}
.hc-black .split-view-view > .header .action-label:before { .hc-black .split-view-view > .header .action-label:before {
top: 4px !important; top: 4px !important;
} }

View File

@@ -12,6 +12,7 @@ export const tableHeaderForeground = registerColor('table.headerForeground', { d
export const disabledInputBackground = registerColor('input.disabled.background', { dark: '#444444', light: '#dcdcdc', hc: Color.black }, nls.localize('disabledInputBoxBackground', "Disabled Input box background.")); export const disabledInputBackground = registerColor('input.disabled.background', { dark: '#444444', light: '#dcdcdc', hc: Color.black }, nls.localize('disabledInputBoxBackground', "Disabled Input box background."));
export const disabledInputForeground = registerColor('input.disabled.foreground', { dark: '#888888', light: '#888888', hc: foreground }, nls.localize('disabledInputBoxForeground', "Disabled Input box foreground.")); export const disabledInputForeground = registerColor('input.disabled.foreground', { dark: '#888888', light: '#888888', hc: foreground }, nls.localize('disabledInputBoxForeground', "Disabled Input box foreground."));
export const buttonFocusOutline = registerColor('button.focusOutline', { dark: '#eaeaea', light: '#666666', hc: null }, nls.localize('buttonFocusOutline', "Button outline color when focused.")); export const buttonFocusOutline = registerColor('button.focusOutline', { dark: '#eaeaea', light: '#666666', hc: null }, nls.localize('buttonFocusOutline', "Button outline color when focused."));
export const disabledCheckboxForeground = registerColor('checkbox.disabled.foreground', { dark: '#888888', light: '#888888', hc: Color.black }, nls.localize('disabledCheckboxforeground', "Disabled checkbox foreground."));
export const listFocusAndSelectionBackground = registerColor('list.focusAndSelectionBackground', { dark: '#2c3295', light: '#2c3295', hc: null }, nls.localize('listFocusAndSelectionBackground', "List/Table background color for the selected and focus item when the list/table is active")); export const listFocusAndSelectionBackground = registerColor('list.focusAndSelectionBackground', { dark: '#2c3295', light: '#2c3295', hc: null }, nls.localize('listFocusAndSelectionBackground', "List/Table background color for the selected and focus item when the list/table is active"));

View File

@@ -255,3 +255,10 @@ export function attachButtonStyler(widget: IThemable, themeService: IThemeServic
buttonFocusOutline: (style && style.buttonFocusOutline) || sqlcolors.buttonFocusOutline buttonFocusOutline: (style && style.buttonFocusOutline) || sqlcolors.buttonFocusOutline
}, widget); }, widget);
} }
export function attachCheckboxStyler(widget: IThemable, themeService: IThemeService, style?: { disabledCheckboxForeground?: cr.ColorIdentifier })
: IDisposable {
return attachStyler(themeService, {
disabledCheckboxForeground: (style && style.disabledCheckboxForeground) || sqlcolors.disabledCheckboxForeground
}, widget);
}

View File

@@ -0,0 +1,17 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export interface ICommandLineProcessing {
_serviceBrand: any;
/**
* Interprets the various Azure Data Studio-specific command line switches and
* performs the requisite tasks such as connecting to a server
*/
processCommandLine() : void;
}
export const ICommandLineProcessing = createDecorator<ICommandLineProcessing>('commandLineService');

View File

@@ -0,0 +1,75 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
import { ICommandLineProcessing } from 'sql/parts/commandLine/common/commandLine';
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import * as Constants from 'sql/parts/connection/common/constants';
import { IQueryEditorService } from 'sql/parts/query/common/queryEditorService';
import * as platform from 'vs/platform/registry/common/platform';
import { ConnectionProviderProperties, IConnectionProviderRegistry, Extensions as ConnectionProviderExtensions } from 'sql/workbench/parts/connection/common/connectionProviderExtension';
import * as TaskUtilities from 'sql/workbench/common/taskUtilities';
import { IObjectExplorerService } from 'sql/parts/objectExplorer/common/objectExplorerService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
export class CommandLineService implements ICommandLineProcessing {
private _connectionProfile: ConnectionProfile;
private _showConnectionDialog: boolean;
constructor(
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
@ICapabilitiesService private _capabilitiesService: ICapabilitiesService,
@IEnvironmentService private _environmentService: IEnvironmentService,
@IQueryEditorService private _queryEditorService: IQueryEditorService,
@IObjectExplorerService private _objectExplorerService: IObjectExplorerService,
@IEditorService private _editorService: IEditorService,
) {
let profile = null;
if (this._environmentService && this._environmentService.args.server) {
profile = new ConnectionProfile(_capabilitiesService, null);
// We want connection store to use any matching password it finds
profile.savePassword = true;
profile.providerName = Constants.mssqlProviderName;
profile.serverName = _environmentService.args.server;
profile.databaseName = _environmentService.args.database ? _environmentService.args.database : '';
profile.userName = _environmentService.args.user ? _environmentService.args.user : '';
profile.authenticationType = _environmentService.args.integrated ? 'Integrated' : 'SqlLogin';
profile.connectionName = '';
profile.setOptionValue('applicationName', Constants.applicationName);
profile.setOptionValue('databaseDisplayName', profile.databaseName);
profile.setOptionValue('groupId', profile.groupId);
}
this._connectionProfile = profile;
const registry = platform.Registry.as<IConnectionProviderRegistry>(ConnectionProviderExtensions.ConnectionProviderContributions);
let sqlProvider = registry.getProperties(Constants.mssqlProviderName);
// We can't connect to object explorer until the MSSQL connection provider is registered
if (sqlProvider) {
this.processCommandLine();
} else {
registry.onNewProvider(e => {
if (e.id === Constants.mssqlProviderName) {
this.processCommandLine();
}
});
}
}
public _serviceBrand: any;
public processCommandLine(): void {
if (!this._connectionProfile && !this._connectionManagementService.hasRegisteredServers()) {
// prompt the user for a new connection on startup if no profiles are registered
this._connectionManagementService.showConnectionDialog();
} else if (this._connectionProfile) {
this._connectionManagementService.connectIfNotConnected(this._connectionProfile, 'connection')
.then(result => TaskUtilities.newQuery(this._connectionProfile,
this._connectionManagementService,
this._queryEditorService,
this._objectExplorerService,
this._editorService))
.catch(() => { });
}
}
}

View File

@@ -77,7 +77,6 @@ export class ConnectionManagementService extends Disposable implements IConnecti
private _onConnectRequestSent = new Emitter<void>(); private _onConnectRequestSent = new Emitter<void>();
private _onConnectionChanged = new Emitter<IConnectionParams>(); private _onConnectionChanged = new Emitter<IConnectionParams>();
private _onLanguageFlavorChanged = new Emitter<sqlops.DidChangeLanguageFlavorParams>(); private _onLanguageFlavorChanged = new Emitter<sqlops.DidChangeLanguageFlavorParams>();
private _connectionGlobalStatus = new ConnectionGlobalStatus(this._statusBarService); private _connectionGlobalStatus = new ConnectionGlobalStatus(this._statusBarService);
private _configurationEditService: ConfigurationEditingService; private _configurationEditService: ConfigurationEditingService;
@@ -124,16 +123,6 @@ export class ConnectionManagementService extends Disposable implements IConnecti
100 /* High Priority */ 100 /* High Priority */
)); ));
if (_capabilitiesService && Object.keys(_capabilitiesService.providers).length > 0 && !this.hasRegisteredServers()) {
// prompt the user for a new connection on startup if no profiles are registered
this.showConnectionDialog();
} else if (_capabilitiesService && !this.hasRegisteredServers()) {
_capabilitiesService.onCapabilitiesRegistered(e => {
// prompt the user for a new connection on startup if no profiles are registered
this.showConnectionDialog();
});
}
const registry = platform.Registry.as<IConnectionProviderRegistry>(ConnectionProviderExtensions.ConnectionProviderContributions); const registry = platform.Registry.as<IConnectionProviderRegistry>(ConnectionProviderExtensions.ConnectionProviderContributions);
let providerRegistration = (p: { id: string, properties: ConnectionProviderProperties }) => { let providerRegistration = (p: { id: string, properties: ConnectionProviderProperties }) => {
@@ -282,29 +271,30 @@ export class ConnectionManagementService extends Disposable implements IConnecti
* @param options to use after the connection is complete * @param options to use after the connection is complete
*/ */
private tryConnect(connection: IConnectionProfile, owner: IConnectableInput, options?: IConnectionCompletionOptions): Promise<IConnectionResult> { private tryConnect(connection: IConnectionProfile, owner: IConnectableInput, options?: IConnectionCompletionOptions): Promise<IConnectionResult> {
let self = this;
return new Promise<IConnectionResult>((resolve, reject) => { return new Promise<IConnectionResult>((resolve, reject) => {
// Load the password if it's not already loaded // Load the password if it's not already loaded
this._connectionStore.addSavedPassword(connection).then(result => { self._connectionStore.addSavedPassword(connection).then(result => {
let newConnection = result.profile; let newConnection = result.profile;
let foundPassword = result.savedCred; let foundPassword = result.savedCred;
// If there is no password, try to load it from an existing connection // If there is no password, try to load it from an existing connection
if (!foundPassword && this._connectionStore.isPasswordRequired(newConnection)) { if (!foundPassword && self._connectionStore.isPasswordRequired(newConnection)) {
let existingConnection = this._connectionStatusManager.findConnectionProfile(connection); let existingConnection = self._connectionStatusManager.findConnectionProfile(connection);
if (existingConnection && existingConnection.connectionProfile) { if (existingConnection && existingConnection.connectionProfile) {
newConnection.password = existingConnection.connectionProfile.password; newConnection.password = existingConnection.connectionProfile.password;
foundPassword = true; foundPassword = true;
} }
} }
// If the password is required and still not loaded show the dialog // If the password is required and still not loaded show the dialog
if (!foundPassword && this._connectionStore.isPasswordRequired(newConnection) && !newConnection.password) { if (!foundPassword && self._connectionStore.isPasswordRequired(newConnection) && !newConnection.password) {
resolve(this.showConnectionDialogOnError(connection, owner, { connected: false, errorMessage: undefined, callStack: undefined, errorCode: undefined }, options)); resolve(self.showConnectionDialogOnError(connection, owner, { connected: false, errorMessage: undefined, callStack: undefined, errorCode: undefined }, options));
} else { } else {
// Try to connect // Try to connect
this.connectWithOptions(newConnection, owner.uri, options, owner).then(connectionResult => { self.connectWithOptions(newConnection, owner.uri, options, owner).then(connectionResult => {
if (!connectionResult.connected && !connectionResult.errorHandled) { if (!connectionResult.connected && !connectionResult.errorHandled) {
// If connection fails show the dialog // If connection fails show the dialog
resolve(this.showConnectionDialogOnError(connection, owner, connectionResult, options)); resolve(self.showConnectionDialogOnError(connection, owner, connectionResult, options));
} else { } else {
//Resolve with the connection result //Resolve with the connection result
resolve(connectionResult); resolve(connectionResult);
@@ -390,7 +380,14 @@ export class ConnectionManagementService extends Disposable implements IConnecti
if (this._connectionStatusManager.isConnected(ownerUri)) { if (this._connectionStatusManager.isConnected(ownerUri)) {
resolve(this._connectionStatusManager.getOriginalOwnerUri(ownerUri)); resolve(this._connectionStatusManager.getOriginalOwnerUri(ownerUri));
} else { } else {
this.connect(connection, ownerUri).then(connectionResult => { const options: IConnectionCompletionOptions = {
saveTheConnection: false,
showConnectionDialogOnError: true,
showDashboard: purpose === 'dashboard',
params: undefined,
showFirewallRuleOnError: true,
};
this.connect(connection, ownerUri, options).then(connectionResult => {
if (connectionResult && connectionResult.connected) { if (connectionResult && connectionResult.connected) {
resolve(this._connectionStatusManager.getOriginalOwnerUri(ownerUri)); resolve(this._connectionStatusManager.getOriginalOwnerUri(ownerUri));
} else { } else {

View File

@@ -17,7 +17,7 @@ import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
import { ConnectionOptionSpecialType } from 'sql/workbench/api/common/sqlExtHostTypes'; import { ConnectionOptionSpecialType } from 'sql/workbench/api/common/sqlExtHostTypes';
import * as Constants from 'sql/parts/connection/common/constants'; import * as Constants from 'sql/parts/connection/common/constants';
import { ConnectionProfileGroup, IConnectionProfileGroup } from 'sql/parts/connection/common/connectionProfileGroup'; import { ConnectionProfileGroup, IConnectionProfileGroup } from 'sql/parts/connection/common/connectionProfileGroup';
import { attachInputBoxStyler, attachButtonStyler, attachEditableDropdownStyler } from 'sql/common/theme/styler'; import { attachButtonStyler, attachCheckboxStyler, attachEditableDropdownStyler, attachInputBoxStyler } from 'sql/common/theme/styler';
import { Dropdown } from 'sql/base/browser/ui/editableDropdown/dropdown'; import { Dropdown } from 'sql/base/browser/ui/editableDropdown/dropdown';
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement'; import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService'; import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
@@ -274,6 +274,7 @@ export class ConnectionWidget {
this._toDispose.push(attachInputBoxStyler(this._passwordInputBox, this._themeService)); this._toDispose.push(attachInputBoxStyler(this._passwordInputBox, this._themeService));
this._toDispose.push(styler.attachSelectBoxStyler(this._serverGroupSelectBox, this._themeService)); this._toDispose.push(styler.attachSelectBoxStyler(this._serverGroupSelectBox, this._themeService));
this._toDispose.push(attachButtonStyler(this._advancedButton, this._themeService)); this._toDispose.push(attachButtonStyler(this._advancedButton, this._themeService));
this._toDispose.push(attachCheckboxStyler(this._rememberPasswordCheckBox, this._themeService));
if (this._authTypeSelectBox) { if (this._authTypeSelectBox) {
// Theme styler // Theme styler

View File

@@ -14,7 +14,7 @@ import { ModalFooterStyle } from 'sql/base/browser/ui/modal/modal';
import { CategoryView } from 'sql/base/browser/ui/modal/optionsDialog'; import { CategoryView } from 'sql/base/browser/ui/modal/optionsDialog';
import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox'; import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox';
import { SplitView } from 'sql/base/browser/ui/splitview/splitview'; import { SplitView } from 'sql/base/browser/ui/splitview/splitview';
import { attachButtonStyler, attachListBoxStyler, attachInputBoxStyler, attachSelectBoxStyler } from 'sql/common/theme/styler'; import { attachButtonStyler, attachListBoxStyler, attachInputBoxStyler, attachSelectBoxStyler, attachCheckboxStyler } from 'sql/common/theme/styler';
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces'; import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
import * as BackupConstants from 'sql/parts/disasterRecovery/backup/constants'; import * as BackupConstants from 'sql/parts/disasterRecovery/backup/constants';
import { IBackupService, IBackupUiService, TaskExecutionMode } from 'sql/parts/disasterRecovery/backup/common/backupService'; import { IBackupService, IBackupUiService, TaskExecutionMode } from 'sql/parts/disasterRecovery/backup/common/backupService';
@@ -523,6 +523,11 @@ export class BackupComponent {
this._toDispose.push(attachInputBoxStyler(this.mediaNameBox, this.themeService)); this._toDispose.push(attachInputBoxStyler(this.mediaNameBox, this.themeService));
this._toDispose.push(attachInputBoxStyler(this.mediaDescriptionBox, this.themeService)); this._toDispose.push(attachInputBoxStyler(this.mediaDescriptionBox, this.themeService));
this._toDispose.push(attachInputBoxStyler(this.backupRetainDaysBox, this.themeService)); this._toDispose.push(attachInputBoxStyler(this.backupRetainDaysBox, this.themeService));
this._toDispose.push(attachCheckboxStyler(this.copyOnlyCheckBox, this.themeService));
this._toDispose.push(attachCheckboxStyler(this.encryptCheckBox, this.themeService));
this._toDispose.push(attachCheckboxStyler(this.verifyCheckBox, this.themeService));
this._toDispose.push(attachCheckboxStyler(this.checksumCheckBox, this.themeService));
this._toDispose.push(attachCheckboxStyler(this.continueOnErrorCheckBox, this.themeService));
this._toDispose.push(this.backupTypeSelectBox.onDidSelect(selected => this.onBackupTypeChanged())); this._toDispose.push(this.backupTypeSelectBox.onDidSelect(selected => this.onBackupTypeChanged()));
this.addButtonClickHandler(this.addPathButton, () => this.onAddClick()); this.addButtonClickHandler(this.addPathButton, () => this.onAddClick());

View File

@@ -17,7 +17,7 @@
} }
.backup-dialog { .backup-dialog {
height: calc(100% - 15px) height: 100%
} }
.backup-dialog .advanced-main-header { .backup-dialog .advanced-main-header {

View File

@@ -33,7 +33,7 @@ import { Table } from 'sql/base/browser/ui/table/table';
import { TableDataView } from 'sql/base/browser/ui/table/tableDataView'; import { TableDataView } from 'sql/base/browser/ui/table/tableDataView';
import * as DialogHelper from 'sql/base/browser/ui/modal/dialogHelper'; import * as DialogHelper from 'sql/base/browser/ui/modal/dialogHelper';
import { Modal } from 'sql/base/browser/ui/modal/modal'; import { Modal } from 'sql/base/browser/ui/modal/modal';
import { attachButtonStyler, attachModalDialogStyler, attachTableStyler, attachInputBoxStyler, attachSelectBoxStyler, attachEditableDropdownStyler } from 'sql/common/theme/styler'; import { attachButtonStyler, attachModalDialogStyler, attachTableStyler, attachInputBoxStyler, attachSelectBoxStyler, attachEditableDropdownStyler, attachCheckboxStyler } from 'sql/common/theme/styler';
import * as TelemetryKeys from 'sql/common/telemetryKeys'; import * as TelemetryKeys from 'sql/common/telemetryKeys';
import * as BackupConstants from 'sql/parts/disasterRecovery/backup/constants'; import * as BackupConstants from 'sql/parts/disasterRecovery/backup/constants';
import { RestoreViewModel, RestoreOptionParam, SouceDatabaseNamesParam } from 'sql/parts/disasterRecovery/restore/restoreViewModel'; import { RestoreViewModel, RestoreOptionParam, SouceDatabaseNamesParam } from 'sql/parts/disasterRecovery/restore/restoreViewModel';
@@ -532,6 +532,7 @@ export class RestoreDialog extends Modal {
ariaLabel: label ariaLabel: label
}); });
}); });
this._register(attachCheckboxStyler(checkbox, this._themeService));
return checkbox; return checkbox;
} }

View File

@@ -1,8 +1,7 @@
div.qp-node { div.qp-node {
background-color: #FFFFCC;
margin: 2px; margin: 2px;
padding: 2px; padding: 2px;
border: 1px solid black; border: 1px solid;
} }
div.qp-statement-header { div.qp-statement-header {
margin: 2px; margin: 2px;
@@ -33,8 +32,7 @@ div[class|='qp-icon'] {
.qp-tt { .qp-tt {
top: 4em; top: 4em;
left: 2em; left: 2em;
border: 1px solid black; border: 1px solid;
background-color: #FFFFEE;
padding: 2px; padding: 2px;
width: 30em; width: 30em;
} }
@@ -56,7 +54,7 @@ div[class|='qp-icon'] {
.qp-tt td, .qp-tt td,
.qp-tt th { .qp-tt th {
font-size: 11px; font-size: 11px;
border-bottom: solid 1px Black; border-bottom: solid 1px;
padding: 1px; padding: 1px;
} }
@@ -204,8 +202,6 @@ div.qp-node:hover .qp-tt {
.qp-root { .qp-root {
display: table; display: table;
position: relative; position: relative;
background-color: #fff;
color: #000;
} }
.qp-root svg { .qp-root svg {

View File

@@ -219,14 +219,10 @@ export class NewStepAction extends Action {
public run(context: JobHistoryComponent): TPromise<boolean> { public run(context: JobHistoryComponent): TPromise<boolean> {
let ownerUri = context.ownerUri; let ownerUri = context.ownerUri;
let jobName = context.agentJobInfo.name;
let server = context.serverName; let server = context.serverName;
let stepId = 0; let jobInfo = context.agentJobInfo;
if (context.agentJobHistoryInfo && context.agentJobHistoryInfo.steps) {
stepId = context.agentJobHistoryInfo.steps.length + 1;
}
return new TPromise<boolean>((resolve, reject) => { return new TPromise<boolean>((resolve, reject) => {
resolve(this._commandService.executeCommand('agent.openNewStepDialog', ownerUri, jobName, server, stepId)); resolve(this._commandService.executeCommand('agent.openNewStepDialog', ownerUri, server, jobInfo , null));
}); });
} }
} }

View File

@@ -923,33 +923,17 @@ export class JobsViewComponent extends JobManagementView implements OnInit {
let steps = this.jobSteps[jobId]; let steps = this.jobSteps[jobId];
job[0].JobSteps = steps; job[0].JobSteps = steps;
} }
let jobHistories = this.jobHistories[job[0].jobId];
let schedules: sqlops.AgentJobScheduleInfo[] = this.jobSchedules[job[0].jobId];
let alerts: sqlops.AgentAlertInfo[] = this.jobAlerts[job[0].jobId];
if (jobHistories && jobHistories[jobHistories.length-1]) {
// add schedules // add schedules
if (schedules && schedules.length > 0) { if (this.jobSchedules && this.jobSchedules[jobId]) {
if (!job[0].JobSchedules) { let schedules = this.jobSchedules[jobId];
job[0].JobSchedules = []; job[0].JobSchedules = schedules;
}
if (job[0].JobSchedules.length !== schedules.length) {
job[0].JobSchedules = [];
schedules.forEach(schedule => {
job[0].JobSchedules.push(schedule);
});
}
} }
// add alerts // add alerts
if (!job[0].Alerts) { if (this.jobAlerts && this.jobAlerts[jobId]) {
job[0].Alerts = []; let alerts = this.jobAlerts[jobId];
} job[0].Alerts = alerts;
if (job[0].Alerts.length !== alerts.length) {
job[0].Alerts = [];
alerts.forEach(alert => {
job[0].Alerts.push(alert);
});
}
} }
return job && job.length > 0 ? job[0] : undefined; return job && job.length > 0 ? job[0] : undefined;
} }

View File

@@ -14,6 +14,8 @@ import { ComponentBase } from 'sql/parts/modelComponents/componentBase';
import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/parts/modelComponents/interfaces'; import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/parts/modelComponents/interfaces';
import { Checkbox, ICheckboxOptions } from 'sql/base/browser/ui/checkbox/checkbox'; import { Checkbox, ICheckboxOptions } from 'sql/base/browser/ui/checkbox/checkbox';
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service'; import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
import { attachCheckboxStyler } from 'sql/common/theme/styler';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
@Component({ @Component({
selector: 'modelview-checkbox', selector: 'modelview-checkbox',
@@ -30,7 +32,8 @@ export default class CheckBoxComponent extends ComponentBase implements ICompone
constructor( constructor(
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface, @Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef, @Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef) { @Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
@Inject(forwardRef(() => ElementRef)) el: ElementRef,) {
super(changeRef, el); super(changeRef, el);
} }
@@ -55,6 +58,7 @@ export default class CheckBoxComponent extends ComponentBase implements ICompone
args: e args: e
}); });
})); }));
this._register(attachCheckboxStyler(this._input, this.themeService));
} }
} }

View File

@@ -326,7 +326,7 @@ export class ChartView extends Disposable implements IPanelView {
this.optionDisposables.push(attachInputBoxStyler(numberInput, this._themeService)); this.optionDisposables.push(attachInputBoxStyler(numberInput, this._themeService));
break; break;
case ControlType.dateInput: case ControlType.dateInput:
let dateInput = new InputBox(optionContainer, this._contextViewService, { type: 'date' }); let dateInput = new InputBox(optionContainer, this._contextViewService, { type: 'datetime-local' });
dateInput.value = value || ''; dateInput.value = value || '';
dateInput.onDidChange(e => { dateInput.onDidChange(e => {
if (this.options[option.configEntry] !== e) { if (this.options[option.configEntry] !== e) {

View File

@@ -19,7 +19,7 @@ import { ChartType, DataDirection, LegendPosition, DataType, IPointDataSet, cust
const noneLineGraphs = [ChartType.Doughnut, ChartType.Pie]; const noneLineGraphs = [ChartType.Doughnut, ChartType.Pie];
const timeSeriesScales = { const timeSeriesScales: ChartJs.ChartOptions = {
scales: { scales: {
xAxes: [{ xAxes: [{
type: 'time', type: 'time',
@@ -64,7 +64,7 @@ export class Graph implements IInsight {
this._theme = e; this._theme = e;
this.data = this._data; this.data = this._data;
}); });
this._options = mixin(options, defaultOptions, false); this.options = mixin(options, defaultOptions, false);
let canvasContainer = document.createElement('div'); let canvasContainer = document.createElement('div');
canvasContainer.style.width = '100%'; canvasContainer.style.width = '100%';
@@ -89,9 +89,12 @@ export class Graph implements IInsight {
} }
public set data(data: IInsightData) { public set data(data: IInsightData) {
if (!data) {
return;
}
this._data = data; this._data = data;
let chartData: Array<ChartJs.ChartDataSets>;
let labels: Array<string>; let labels: Array<string>;
let chartData: Array<ChartJs.ChartDataSets>;
if (this.options.dataDirection === DataDirection.Horizontal) { if (this.options.dataDirection === DataDirection.Horizontal) {
if (this.options.labelFirstColumn) { if (this.options.labelFirstColumn) {
@@ -158,19 +161,19 @@ export class Graph implements IInsight {
if (this.chartjs) { if (this.chartjs) {
this.chartjs.data.datasets = chartData; this.chartjs.data.datasets = chartData;
this.chartjs.config.type = this.options.type; this.chartjs.config.type = this.options.type;
this.chartjs.data.labels = labels; // we don't want to include lables for timeSeries
this.chartjs.data.labels = this.originalType === 'timeSeries' ? [] : labels;
this.chartjs.options = this.transformOptions(this.options); this.chartjs.options = this.transformOptions(this.options);
this.chartjs.update(0); this.chartjs.update(0);
} else { } else {
this.chartjs = new ChartJs(this.canvas.getContext('2d'), { this.chartjs = new ChartJs(this.canvas.getContext('2d'), {
data: { data: {
labels: labels, // we don't want to include lables for timeSeries
labels: this.originalType === 'timeSeries' ? [] : labels,
datasets: chartData datasets: chartData
}, },
type: this.options.type, type: this.options.type,
options: { options: this.transformOptions(this.options)
maintainAspectRatio: false
}
}); });
} }
} }
@@ -197,15 +200,21 @@ export class Graph implements IInsight {
display: options.xAxisLabel ? true : false display: options.xAxisLabel ? true : false
}, },
ticks: { ticks: {
fontColor: foreground, fontColor: foreground
max: options.xAxisMax,
min: options.xAxisMin
}, },
gridLines: { gridLines: {
color: gridLines color: gridLines
} }
}]; }];
if (options.xAxisMax) {
retval.scales = mixin(retval.scales, { xAxes: [{ ticks: { max: options.xAxisMax } }] }, true, customMixin);
}
if (options.xAxisMin) {
retval.scales = mixin(retval.scales, { xAxes: [{ ticks: { min: options.xAxisMin } }] }, true, customMixin);
}
retval.scales.yAxes = [{ retval.scales.yAxes = [{
scaleLabel: { scaleLabel: {
fontColor: foreground, fontColor: foreground,
@@ -213,22 +222,27 @@ export class Graph implements IInsight {
display: options.yAxisLabel ? true : false display: options.yAxisLabel ? true : false
}, },
ticks: { ticks: {
fontColor: foreground, fontColor: foreground
max: options.yAxisMax,
min: options.yAxisMin
}, },
gridLines: { gridLines: {
color: gridLines color: gridLines
} }
}]; }];
if (options.yAxisMax) {
retval.scales = mixin(retval.scales, { yAxes: [{ ticks: { max: options.yAxisMax } }] }, true, customMixin);
}
if (options.yAxisMin) {
retval.scales = mixin(retval.scales, { yAxes: [{ ticks: { min: options.yAxisMin } }] }, true, customMixin);
}
if (this.originalType === ChartType.TimeSeries) { if (this.originalType === ChartType.TimeSeries) {
retval = mixin(retval, timeSeriesScales, true, customMixin); retval = mixin(retval, timeSeriesScales, true, customMixin);
if (options.xAxisMax) { if (options.xAxisMax) {
retval = mixin(retval, { retval = mixin(retval, {
scales: { scales: {
xAxes: [{ xAxes: [{
type: 'time',
time: { time: {
max: options.xAxisMax max: options.xAxisMax
} }
@@ -241,7 +255,6 @@ export class Graph implements IInsight {
retval = mixin(retval, { retval = mixin(retval, {
scales: { scales: {
xAxes: [{ xAxes: [{
type: 'time',
time: { time: {
min: options.xAxisMin min: options.xAxisMin
} }

View File

@@ -93,6 +93,10 @@ export class QueryPlan {
QP.showPlan(this.container, this._xml, { QP.showPlan(this.container, this._xml, {
jsTooltips: false jsTooltips: false
}); });
(<any>this.container.querySelectorAll('div.qp-tt')).forEach(toolTip=>{
toolTip.classList.add('monaco-editor');
toolTip.classList.add('monaco-editor-hover');
});
} }
public get xml(): string { public get xml(): string {

View File

@@ -0,0 +1,176 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as Constants from 'sql/parts/connection/common/constants';
import * as Utils from 'sql/parts/connection/common/utils';
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
import * as sqlops from 'sqlops';
import { TPromise } from 'vs/base/common/winjs.base';
import * as assert from 'assert';
import * as TypeMoq from 'typemoq';
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
import { CommandLineService } from 'sql/parts/commandLine/common/commandLineService';
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
import { CapabilitiesService, ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
import { CapabilitiesTestService } from 'sqltest/stubs/capabilitiesTestService';
import { QueryEditorService } from 'sql/parts/query/services/queryEditorService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ObjectExplorerService } from 'sql/parts/objectExplorer/common/objectExplorerService';
import {
IConnectionManagementService, IConnectionDialogService, INewConnectionParams,
ConnectionType, IConnectableInput, IConnectionCompletionOptions, IConnectionCallbacks,
IConnectionParams, IConnectionResult, IServerGroupController, IServerGroupDialogCallbacks,
RunQueryOnConnectionMode
} from 'sql/parts/connection/common/connectionManagement';
import { ConnectionStore } from 'sql/parts/connection/common/connectionStore';
import { TestConnectionManagementService } from 'sqltest/stubs/connectionManagementService.test';
class TestParsedArgs implements ParsedArgs{
[arg: string]: any;
_: string[];
aad?: boolean;
add?: boolean;
database?:string;
debugBrkPluginHost?: string;
debugBrkSearch?: string;
debugId?: string;
debugPluginHost?: string;
debugSearch?: string;
diff?: boolean;
'disable-crash-reporter'?: string;
'disable-extension'?: string | string[];
'disable-extensions'?: boolean;
'disable-restore-windows'?: boolean;
'disable-telemetry'?: boolean;
'disable-updates'?: string;
'driver'?: string;
'enable-proposed-api'?: string | string[];
'export-default-configuration'?: string;
'extensions-dir'?: string;
extensionDevelopmentPath?: string;
extensionTestsPath?: string;
'file-chmod'?: boolean;
'file-write'?: boolean;
'folder-uri'?: string | string[];
goto?: boolean;
help?: boolean;
'install-extension'?: string | string[];
'install-source'?: string;
integrated?: boolean;
'list-extensions'?: boolean;
locale?: string;
log?: string;
logExtensionHostCommunication?: boolean;
'max-memory'?: number;
'new-window'?: boolean;
'open-url'?: boolean;
performance?: boolean;
'prof-append-timers'?: string;
'prof-startup'?: string;
'prof-startup-prefix'?: string;
'reuse-window'?: boolean;
server?: string;
'show-versions'?: boolean;
'skip-add-to-recently-opened'?: boolean;
'skip-getting-started'?: boolean;
'skip-release-notes'?: boolean;
status?: boolean;
'sticky-quickopen'?: boolean;
'uninstall-extension'?: string | string[];
'unity-launch'?: boolean; // Always open a new window, except if opening the first window or opening a file or folder as part of the launch.
'upload-logs'?: string;
user?: string;
'user-data-dir'?: string;
_urls?: string[];
verbose?: boolean;
version?: boolean;
wait?: boolean;
waitMarkerFilePath?: string;
}
suite('commandLineService tests', () => {
let capabilitiesService: CapabilitiesTestService;
let commandLineService : CommandLineService;
let environmentService : TypeMoq.Mock<EnvironmentService>;
let queryEditorService : TypeMoq.Mock<QueryEditorService>;
let editorService:TypeMoq.Mock<IEditorService>;
let objectExplorerService : TypeMoq.Mock<ObjectExplorerService>;
let connectionStore: TypeMoq.Mock<ConnectionStore>;
setup(() => {
capabilitiesService = new CapabilitiesTestService();
connectionStore = TypeMoq.Mock.ofType(ConnectionStore);
});
function getCommandLineService(connectionManagementService : IConnectionManagementService,
environmentService? : IEnvironmentService,
capabilitiesService? : ICapabilitiesService
) : CommandLineService
{
let service= new CommandLineService(
connectionManagementService,
capabilitiesService,
environmentService,
undefined,
undefined,
undefined
);
return service;
}
test('processCommandLine shows connection dialog by default', done => {
const connectionManagementService : TypeMoq.Mock<IConnectionManagementService>
= TypeMoq.Mock.ofType<IConnectionManagementService>(TestConnectionManagementService, TypeMoq.MockBehavior.Strict);
connectionManagementService.setup((c) => c.showConnectionDialog()).verifiable();
connectionManagementService.setup(c => c.hasRegisteredServers()).returns(() => false);
connectionManagementService.setup(c => c.connectIfNotConnected(TypeMoq.It.isAny(), TypeMoq.It.isAny()))
.verifiable(TypeMoq.Times.never());
let service = getCommandLineService(connectionManagementService.object);
service.processCommandLine();
connectionManagementService.verifyAll();
done();
});
test('processCommandLine does nothing if registered servers exist and no server name is provided', done => {
const connectionManagementService : TypeMoq.Mock<IConnectionManagementService>
= TypeMoq.Mock.ofType<IConnectionManagementService>(TestConnectionManagementService, TypeMoq.MockBehavior.Strict);
connectionManagementService.setup((c) => c.showConnectionDialog()).verifiable(TypeMoq.Times.never());
connectionManagementService.setup(c => c.hasRegisteredServers()).returns(() => true);
connectionManagementService.setup(c => c.connectIfNotConnected(TypeMoq.It.isAny(), TypeMoq.It.isAny()))
.verifiable(TypeMoq.Times.never());
let service = getCommandLineService(connectionManagementService.object);
service.processCommandLine();
connectionManagementService.verifyAll();
done();
});
test('processCommandLine opens a new connection if a server name is passed', done => {
const connectionManagementService : TypeMoq.Mock<IConnectionManagementService>
= TypeMoq.Mock.ofType<IConnectionManagementService>(TestConnectionManagementService, TypeMoq.MockBehavior.Strict);
const environmentService : TypeMoq.Mock<IEnvironmentService> = TypeMoq.Mock.ofType<IEnvironmentService>(EnvironmentService);
const args : TestParsedArgs = new TestParsedArgs();
args.server = 'myserver';
args.database = 'mydatabase';
environmentService.setup(e => e.args).returns(() => args).verifiable(TypeMoq.Times.atLeastOnce());
connectionManagementService.setup((c) => c.showConnectionDialog()).verifiable(TypeMoq.Times.never());
connectionManagementService.setup(c => c.hasRegisteredServers()).returns(() => true).verifiable(TypeMoq.Times.atMostOnce());
connectionManagementService.setup(c => c.connectIfNotConnected(TypeMoq.It.isAny(), 'connection'))
.returns(() => new Promise<string>((resolve, reject) => { reject('unused');}))
.verifiable(TypeMoq.Times.once());
let service = getCommandLineService(connectionManagementService.object, environmentService.object, capabilitiesService);
service.processCommandLine();
environmentService.verifyAll();
connectionManagementService.verifyAll();
done();
});
});

View File

@@ -62,6 +62,13 @@ export interface ParsedArgs {
'upload-logs'?: string; 'upload-logs'?: string;
'driver'?: string; 'driver'?: string;
'driver-verbose'?: boolean; 'driver-verbose'?: boolean;
// {{SQL CARBON EDIT}}
aad?: boolean;
database?: string;
integrated?: boolean;
server?: string;
user?: string;
// {{SQL CARBON EDIT}}
} }
export const IEnvironmentService = createDecorator<IEnvironmentService>('environmentService'); export const IEnvironmentService = createDecorator<IEnvironmentService>('environmentService');

View File

@@ -33,7 +33,12 @@ const options: minimist.Opts = {
'export-default-configuration', 'export-default-configuration',
'install-source', 'install-source',
'upload-logs', 'upload-logs',
'driver' 'driver',
// {{SQL CARBON EDIT}}
'database',
'server',
'user',
// {{SQL CARBON EDIT}}
], ],
boolean: [ boolean: [
'help', 'help',
@@ -66,7 +71,11 @@ const options: minimist.Opts = {
'status', 'status',
'file-write', 'file-write',
'file-chmod', 'file-chmod',
'driver-verbose' 'driver-verbose',
// {{SQL CARBON EDIT}}
'aad',
'integrated',
// {{SQL CARBON EDIT}}
], ],
alias: { alias: {
add: 'a', add: 'a',
@@ -85,6 +94,12 @@ const options: minimist.Opts = {
'debugBrkPluginHost': 'inspect-brk-extensions', 'debugBrkPluginHost': 'inspect-brk-extensions',
'debugSearch': 'inspect-search', 'debugSearch': 'inspect-search',
'debugBrkSearch': 'inspect-brk-search', 'debugBrkSearch': 'inspect-brk-search',
// {{SQL CARBON EDIT}}
database: 'D',
integrated: 'E',
server: 'S',
user: 'U',
// {{SQL CARBON EDIT}}
} }
}; };

View File

@@ -165,6 +165,8 @@ import { DashboardViewService } from 'sql/services/dashboard/common/dashboardVie
import { ModelViewService } from 'sql/services/modelComponents/modelViewServiceImpl'; import { ModelViewService } from 'sql/services/modelComponents/modelViewServiceImpl';
import { IDashboardService } from 'sql/services/dashboard/common/dashboardService'; import { IDashboardService } from 'sql/services/dashboard/common/dashboardService';
import { DashboardService } from 'sql/services/dashboard/common/dashboardServiceImpl'; import { DashboardService } from 'sql/services/dashboard/common/dashboardServiceImpl';
import { NotebookService } from 'sql/services/notebook/notebookServiceImpl';
import { INotebookService } from 'sql/services/notebook/notebookService';
import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService'; import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
@@ -172,8 +174,10 @@ import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'
import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService'; import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { IUriDisplayService, UriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; import { IUriDisplayService, UriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay';
import { NotebookService } from 'sql/services/notebook/notebookServiceImpl'; // {{SQL CARBON EDIT}}
import { INotebookService } from 'sql/services/notebook/notebookService'; import { ICommandLineProcessing } from 'sql/parts/commandLine/common/commandLine';
import { CommandLineService } from 'sql/parts/commandLine/common/commandLineService';
// {{SQL CARBON EDIT}}
interface WorkbenchParams { interface WorkbenchParams {
configuration: IWindowConfiguration; configuration: IWindowConfiguration;
@@ -579,7 +583,9 @@ export class Workbench extends Disposable implements IPartService {
serviceCollection.set(INotebookService, notebookService); serviceCollection.set(INotebookService, notebookService);
serviceCollection.set(IAccountPickerService, this.instantiationService.createInstance(AccountPickerService)); serviceCollection.set(IAccountPickerService, this.instantiationService.createInstance(AccountPickerService));
serviceCollection.set(IProfilerService, this.instantiationService.createInstance(ProfilerService)); serviceCollection.set(IProfilerService, this.instantiationService.createInstance(ProfilerService));
// {{SQL CARBON EDIT}}
serviceCollection.set(ICommandLineProcessing, this.instantiationService.createInstance(CommandLineService));
// {{SQL CARBON EDIT}}
this._register(toDisposable(() => connectionManagementService.shutdown())); this._register(toDisposable(() => connectionManagementService.shutdown()));
this._register(toDisposable(() => accountManagementService.shutdown())); this._register(toDisposable(() => accountManagementService.shutdown()));
this._register(toDisposable(() => notebookService.shutdown())); this._register(toDisposable(() => notebookService.shutdown()));