mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 11:01:37 -05:00
Added data points for Table Designer (#18182)
* added server infor and metrics for table designer * update generate script * pr comments * format more files * pr comments * make changes to core * remove unused imports * add server info * revert enum change and add publish event * format doc * nitpicks * remove os version * remove modifier from telemetry info * remove error message
This commit is contained in:
@@ -65,6 +65,10 @@ export enum MssqlClusterItemsSubType {
|
|||||||
Spark = ':spark:'
|
Spark = ':spark:'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum TableType {
|
||||||
|
Basic = 'basic'
|
||||||
|
}
|
||||||
|
|
||||||
// SPARK JOB SUBMISSION //////////////////////////////////////////////////////////
|
// SPARK JOB SUBMISSION //////////////////////////////////////////////////////////
|
||||||
export const mssqlClusterNewNotebookTask = 'mssqlCluster.task.newNotebook';
|
export const mssqlClusterNewNotebookTask = 'mssqlCluster.task.newNotebook';
|
||||||
export const mssqlClusterOpenNotebookTask = 'mssqlCluster.task.openNotebook';
|
export const mssqlClusterOpenNotebookTask = 'mssqlCluster.task.openNotebook';
|
||||||
|
|||||||
1
extensions/mssql/src/mssql.d.ts
vendored
1
extensions/mssql/src/mssql.d.ts
vendored
@@ -6,7 +6,6 @@
|
|||||||
// This is the place for extensions to expose APIs.
|
// This is the place for extensions to expose APIs.
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import * as vscode from 'vscode';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Covers defining what the mssql extension exports to other extensions
|
* Covers defining what the mssql extension exports to other extensions
|
||||||
|
|||||||
@@ -8,17 +8,21 @@ import * as azdata from 'azdata';
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { sqlProviderName } from '../constants';
|
import { sqlProviderName } from '../constants';
|
||||||
import { generateUuid } from 'vscode-languageclient/lib/utils/uuid';
|
import { generateUuid } from 'vscode-languageclient/lib/utils/uuid';
|
||||||
|
import { ITelemetryEventProperties, Telemetry } from '../telemetry';
|
||||||
|
|
||||||
export function registerTableDesignerCommands(appContext: AppContext) {
|
export function registerTableDesignerCommands(appContext: AppContext) {
|
||||||
appContext.extensionContext.subscriptions.push(vscode.commands.registerCommand('mssql.newTable', async (context: azdata.ObjectExplorerContext) => {
|
appContext.extensionContext.subscriptions.push(vscode.commands.registerCommand('mssql.newTable', async (context: azdata.ObjectExplorerContext) => {
|
||||||
const connectionString = await azdata.connection.getConnectionString(context.connectionProfile.id, true);
|
const connectionString = await azdata.connection.getConnectionString(context.connectionProfile.id, true);
|
||||||
|
const serverInfo = await azdata.connection.getServerInfo(context.connectionProfile.id);
|
||||||
|
let telemetryInfo: ITelemetryEventProperties = {};
|
||||||
|
telemetryInfo = Telemetry.fillServerInfo(telemetryInfo, serverInfo);
|
||||||
await azdata.designers.openTableDesigner(sqlProviderName, {
|
await azdata.designers.openTableDesigner(sqlProviderName, {
|
||||||
server: context.connectionProfile.serverName,
|
server: context.connectionProfile.serverName,
|
||||||
database: context.connectionProfile.databaseName,
|
database: context.connectionProfile.databaseName,
|
||||||
isNewTable: true,
|
isNewTable: true,
|
||||||
id: generateUuid(),
|
id: generateUuid(),
|
||||||
connectionString: connectionString
|
connectionString: connectionString
|
||||||
});
|
}, telemetryInfo);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
appContext.extensionContext.subscriptions.push(vscode.commands.registerCommand('mssql.designTable', async (context: azdata.ObjectExplorerContext) => {
|
appContext.extensionContext.subscriptions.push(vscode.commands.registerCommand('mssql.designTable', async (context: azdata.ObjectExplorerContext) => {
|
||||||
@@ -28,6 +32,9 @@ export function registerTableDesignerCommands(appContext: AppContext) {
|
|||||||
const name = context.nodeInfo.metadata.name;
|
const name = context.nodeInfo.metadata.name;
|
||||||
const connectionString = await azdata.connection.getConnectionString(context.connectionProfile.id, true);
|
const connectionString = await azdata.connection.getConnectionString(context.connectionProfile.id, true);
|
||||||
const connectionUri = await azdata.connection.getUriForConnection(context.connectionProfile.id);
|
const connectionUri = await azdata.connection.getUriForConnection(context.connectionProfile.id);
|
||||||
|
const serverInfo = await azdata.connection.getServerInfo(context.connectionProfile.id);
|
||||||
|
let telemetryInfo: ITelemetryEventProperties = {};
|
||||||
|
telemetryInfo = Telemetry.fillServerInfo(telemetryInfo, serverInfo);
|
||||||
await azdata.designers.openTableDesigner(sqlProviderName, {
|
await azdata.designers.openTableDesigner(sqlProviderName, {
|
||||||
server: server,
|
server: server,
|
||||||
database: database,
|
database: database,
|
||||||
@@ -36,6 +43,6 @@ export function registerTableDesignerCommands(appContext: AppContext) {
|
|||||||
schema: schema,
|
schema: schema,
|
||||||
id: `${connectionUri}|${database}|${schema}|${name}`,
|
id: `${connectionUri}|${database}|${schema}|${name}`,
|
||||||
connectionString: connectionString
|
connectionString: connectionString
|
||||||
});
|
}, telemetryInfo);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import { ErrorAction, ErrorHandler, Message, CloseAction } from 'vscode-language
|
|||||||
import * as Utils from './utils';
|
import * as Utils from './utils';
|
||||||
import * as Constants from './constants';
|
import * as Constants from './constants';
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
|
import { ServerInfo } from 'azdata';
|
||||||
|
|
||||||
|
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
const packageJson = require('../package.json');
|
const packageJson = require('../package.json');
|
||||||
@@ -114,6 +116,20 @@ export class Telemetry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collects server information from ServerInfo to put into a
|
||||||
|
* property bag
|
||||||
|
*/
|
||||||
|
public static fillServerInfo(telemetryInfo: { [key: string]: string }, serverInfo: ServerInfo): { [key: string]: string } {
|
||||||
|
telemetryInfo['serverEdition'] = serverInfo?.serverEdition;
|
||||||
|
telemetryInfo['serverLevel'] = serverInfo?.serverLevel;
|
||||||
|
telemetryInfo['serverMajorVersion'] = serverInfo?.serverMajorVersion.toString();
|
||||||
|
telemetryInfo['serverMinorVersion'] = serverInfo?.serverMinorVersion.toString();
|
||||||
|
telemetryInfo['isCloud'] = serverInfo?.isCloud.toString();
|
||||||
|
telemetryInfo['tableType'] = Constants.TableType.Basic;
|
||||||
|
return telemetryInfo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
3
src/sql/azdata.proposed.d.ts
vendored
3
src/sql/azdata.proposed.d.ts
vendored
@@ -1021,8 +1021,9 @@ declare module 'azdata' {
|
|||||||
* Open a table designer window.
|
* Open a table designer window.
|
||||||
* @param providerId The table designer provider Id.
|
* @param providerId The table designer provider Id.
|
||||||
* @param tableInfo The table information. The object will be passed back to the table designer provider as the unique identifier for the table.
|
* @param tableInfo The table information. The object will be passed back to the table designer provider as the unique identifier for the table.
|
||||||
|
* @param telemetryInfo: Optional Key-value pair containing any extra information that needs to be sent via telemetry
|
||||||
*/
|
*/
|
||||||
export function openTableDesigner(providerId: string, tableInfo: TableInfo): Thenable<void>;
|
export function openTableDesigner(providerId: string, tableInfo: TableInfo, telemetryInfo?: { [key: string]: string }): Thenable<void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Definition for the table designer provider.
|
* Definition for the table designer provider.
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ export const enum TelemetryAction {
|
|||||||
ChartCreated = 'ChartCreated',
|
ChartCreated = 'ChartCreated',
|
||||||
Click = 'Click',
|
Click = 'Click',
|
||||||
FirewallRuleRequested = 'FirewallRuleCreated',
|
FirewallRuleRequested = 'FirewallRuleCreated',
|
||||||
|
GenerateScript = 'GenerateScript',
|
||||||
GetDataGridItems = 'GetDataGridItems',
|
GetDataGridItems = 'GetDataGridItems',
|
||||||
GetDataGridColumns = 'GetDataGridColumns',
|
GetDataGridColumns = 'GetDataGridColumns',
|
||||||
ModelViewDashboardOpened = 'ModelViewDashboardOpened',
|
ModelViewDashboardOpened = 'ModelViewDashboardOpened',
|
||||||
@@ -80,6 +81,7 @@ export const enum TelemetryAction {
|
|||||||
NewQuery = 'NewQuery',
|
NewQuery = 'NewQuery',
|
||||||
ObjectExplorerExpand = 'ObjectExplorerExpand',
|
ObjectExplorerExpand = 'ObjectExplorerExpand',
|
||||||
Open = 'Open',
|
Open = 'Open',
|
||||||
|
PublishChanges = 'PublishChanges',
|
||||||
RestoreRequested = 'RestoreRequested',
|
RestoreRequested = 'RestoreRequested',
|
||||||
RunAgentJob = 'RunAgentJob',
|
RunAgentJob = 'RunAgentJob',
|
||||||
RunQuery = 'RunQuery',
|
RunQuery = 'RunQuery',
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
|||||||
import { serializableToMap } from 'sql/base/common/map';
|
import { serializableToMap } from 'sql/base/common/map';
|
||||||
import { IAssessmentService } from 'sql/workbench/services/assessment/common/interfaces';
|
import { IAssessmentService } from 'sql/workbench/services/assessment/common/interfaces';
|
||||||
import { IDataGridProviderService } from 'sql/workbench/services/dataGridProvider/common/dataGridProviderService';
|
import { IDataGridProviderService } from 'sql/workbench/services/dataGridProvider/common/dataGridProviderService';
|
||||||
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
|
import { IAdsTelemetryService, ITelemetryEventProperties } from 'sql/platform/telemetry/common/telemetry';
|
||||||
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
|
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
|
||||||
import { ITableDesignerService } from 'sql/workbench/services/tableDesigner/common/interface';
|
import { ITableDesignerService } from 'sql/workbench/services/tableDesigner/common/interface';
|
||||||
|
|
||||||
@@ -646,8 +646,8 @@ export class MainThreadDataProtocol extends Disposable implements MainThreadData
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Table Designer
|
// Table Designer
|
||||||
public $openTableDesigner(providerId: string, tableInfo: azdata.designers.TableInfo): void {
|
public $openTableDesigner(providerId: string, tableInfo: azdata.designers.TableInfo, telemetryInfo?: ITelemetryEventProperties): void {
|
||||||
this._tableDesignerService.openTableDesigner(providerId, tableInfo);
|
this._tableDesignerService.openTableDesigner(providerId, tableInfo, telemetryInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public $unregisterProvider(handle: number): Promise<any> {
|
public $unregisterProvider(handle: number): Promise<any> {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { IURITransformer } from 'vs/base/common/uriIpc';
|
|||||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||||
import { mapToSerializable } from 'sql/base/common/map';
|
import { mapToSerializable } from 'sql/base/common/map';
|
||||||
|
import { ITelemetryEventProperties } from 'sql/platform/telemetry/common/telemetry';
|
||||||
|
|
||||||
export class ExtHostDataProtocol extends ExtHostDataProtocolShape {
|
export class ExtHostDataProtocol extends ExtHostDataProtocolShape {
|
||||||
|
|
||||||
@@ -916,8 +917,8 @@ export class ExtHostDataProtocol extends ExtHostDataProtocolShape {
|
|||||||
return this._resolveProvider<azdata.designers.TableDesignerProvider>(handle).disposeTableDesigner(table);
|
return this._resolveProvider<azdata.designers.TableDesignerProvider>(handle).disposeTableDesigner(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override $openTableDesigner(providerId: string, tableInfo: azdata.designers.TableInfo): Promise<void> {
|
public override $openTableDesigner(providerId: string, tableInfo: azdata.designers.TableInfo, telemetryInfo?: ITelemetryEventProperties): Promise<void> {
|
||||||
this._proxy.$openTableDesigner(providerId, tableInfo);
|
this._proxy.$openTableDesigner(providerId, tableInfo, telemetryInfo);
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
|
|||||||
import { ExtHostWorkspace } from 'sql/workbench/api/common/extHostWorkspace';
|
import { ExtHostWorkspace } from 'sql/workbench/api/common/extHostWorkspace';
|
||||||
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
|
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
|
import { ITelemetryEventProperties } from 'sql/platform/telemetry/common/telemetry';
|
||||||
|
|
||||||
export interface IAzdataExtensionApiFactory {
|
export interface IAzdataExtensionApiFactory {
|
||||||
(extension: IExtensionDescription): typeof azdata;
|
(extension: IExtensionDescription): typeof azdata;
|
||||||
@@ -578,8 +579,8 @@ export function createAdsApiFactory(accessor: ServicesAccessor): IAdsExtensionAp
|
|||||||
TableIndexProperty: sqlExtHostTypes.designers.TableIndexProperty,
|
TableIndexProperty: sqlExtHostTypes.designers.TableIndexProperty,
|
||||||
TableIndexColumnSpecificationProperty: sqlExtHostTypes.designers.TableIndexColumnSpecificationProperty,
|
TableIndexColumnSpecificationProperty: sqlExtHostTypes.designers.TableIndexColumnSpecificationProperty,
|
||||||
DesignerEditType: sqlExtHostTypes.designers.DesignerEditType,
|
DesignerEditType: sqlExtHostTypes.designers.DesignerEditType,
|
||||||
openTableDesigner(providerId, tableInfo: azdata.designers.TableInfo): Promise<void> {
|
openTableDesigner(providerId, tableInfo: azdata.designers.TableInfo, telemetryInfo?: ITelemetryEventProperties): Promise<void> {
|
||||||
return extHostDataProvider.$openTableDesigner(providerId, tableInfo);
|
return extHostDataProvider.$openTableDesigner(providerId, tableInfo, telemetryInfo);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'
|
|||||||
import { IQueryEvent } from 'sql/workbench/services/query/common/queryModel';
|
import { IQueryEvent } from 'sql/workbench/services/query/common/queryModel';
|
||||||
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
|
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
|
||||||
import { TreeDataTransferDTO } from 'vs/workbench/api/common/shared/treeDataTransfer';
|
import { TreeDataTransferDTO } from 'vs/workbench/api/common/shared/treeDataTransfer';
|
||||||
|
import { ITelemetryEventProperties } from 'sql/platform/telemetry/common/telemetry';
|
||||||
|
|
||||||
export abstract class ExtHostAccountManagementShape {
|
export abstract class ExtHostAccountManagementShape {
|
||||||
$autoOAuthCancelled(handle: number): Thenable<void> { throw ni(); }
|
$autoOAuthCancelled(handle: number): Thenable<void> { throw ni(); }
|
||||||
@@ -560,7 +561,7 @@ export abstract class ExtHostDataProtocolShape {
|
|||||||
/**
|
/**
|
||||||
* Open a new instance of table designer.
|
* Open a new instance of table designer.
|
||||||
*/
|
*/
|
||||||
$openTableDesigner(providerId: string, tableInfo: azdata.designers.TableInfo, designerInfo: azdata.designers.TableDesignerInfo): void { throw ni(); }
|
$openTableDesigner(providerId: string, tableInfo: azdata.designers.TableInfo, telemetryInfo?: ITelemetryEventProperties): void { throw ni(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -650,7 +651,7 @@ export interface MainThreadDataProtocolShape extends IDisposable {
|
|||||||
$onSessionStopped(handle: number, response: azdata.ProfilerSessionStoppedParams): void;
|
$onSessionStopped(handle: number, response: azdata.ProfilerSessionStoppedParams): void;
|
||||||
$onProfilerSessionCreated(handle: number, response: azdata.ProfilerSessionCreatedParams): void;
|
$onProfilerSessionCreated(handle: number, response: azdata.ProfilerSessionCreatedParams): void;
|
||||||
$onJobDataUpdated(handle: Number): void;
|
$onJobDataUpdated(handle: Number): void;
|
||||||
$openTableDesigner(providerId: string, tableInfo: azdata.designers.TableInfo): void;
|
$openTableDesigner(providerId: string, tableInfo: azdata.designers.TableInfo, telemetryInfo?: ITelemetryEventProperties): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback when a session has completed initialization
|
* Callback when a session has completed initialization
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export class TableDesignerInput extends EditorInput {
|
|||||||
constructor(
|
constructor(
|
||||||
private _provider: TableDesignerProvider,
|
private _provider: TableDesignerProvider,
|
||||||
private _tableInfo: azdata.designers.TableInfo,
|
private _tableInfo: azdata.designers.TableInfo,
|
||||||
|
telemetryInfo: { [key: string]: string },
|
||||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||||
@IEditorService editorService: IEditorService,
|
@IEditorService editorService: IEditorService,
|
||||||
@INotificationService private readonly _notificationService: INotificationService) {
|
@INotificationService private readonly _notificationService: INotificationService) {
|
||||||
super();
|
super();
|
||||||
this._designerComponentInput = this._instantiationService.createInstance(TableDesignerComponentInput, this._provider, this._tableInfo);
|
this._designerComponentInput = this._instantiationService.createInstance(TableDesignerComponentInput, this._provider, this._tableInfo, telemetryInfo);
|
||||||
this._register(this._designerComponentInput.onStateChange((e) => {
|
this._register(this._designerComponentInput.onStateChange((e) => {
|
||||||
if (e.currentState.dirty !== e.previousState.dirty) {
|
if (e.currentState.dirty !== e.previousState.dirty) {
|
||||||
this._onDidChangeDirty.fire();
|
this._onDidChangeDirty.fire();
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import { DesignerViewModel, DesignerEdit, DesignerComponentInput, DesignerView, DesignerTab, DesignerDataPropertyInfo, DropDownProperties, DesignerTableProperties, DesignerEditProcessedEventArgs, DesignerAction, DesignerStateChangedEventArgs } from 'sql/workbench/browser/designer/interfaces';
|
import { DesignerViewModel, DesignerEdit, DesignerComponentInput, DesignerView, DesignerTab, DesignerDataPropertyInfo, DropDownProperties, DesignerTableProperties, DesignerEditProcessedEventArgs, DesignerAction, DesignerStateChangedEventArgs, DesignerEditPath } from 'sql/workbench/browser/designer/interfaces';
|
||||||
import { TableDesignerProvider } from 'sql/workbench/services/tableDesigner/common/interface';
|
import { TableDesignerProvider } from 'sql/workbench/services/tableDesigner/common/interface';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
import { designers } from 'sql/workbench/api/common/sqlExtHostTypes';
|
import { designers } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||||
@@ -14,6 +14,8 @@ import { deepClone, equals } from 'vs/base/common/objects';
|
|||||||
import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService';
|
import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { TableDesignerPublishDialogResult, TableDesignerPublishDialog } from 'sql/workbench/services/tableDesigner/browser/tableDesignerPublishDialog';
|
import { TableDesignerPublishDialogResult, TableDesignerPublishDialog } from 'sql/workbench/services/tableDesigner/browser/tableDesignerPublishDialog';
|
||||||
|
import { IAdsTelemetryService, ITelemetryEventProperties } from 'sql/platform/telemetry/common/telemetry';
|
||||||
|
import { TelemetryAction, TelemetryView } from 'sql/platform/telemetry/common/telemetryKeys';
|
||||||
|
|
||||||
export class TableDesignerComponentInput implements DesignerComponentInput {
|
export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||||
|
|
||||||
@@ -31,9 +33,15 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
|||||||
public readonly onEditProcessed: Event<DesignerEditProcessedEventArgs> = this._onEditProcessed.event;
|
public readonly onEditProcessed: Event<DesignerEditProcessedEventArgs> = this._onEditProcessed.event;
|
||||||
public readonly onStateChange: Event<DesignerStateChangedEventArgs> = this._onStateChange.event;
|
public readonly onStateChange: Event<DesignerStateChangedEventArgs> = this._onStateChange.event;
|
||||||
|
|
||||||
|
private readonly designerEditTypeDisplayValue: { [key: number]: string } = {
|
||||||
|
0: 'Add', 1: 'Remove', 2: 'Update'
|
||||||
|
};
|
||||||
|
|
||||||
constructor(private readonly _provider: TableDesignerProvider,
|
constructor(private readonly _provider: TableDesignerProvider,
|
||||||
private _tableInfo: azdata.designers.TableInfo,
|
private _tableInfo: azdata.designers.TableInfo,
|
||||||
|
private _telemetryInfo: ITelemetryEventProperties,
|
||||||
@INotificationService private readonly _notificationService: INotificationService,
|
@INotificationService private readonly _notificationService: INotificationService,
|
||||||
|
@IAdsTelemetryService readonly _adsTelemetryService: IAdsTelemetryService,
|
||||||
@IQueryEditorService private readonly _queryEditorService: IQueryEditorService,
|
@IQueryEditorService private readonly _queryEditorService: IQueryEditorService,
|
||||||
@IInstantiationService private readonly _instantiationService: IInstantiationService) {
|
@IInstantiationService private readonly _instantiationService: IInstantiationService) {
|
||||||
}
|
}
|
||||||
@@ -63,6 +71,11 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
processEdit(edit: DesignerEdit): void {
|
processEdit(edit: DesignerEdit): void {
|
||||||
|
const telemetryInfo = this.createTelemetryInfo();
|
||||||
|
telemetryInfo.tableObjectType = this.getObjectTypeFromPath(edit.path);
|
||||||
|
const editAction = this._adsTelemetryService.createActionEvent(TelemetryView.TableDesigner,
|
||||||
|
this.designerEditTypeDisplayValue[edit.type]).withAdditionalProperties(telemetryInfo);
|
||||||
|
const startTime = new Date().getTime();
|
||||||
this.updateState(this.valid, this.dirty, 'processEdit');
|
this.updateState(this.valid, this.dirty, 'processEdit');
|
||||||
this._provider.processTableEdit(this._tableInfo, edit).then(
|
this._provider.processTableEdit(this._tableInfo, edit).then(
|
||||||
result => {
|
result => {
|
||||||
@@ -76,10 +89,15 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
|||||||
errors: result.errors
|
errors: result.errors
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
editAction.withAdditionalMeasurements({
|
||||||
|
'elapsedTimeMs': new Date().getTime() - startTime
|
||||||
|
}).send();
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
this._notificationService.error(localize('tableDesigner.errorProcessingEdit', "An error occured while processing the change: {0}", error?.message ?? error));
|
this._notificationService.error(localize('tableDesigner.errorProcessingEdit', "An error occured while processing the change: {0}", error?.message ?? error));
|
||||||
this.updateState(this.valid, this.dirty);
|
this.updateState(this.valid, this.dirty);
|
||||||
|
this._adsTelemetryService.createErrorEvent(TelemetryView.TableDesigner,
|
||||||
|
this.designerEditTypeDisplayValue[edit.type]).withAdditionalProperties(telemetryInfo).send();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -90,35 +108,49 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
|||||||
message: localize('tableDesigner.generatingScript', "Generating script..."),
|
message: localize('tableDesigner.generatingScript', "Generating script..."),
|
||||||
sticky: true
|
sticky: true
|
||||||
});
|
});
|
||||||
|
const telemetryInfo = this.createTelemetryInfo();
|
||||||
|
const generateScriptEvent = this._adsTelemetryService.createActionEvent(TelemetryView.TableDesigner, TelemetryAction.GenerateScript).withAdditionalProperties(telemetryInfo);
|
||||||
|
const startTime = new Date().getTime();
|
||||||
try {
|
try {
|
||||||
this.updateState(this.valid, this.dirty, 'generateScript');
|
this.updateState(this.valid, this.dirty, 'generateScript');
|
||||||
const script = await this._provider.generateScript(this._tableInfo);
|
const script = await this._provider.generateScript(this._tableInfo);
|
||||||
this._queryEditorService.newSqlEditor({ initalContent: script });
|
this._queryEditorService.newSqlEditor({ initalContent: script });
|
||||||
this.updateState(this.valid, this.dirty);
|
this.updateState(this.valid, this.dirty);
|
||||||
notificationHandle.updateMessage(localize('tableDesigner.generatingScriptCompleted', "Script generated."));
|
notificationHandle.updateMessage(localize('tableDesigner.generatingScriptCompleted', "Script generated."));
|
||||||
|
generateScriptEvent.withAdditionalMeasurements({
|
||||||
|
'elapsedTimeMs': new Date().getTime() - startTime
|
||||||
|
}).send();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notificationHandle.updateSeverity(Severity.Error);
|
notificationHandle.updateSeverity(Severity.Error);
|
||||||
notificationHandle.updateMessage(localize('tableDesigner.generateScriptError', "An error occured while generating the script: {0}", error?.message ?? error));
|
notificationHandle.updateMessage(localize('tableDesigner.generateScriptError', "An error occured while generating the script: {0}", error?.message ?? error));
|
||||||
this.updateState(this.valid, this.dirty);
|
this.updateState(this.valid, this.dirty);
|
||||||
|
this._adsTelemetryService.createErrorEvent(TelemetryView.TableDesigner, TelemetryAction.GenerateScript).withAdditionalProperties(telemetryInfo).send();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async publishChanges(): Promise<void> {
|
async publishChanges(): Promise<void> {
|
||||||
|
const telemetryInfo = this.createTelemetryInfo();
|
||||||
|
const publishEvent = this._adsTelemetryService.createActionEvent(TelemetryView.TableDesigner, TelemetryAction.PublishChanges).withAdditionalProperties(telemetryInfo);
|
||||||
const saveNotificationHandle = this._notificationService.notify({
|
const saveNotificationHandle = this._notificationService.notify({
|
||||||
severity: Severity.Info,
|
severity: Severity.Info,
|
||||||
message: localize('tableDesigner.savingChanges', "Saving table designer changes..."),
|
message: localize('tableDesigner.savingChanges', "Saving table designer changes..."),
|
||||||
sticky: true
|
sticky: true
|
||||||
});
|
});
|
||||||
|
const startTime = new Date().getTime();
|
||||||
try {
|
try {
|
||||||
this.updateState(this.valid, this.dirty, 'save');
|
this.updateState(this.valid, this.dirty, 'save');
|
||||||
await this._provider.publishChanges(this._tableInfo);
|
await this._provider.publishChanges(this._tableInfo);
|
||||||
this._originalViewModel = this._viewModel;
|
this._originalViewModel = this._viewModel;
|
||||||
this.updateState(true, false);
|
this.updateState(true, false);
|
||||||
saveNotificationHandle.updateMessage(localize('tableDesigner.publishChangeSuccess', "The changes have been successfully published."));
|
saveNotificationHandle.updateMessage(localize('tableDesigner.publishChangeSuccess', "The changes have been successfully published."));
|
||||||
|
publishEvent.withAdditionalMeasurements({
|
||||||
|
'elapsedTimeMs': new Date().getTime() - startTime
|
||||||
|
}).send();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
saveNotificationHandle.updateSeverity(Severity.Error);
|
saveNotificationHandle.updateSeverity(Severity.Error);
|
||||||
saveNotificationHandle.updateMessage(localize('tableDesigner.publishChangeError', "An error occured while publishing changes: {0}", error?.message ?? error));
|
saveNotificationHandle.updateMessage(localize('tableDesigner.publishChangeError', "An error occured while publishing changes: {0}", error?.message ?? error));
|
||||||
this.updateState(this.valid, this.dirty);
|
this.updateState(this.valid, this.dirty);
|
||||||
|
this._adsTelemetryService.createErrorEvent(TelemetryView.TableDesigner, TelemetryAction.PublishChanges).withAdditionalProperties(telemetryInfo).send();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -580,4 +612,36 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
|||||||
this._viewModel[property] = {};
|
this._viewModel[property] = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private createTelemetryInfo(): ITelemetryEventProperties {
|
||||||
|
let telemetryInfo = {
|
||||||
|
provider: this._provider.providerId,
|
||||||
|
isNewTable: this._tableInfo.isNewTable,
|
||||||
|
};
|
||||||
|
Object.assign(telemetryInfo, this._telemetryInfo);
|
||||||
|
return telemetryInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. 'Add' scenario
|
||||||
|
a. ['propertyName1']. Example: add a column to the columns property: ['columns'].
|
||||||
|
b. ['propertyName1',index-1,'propertyName2']. Example: add a column mapping to the first foreign key: ['foreignKeys',0,'mappings'].
|
||||||
|
2. 'Update' scenario
|
||||||
|
a. ['propertyName1']. Example: update the name of the table: ['name'].
|
||||||
|
b. ['propertyName1',index-1,'propertyName2']. Example: update the name of a column: ['columns',0,'name'].
|
||||||
|
c. ['propertyName1',index-1,'propertyName2',index-2,'propertyName3']. Example: update the source column of an entry in a foreign key's column mapping table: ['foreignKeys',0,'mappings',0,'source'].
|
||||||
|
3. 'Remove' scenario
|
||||||
|
a. ['propertyName1',index-1]. Example: remove a column from the columns property: ['columns',0'].
|
||||||
|
b. ['propertyName1',index-1,'proper
|
||||||
|
The return values would be the propertyNames followed by slashes in level order. Eg.: propertyName1/propertyName2/...
|
||||||
|
*/
|
||||||
|
private getObjectTypeFromPath(path: DesignerEditPath): string {
|
||||||
|
let typeArray = [];
|
||||||
|
for (let i = 0; i < path.length; i++) {
|
||||||
|
if (i % 2 === 0) {
|
||||||
|
typeArray.push(path[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typeArray.join('/');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import * as azdata from 'azdata';
|
|||||||
import { ACTIVE_GROUP, IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
import { ACTIVE_GROUP, IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
import { TableDesignerInput } from 'sql/workbench/browser/editor/tableDesigner/tableDesignerInput';
|
import { TableDesignerInput } from 'sql/workbench/browser/editor/tableDesigner/tableDesignerInput';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
|
import { IAdsTelemetryService, ITelemetryEventProperties } from 'sql/platform/telemetry/common/telemetry';
|
||||||
import { TelemetryAction, TelemetryView } from 'sql/platform/telemetry/common/telemetryKeys';
|
import { TelemetryAction, TelemetryView } from 'sql/platform/telemetry/common/telemetryKeys';
|
||||||
|
|
||||||
export class TableDesignerService implements ITableDesignerService {
|
export class TableDesignerService implements ITableDesignerService {
|
||||||
@@ -43,13 +43,13 @@ export class TableDesignerService implements ITableDesignerService {
|
|||||||
throw invalidProvider(providerId);
|
throw invalidProvider(providerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async openTableDesigner(providerId: string, tableInfo: azdata.designers.TableInfo): Promise<void> {
|
public async openTableDesigner(providerId: string, tableInfo: azdata.designers.TableInfo, telemetryInfo?: ITelemetryEventProperties): Promise<void> {
|
||||||
this._adsTelemetryService.createActionEvent(TelemetryView.TableDesigner, TelemetryAction.Open).withAdditionalProperties({
|
this._adsTelemetryService.createActionEvent(TelemetryView.TableDesigner, TelemetryAction.Open).withAdditionalProperties({
|
||||||
provider: providerId,
|
provider: providerId,
|
||||||
newTable: tableInfo.isNewTable
|
newTable: tableInfo.isNewTable
|
||||||
}).send();
|
}).send();
|
||||||
const provider = this.getProvider(providerId);
|
const provider = this.getProvider(providerId);
|
||||||
const tableDesignerInput = this._instantiationService.createInstance(TableDesignerInput, provider, tableInfo);
|
const tableDesignerInput = this._instantiationService.createInstance(TableDesignerInput, provider, tableInfo, telemetryInfo);
|
||||||
await this._editorService.openEditor(tableDesignerInput, { pinned: true }, ACTIVE_GROUP);
|
await this._editorService.openEditor(tableDesignerInput, { pinned: true }, ACTIVE_GROUP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
|
import { ITelemetryEventProperties } from 'sql/platform/telemetry/common/telemetry';
|
||||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
|
||||||
|
|
||||||
@@ -36,5 +37,5 @@ export interface ITableDesignerService {
|
|||||||
* @param providerId The provider id
|
* @param providerId The provider id
|
||||||
* @param tableInfo The table information
|
* @param tableInfo The table information
|
||||||
*/
|
*/
|
||||||
openTableDesigner(providerId: string, tableInfo: azdata.designers.TableInfo): Promise<void>;
|
openTableDesigner(providerId: string, tableInfo: azdata.designers.TableInfo, telemetryInfo?: ITelemetryEventProperties): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user