mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
add foreign keys and constraints (#17697)
* foreign keys and constraints * refactoring * fix issues
This commit is contained in:
91
src/sql/azdata.proposed.d.ts
vendored
91
src/sql/azdata.proposed.d.ts
vendored
@@ -1079,18 +1079,20 @@ declare module 'azdata' {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Name of the common table properties.
|
* Name of the common table properties.
|
||||||
* Extensions can use the names to access the designer data.
|
* Extensions can use the names to access the designer view model.
|
||||||
*/
|
*/
|
||||||
export enum TableProperty {
|
export enum TableProperty {
|
||||||
Columns = 'columns',
|
Columns = 'columns',
|
||||||
Description = 'description',
|
Description = 'description',
|
||||||
Name = 'name',
|
Name = 'name',
|
||||||
Schema = 'schema',
|
Schema = 'schema',
|
||||||
Script = 'script'
|
Script = 'script',
|
||||||
|
ForeignKeys = 'foreignKeys',
|
||||||
|
CheckConstraints = 'checkConstraints',
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Name of the common table column properties.
|
* Name of the common table column properties.
|
||||||
* Extensions can use the names to access the designer data.
|
* Extensions can use the names to access the designer view model.
|
||||||
*/
|
*/
|
||||||
export enum TableColumnProperty {
|
export enum TableColumnProperty {
|
||||||
AllowNulls = 'allowNulls',
|
AllowNulls = 'allowNulls',
|
||||||
@@ -1103,6 +1105,35 @@ declare module 'azdata' {
|
|||||||
Scale = 'scale'
|
Scale = 'scale'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the common foreign key constraint properties.
|
||||||
|
* Extensions can use the names to access the designer view model.
|
||||||
|
*/
|
||||||
|
export enum TableForeignKeyProperty {
|
||||||
|
Name = 'name',
|
||||||
|
PrimaryKeyTable = 'primaryKeyTable',
|
||||||
|
OnDeleteAction = 'onDeleteAction',
|
||||||
|
OnUpdateAction = 'onUpdateAction',
|
||||||
|
Columns = 'columns'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the columns mapping properties for foreign key.
|
||||||
|
*/
|
||||||
|
export enum ForeignKeyColumnMappingProperty {
|
||||||
|
PrimaryKeyColumn = 'primaryKeyColumn',
|
||||||
|
ForeignKeyColumn = 'foreignKeyColumn'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the common check constraint properties.
|
||||||
|
* Extensions can use the name to access the designer view model.
|
||||||
|
*/
|
||||||
|
export enum TableCheckConstraintProperty {
|
||||||
|
Name = 'name',
|
||||||
|
Expression = 'expression'
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The table designer view definition.
|
* The table designer view definition.
|
||||||
*/
|
*/
|
||||||
@@ -1112,25 +1143,65 @@ declare module 'azdata' {
|
|||||||
*/
|
*/
|
||||||
additionalTableProperties?: DesignerDataPropertyInfo[];
|
additionalTableProperties?: DesignerDataPropertyInfo[];
|
||||||
/**
|
/**
|
||||||
* Additional table column properties.Common table properties are handled by Azure Data Studio. see {@link TableColumnProperty}
|
* Whether to show columns tab. The default value is false.
|
||||||
|
*/
|
||||||
|
showColumnsTab?: boolean;
|
||||||
|
/**
|
||||||
|
* Additional table column properties. Common table columns properties are handled by Azure Data Studio. see {@link TableColumnProperty}
|
||||||
*/
|
*/
|
||||||
additionalTableColumnProperties?: DesignerDataPropertyInfo[];
|
additionalTableColumnProperties?: DesignerDataPropertyInfo[];
|
||||||
/**
|
|
||||||
* Additional tabs.
|
|
||||||
*/
|
|
||||||
additionalTabs?: DesignerTab[];
|
|
||||||
/**
|
/**
|
||||||
* The properties to be displayed in the columns table. Default values are: Name, Type, Length, Precision, Scale, IsPrimaryKey, AllowNulls, DefaultValue.
|
* The properties to be displayed in the columns table. Default values are: Name, Type, Length, Precision, Scale, IsPrimaryKey, AllowNulls, DefaultValue.
|
||||||
*/
|
*/
|
||||||
columnsTableProperties?: string[];
|
columnsTableProperties?: string[];
|
||||||
/**
|
/**
|
||||||
* Whether user can add columns. The default value is true.
|
* Whether user can add columns. The default value is false.
|
||||||
*/
|
*/
|
||||||
canAddColumns?: boolean;
|
canAddColumns?: boolean;
|
||||||
/**
|
/**
|
||||||
* Whether user can remove columns. The default value is true.
|
* Whether user can remove columns. The default value is false.
|
||||||
*/
|
*/
|
||||||
canRemoveColumns?: boolean;
|
canRemoveColumns?: boolean;
|
||||||
|
/**
|
||||||
|
* Whether to show foreign keys tab. The default value is false.
|
||||||
|
*/
|
||||||
|
showForeignKeysTab?: boolean;
|
||||||
|
/**
|
||||||
|
* Additional foreign key properties. Common foreign key properties are handled by Azure Data Studio. see {@link TableForeignKeyProperty}
|
||||||
|
*/
|
||||||
|
additionalForeignKeyProperties?: DesignerDataPropertyInfo[];
|
||||||
|
/**
|
||||||
|
* The properties to be displayed in the foreign keys table. Default values are: Name, PrimaryKeyTable.
|
||||||
|
*/
|
||||||
|
foreignKeysTableProperties?: string[];
|
||||||
|
/**
|
||||||
|
* Whether user can add foreign keys. The default value is false.
|
||||||
|
*/
|
||||||
|
canAddForeignKeys?: boolean;
|
||||||
|
/**
|
||||||
|
* Whether user can remove foreign keys. The default value is false.
|
||||||
|
*/
|
||||||
|
canRemoveForeignKeys?: boolean;
|
||||||
|
/**
|
||||||
|
* Whether to show check constraints tab. The default value is false.
|
||||||
|
*/
|
||||||
|
showCheckConstraintsTab?: boolean;
|
||||||
|
/**
|
||||||
|
* Additional check constraint properties. Common check constraint properties are handled by Azure Data Studio. see {@link TableCheckConstraintProperty}
|
||||||
|
*/
|
||||||
|
additionalCheckConstraintProperties?: DesignerDataPropertyInfo[];
|
||||||
|
/**
|
||||||
|
* Whether user can add check constraints keys. The default value is false.
|
||||||
|
*/
|
||||||
|
canAddCheckConstraints?: boolean;
|
||||||
|
/**
|
||||||
|
* Whether user can remove check constraints. The default value is false.
|
||||||
|
*/
|
||||||
|
canRemoveCheckConstraints?: boolean;
|
||||||
|
/**
|
||||||
|
* Additional tabs.
|
||||||
|
*/
|
||||||
|
additionalTabs?: DesignerTab[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -572,6 +572,9 @@ export function createAdsApiFactory(accessor: ServicesAccessor): IAdsExtensionAp
|
|||||||
const designers: typeof azdata.designers = {
|
const designers: typeof azdata.designers = {
|
||||||
TableProperty: sqlExtHostTypes.designers.TableProperty,
|
TableProperty: sqlExtHostTypes.designers.TableProperty,
|
||||||
TableColumnProperty: sqlExtHostTypes.designers.TableColumnProperty,
|
TableColumnProperty: sqlExtHostTypes.designers.TableColumnProperty,
|
||||||
|
TableForeignKeyProperty: sqlExtHostTypes.designers.TableForeignKeyProperty,
|
||||||
|
ForeignKeyColumnMappingProperty: sqlExtHostTypes.designers.ForeignKeyColumnMappingProperty,
|
||||||
|
TableCheckConstraintProperty: sqlExtHostTypes.designers.TableCheckConstraintProperty,
|
||||||
DesignerEditType: sqlExtHostTypes.designers.DesignerEditType,
|
DesignerEditType: sqlExtHostTypes.designers.DesignerEditType,
|
||||||
openTableDesigner(providerId, tableInfo: azdata.designers.TableInfo): Promise<void> {
|
openTableDesigner(providerId, tableInfo: azdata.designers.TableInfo): Promise<void> {
|
||||||
return extHostDataProvider.$openTableDesigner(providerId, tableInfo);
|
return extHostDataProvider.$openTableDesigner(providerId, tableInfo);
|
||||||
|
|||||||
@@ -913,7 +913,9 @@ export namespace designers {
|
|||||||
Name = 'name',
|
Name = 'name',
|
||||||
Description = 'description',
|
Description = 'description',
|
||||||
Columns = 'columns',
|
Columns = 'columns',
|
||||||
Script = 'script'
|
Script = 'script',
|
||||||
|
ForeignKeys = 'foreignKeys',
|
||||||
|
CheckConstraints = 'checkConstraints',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum TableColumnProperty {
|
export enum TableColumnProperty {
|
||||||
@@ -927,6 +929,24 @@ export namespace designers {
|
|||||||
Scale = 'scale'
|
Scale = 'scale'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum TableForeignKeyProperty {
|
||||||
|
Name = 'name',
|
||||||
|
PrimaryKeyTable = 'primaryKeyTable',
|
||||||
|
OnDeleteAction = 'onDeleteAction',
|
||||||
|
OnUpdateAction = 'onUpdateAction',
|
||||||
|
Columns = 'columns'
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ForeignKeyColumnMappingProperty {
|
||||||
|
PrimaryKeyColumn = 'primaryKeyColumn',
|
||||||
|
ForeignKeyColumn = 'foreignKeyColumn'
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum TableCheckConstraintProperty {
|
||||||
|
Name = 'name',
|
||||||
|
Expression = 'expression'
|
||||||
|
}
|
||||||
|
|
||||||
export enum DesignerEditType {
|
export enum DesignerEditType {
|
||||||
Add = 0,
|
Add = 0,
|
||||||
Remove = 1,
|
Remove = 1,
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
optionsGetter: (item, column): string[] => {
|
optionsGetter: (item, column): string[] => {
|
||||||
return item[column.field].options;
|
return item[column.field].values;
|
||||||
},
|
},
|
||||||
editorStyler: (component) => {
|
editorStyler: (component) => {
|
||||||
this.styleComponent(component);
|
this.styleComponent(component);
|
||||||
@@ -503,6 +503,8 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
const groupNames = [];
|
const groupNames = [];
|
||||||
const componentsToCreate = !isMainView ? components.filter(component => component.showInPropertiesView !== false) : components;
|
const componentsToCreate = !isMainView ? components.filter(component => component.showInPropertiesView !== false) : components;
|
||||||
componentsToCreate.forEach(component => {
|
componentsToCreate.forEach(component => {
|
||||||
|
// Set the default group name if not set (undefined or null).
|
||||||
|
component.group = component.group || localize('designer.generalGroupName', "General");
|
||||||
if (groupNames.indexOf(component.group) === -1) {
|
if (groupNames.indexOf(component.group) === -1) {
|
||||||
groupNames.push(component.group);
|
groupNames.push(component.group);
|
||||||
}
|
}
|
||||||
@@ -518,7 +520,7 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
const groupHeader = container.appendChild(DOM.$('div.full-row.group-header'));
|
const groupHeader = container.appendChild(DOM.$('div.full-row.group-header'));
|
||||||
groupHeaders.push(groupHeader);
|
groupHeaders.push(groupHeader);
|
||||||
this.styleGroupHeader(groupHeader);
|
this.styleGroupHeader(groupHeader);
|
||||||
groupHeader.innerText = group ?? localize('designer.generalGroupName', "General");
|
groupHeader.innerText = group;
|
||||||
componentsToCreate.forEach(component => {
|
componentsToCreate.forEach(component => {
|
||||||
if (component.group === group) {
|
if (component.group === group) {
|
||||||
uiComponents.push(this.createComponent(container, component, parentPath, componentMap, setWidth, isMainView));
|
uiComponents.push(this.createComponent(container, component, parentPath, componentMap, setWidth, isMainView));
|
||||||
@@ -565,7 +567,7 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
container.appendChild(DOM.$('')).appendChild(DOM.$('span.component-label')).innerText = componentDefinition.componentProperties?.title ?? '';
|
container.appendChild(DOM.$('')).appendChild(DOM.$('span.component-label')).innerText = componentDefinition.componentProperties?.title ?? '';
|
||||||
const dropdownContainer = container.appendChild(DOM.$(''));
|
const dropdownContainer = container.appendChild(DOM.$(''));
|
||||||
const dropdownProperties = componentDefinition.componentProperties as DropDownProperties;
|
const dropdownProperties = componentDefinition.componentProperties as DropDownProperties;
|
||||||
const dropdown = new SelectBox(dropdownProperties.values as string[], undefined, this._contextViewProvider, undefined);
|
const dropdown = new SelectBox(dropdownProperties.values as string[] || [], undefined, this._contextViewProvider, undefined);
|
||||||
dropdown.render(dropdownContainer);
|
dropdown.render(dropdownContainer);
|
||||||
dropdown.selectElem.style.height = '25px';
|
dropdown.selectElem.style.height = '25px';
|
||||||
dropdown.onDidSelect((e) => {
|
dropdown.onDidSelect((e) => {
|
||||||
@@ -579,12 +581,10 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
component = dropdown;
|
component = dropdown;
|
||||||
break;
|
break;
|
||||||
case 'checkbox':
|
case 'checkbox':
|
||||||
container.appendChild(DOM.$('')); // label container place holder
|
container.appendChild(DOM.$('')).appendChild(DOM.$('span.component-label')).innerText = componentDefinition.componentProperties?.title ?? '';
|
||||||
const checkboxContainer = container.appendChild(DOM.$(''));
|
const checkboxContainer = container.appendChild(DOM.$(''));
|
||||||
const checkboxProperties = componentDefinition.componentProperties as CheckBoxProperties;
|
const checkboxProperties = componentDefinition.componentProperties as CheckBoxProperties;
|
||||||
const checkbox = new Checkbox(checkboxContainer, {
|
const checkbox = new Checkbox(checkboxContainer, { label: '', ariaLabel: checkboxProperties.title });
|
||||||
label: checkboxProperties.title
|
|
||||||
});
|
|
||||||
checkbox.onChange((newValue) => {
|
checkbox.onChange((newValue) => {
|
||||||
this.handleEdit({ type: DesignerEditType.Update, path: propertyPath, value: newValue });
|
this.handleEdit({ type: DesignerEditType.Update, path: propertyPath, value: newValue });
|
||||||
});
|
});
|
||||||
@@ -600,7 +600,7 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
container.appendChild(DOM.$('.full-row')).appendChild(DOM.$('span.component-label')).innerText = componentDefinition.componentProperties?.title ?? '';
|
container.appendChild(DOM.$('.full-row')).appendChild(DOM.$('span.component-label')).innerText = componentDefinition.componentProperties?.title ?? '';
|
||||||
}
|
}
|
||||||
const tableProperties = componentDefinition.componentProperties as DesignerTableProperties;
|
const tableProperties = componentDefinition.componentProperties as DesignerTableProperties;
|
||||||
if (tableProperties.canAddRows !== false) {
|
if (tableProperties.canAddRows) {
|
||||||
const buttonContainer = container.appendChild(DOM.$('.full-row')).appendChild(DOM.$('.add-row-button-container'));
|
const buttonContainer = container.appendChild(DOM.$('.full-row')).appendChild(DOM.$('.add-row-button-container'));
|
||||||
const addNewText = localize('designer.newRowText', "Add New");
|
const addNewText = localize('designer.newRowText', "Add New");
|
||||||
const addRowButton = new Button(buttonContainer, {
|
const addRowButton = new Button(buttonContainer, {
|
||||||
@@ -673,7 +673,7 @@ export class Designer extends Disposable implements IThemable {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (tableProperties.canRemoveRows !== false) {
|
if (tableProperties.canRemoveRows) {
|
||||||
const deleteRowColumn = new ButtonColumn({
|
const deleteRowColumn = new ButtonColumn({
|
||||||
id: 'deleteRow',
|
id: 'deleteRow',
|
||||||
iconCssClass: Codicon.trash.classNames,
|
iconCssClass: Codicon.trash.classNames,
|
||||||
|
|||||||
@@ -49,12 +49,11 @@ export class DesignerPropertiesPane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public updateDescription(definition: DesignerDataPropertyInfo) {
|
public updateDescription(definition: DesignerDataPropertyInfo) {
|
||||||
const title: string = definition.componentProperties.title;
|
this._descriptionContainer.style.display = 'block';
|
||||||
const description: string = definition.description;
|
const title: string = definition.componentProperties.title ?? '';
|
||||||
if (title && description) {
|
const description: string = definition.description ?? '';
|
||||||
this._descriptionTitleContainer.innerText = title;
|
this._descriptionTitleContainer.innerText = title;
|
||||||
this._descriptionTextContainer.innerText = description;
|
this._descriptionTextContainer.innerText = description;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public clear(): void {
|
public clear(): void {
|
||||||
@@ -89,5 +88,6 @@ export class DesignerPropertiesPane {
|
|||||||
this._componentMap.forEach((value) => {
|
this._componentMap.forEach((value) => {
|
||||||
this._setComponentValue(value.defintion, value.component, item.viewModel);
|
this._setComponentValue(value.defintion, value.component, item.viewModel);
|
||||||
});
|
});
|
||||||
|
this._descriptionContainer.style.display = 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,7 +79,6 @@
|
|||||||
|
|
||||||
.designer-component .add-row-button-container {
|
.designer-component .add-row-button-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: row-reverse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.designer-component .add-row-button-container .codicon.add-row-button {
|
.designer-component .add-row-button-container .codicon.add-row-button {
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import { localize } from 'vs/nls';
|
|||||||
import { designers } from 'sql/workbench/api/common/sqlExtHostTypes';
|
import { designers } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||||
import { Emitter, Event } from 'vs/base/common/event';
|
import { Emitter, Event } from 'vs/base/common/event';
|
||||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||||
import { ColumnPropertyDescriptions, TablePropertyDescriptions } from 'sql/workbench/services/tableDesigner/browser/tableDesignerStrings';
|
|
||||||
import { deepClone, equals } from 'vs/base/common/objects';
|
import { deepClone, equals } from 'vs/base/common/objects';
|
||||||
|
|
||||||
export class TableDesignerComponentInput implements DesignerComponentInput {
|
export class TableDesignerComponentInput implements DesignerComponentInput {
|
||||||
@@ -146,11 +145,46 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
|||||||
this._originalViewModel = deepClone(this._viewModel);
|
this._originalViewModel = deepClone(this._viewModel);
|
||||||
this.setDefaultData();
|
this.setDefaultData();
|
||||||
|
|
||||||
|
const tabs = [];
|
||||||
|
|
||||||
|
if (designerInfo.view.showColumnsTab) {
|
||||||
|
tabs.push(this.getColumnsTab(designerInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (designerInfo.view.showForeignKeysTab) {
|
||||||
|
tabs.push(this.getForeignKeysTab(designerInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (designerInfo.view.showCheckConstraintsTab) {
|
||||||
|
tabs.push(this.getCheckConstraintsTab(designerInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (designerInfo.view.additionalTabs) {
|
||||||
|
tabs.push(...designerInfo.view.additionalTabs);
|
||||||
|
}
|
||||||
|
|
||||||
|
tabs.push(this.getGeneralTab(designerInfo));
|
||||||
|
|
||||||
|
this._view = {
|
||||||
|
components: [{
|
||||||
|
componentType: 'input',
|
||||||
|
propertyName: designers.TableColumnProperty.Name,
|
||||||
|
description: localize('designer.table.description.name', "The name of the table object."),
|
||||||
|
componentProperties: {
|
||||||
|
title: localize('tableDesigner.nameTitle', "Table name"),
|
||||||
|
width: 200
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
tabs: tabs
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private getGeneralTab(designerInfo: azdata.designers.TableDesignerInfo): DesignerTab {
|
||||||
const generalTabComponents: DesignerDataPropertyInfo[] = [
|
const generalTabComponents: DesignerDataPropertyInfo[] = [
|
||||||
{
|
{
|
||||||
componentType: 'dropdown',
|
componentType: 'dropdown',
|
||||||
propertyName: designers.TableProperty.Schema,
|
propertyName: designers.TableProperty.Schema,
|
||||||
description: TablePropertyDescriptions.SCHEMA,
|
description: localize('designer.table.description.schema', "The schema that contains the table."),
|
||||||
componentProperties: <DropDownProperties>{
|
componentProperties: <DropDownProperties>{
|
||||||
title: localize('tableDesigner.schemaTitle', "Schema"),
|
title: localize('tableDesigner.schemaTitle', "Schema"),
|
||||||
values: designerInfo.schemas
|
values: designerInfo.schemas
|
||||||
@@ -158,7 +192,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
|||||||
}, {
|
}, {
|
||||||
componentType: 'input',
|
componentType: 'input',
|
||||||
propertyName: designers.TableProperty.Description,
|
propertyName: designers.TableProperty.Description,
|
||||||
description: TablePropertyDescriptions.DESCRIPTION,
|
description: localize('designer.table.description.description', "Description for the table."),
|
||||||
componentProperties: {
|
componentProperties: {
|
||||||
title: localize('tableDesigner.descriptionTitle', "Description")
|
title: localize('tableDesigner.descriptionTitle', "Description")
|
||||||
}
|
}
|
||||||
@@ -169,16 +203,19 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
|||||||
generalTabComponents.push(...designerInfo.view.additionalTableProperties);
|
generalTabComponents.push(...designerInfo.view.additionalTableProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
const generalTab = <DesignerTab>{
|
return <DesignerTab>{
|
||||||
title: localize('tableDesigner.generalTab', "General"),
|
title: localize('tableDesigner.generalTab', "General"),
|
||||||
components: generalTabComponents
|
components: generalTabComponents
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private getColumnsTab(designerInfo: azdata.designers.TableDesignerInfo): DesignerTab {
|
||||||
|
|
||||||
const columnProperties: DesignerDataPropertyInfo[] = [
|
const columnProperties: DesignerDataPropertyInfo[] = [
|
||||||
{
|
{
|
||||||
componentType: 'input',
|
componentType: 'input',
|
||||||
propertyName: designers.TableColumnProperty.Name,
|
propertyName: designers.TableColumnProperty.Name,
|
||||||
description: ColumnPropertyDescriptions.NAME,
|
description: localize('designer.column.description.name', "The name of the column object."),
|
||||||
componentProperties: {
|
componentProperties: {
|
||||||
title: localize('tableDesigner.columnNameTitle', "Name"),
|
title: localize('tableDesigner.columnNameTitle', "Name"),
|
||||||
width: 150
|
width: 150
|
||||||
@@ -186,7 +223,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
|||||||
}, {
|
}, {
|
||||||
componentType: 'dropdown',
|
componentType: 'dropdown',
|
||||||
propertyName: designers.TableColumnProperty.Type,
|
propertyName: designers.TableColumnProperty.Type,
|
||||||
description: ColumnPropertyDescriptions.DATA_TYPE,
|
description: localize('designer.column.description.dataType', "Displays the data type name for the column"),
|
||||||
componentProperties: {
|
componentProperties: {
|
||||||
title: localize('tableDesigner.columnTypeTitle', "Type"),
|
title: localize('tableDesigner.columnTypeTitle', "Type"),
|
||||||
width: 100,
|
width: 100,
|
||||||
@@ -195,7 +232,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
|||||||
}, {
|
}, {
|
||||||
componentType: 'input',
|
componentType: 'input',
|
||||||
propertyName: designers.TableColumnProperty.Length,
|
propertyName: designers.TableColumnProperty.Length,
|
||||||
description: ColumnPropertyDescriptions.LENGTH,
|
description: localize('designer.column.description.length', "The maximum length (in characters) that can be stored in this database object."),
|
||||||
componentProperties: {
|
componentProperties: {
|
||||||
title: localize('tableDesigner.columnLengthTitle', "Length"),
|
title: localize('tableDesigner.columnLengthTitle', "Length"),
|
||||||
width: 60
|
width: 60
|
||||||
@@ -203,7 +240,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
|||||||
}, {
|
}, {
|
||||||
componentType: 'input',
|
componentType: 'input',
|
||||||
propertyName: designers.TableColumnProperty.DefaultValue,
|
propertyName: designers.TableColumnProperty.DefaultValue,
|
||||||
description: ColumnPropertyDescriptions.DEFAULT_VALUE_OR_BINDING,
|
description: localize('designer.column.description.defaultValueBinding', "A predefined global default value for the column or binding."),
|
||||||
componentProperties: {
|
componentProperties: {
|
||||||
title: localize('tableDesigner.columnDefaultValueTitle', "Default Value"),
|
title: localize('tableDesigner.columnDefaultValueTitle', "Default Value"),
|
||||||
width: 150
|
width: 150
|
||||||
@@ -211,21 +248,21 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
|||||||
}, {
|
}, {
|
||||||
componentType: 'checkbox',
|
componentType: 'checkbox',
|
||||||
propertyName: designers.TableColumnProperty.AllowNulls,
|
propertyName: designers.TableColumnProperty.AllowNulls,
|
||||||
description: ColumnPropertyDescriptions.ALLOW_NULLS,
|
description: localize('designer.column.description.allowNulls', "Specifies whether the column may have a NULL value."),
|
||||||
componentProperties: {
|
componentProperties: {
|
||||||
title: localize('tableDesigner.columnAllowNullTitle', "Allow Nulls"),
|
title: localize('tableDesigner.columnAllowNullTitle', "Allow Nulls"),
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
componentType: 'checkbox',
|
componentType: 'checkbox',
|
||||||
propertyName: designers.TableColumnProperty.IsPrimaryKey,
|
propertyName: designers.TableColumnProperty.IsPrimaryKey,
|
||||||
description: ColumnPropertyDescriptions.PRIMARY_KEY,
|
description: localize('designer.column.description.primaryKey', "Specifies whether the column is included in the primary key for the table."),
|
||||||
componentProperties: {
|
componentProperties: {
|
||||||
title: localize('tableDesigner.columnIsPrimaryKeyTitle', "Primary Key"),
|
title: localize('tableDesigner.columnIsPrimaryKeyTitle', "Primary Key"),
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
componentType: 'input',
|
componentType: 'input',
|
||||||
propertyName: designers.TableColumnProperty.Precision,
|
propertyName: designers.TableColumnProperty.Precision,
|
||||||
description: ColumnPropertyDescriptions.PRECISION,
|
description: localize('designer.column.description.precision', "For numeric data, the maximum number of decimal digits that can be stored in this database object."),
|
||||||
componentProperties: {
|
componentProperties: {
|
||||||
title: localize('tableDesigner.columnPrecisionTitle', "Precision"),
|
title: localize('tableDesigner.columnPrecisionTitle', "Precision"),
|
||||||
width: 60
|
width: 60
|
||||||
@@ -233,7 +270,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
|||||||
}, {
|
}, {
|
||||||
componentType: 'input',
|
componentType: 'input',
|
||||||
propertyName: designers.TableColumnProperty.Scale,
|
propertyName: designers.TableColumnProperty.Scale,
|
||||||
description: ColumnPropertyDescriptions.NAME,
|
description: localize('designer.column.description.scale', "For numeric data, the maximum number of decimal digits that can be stored in this database object to the right of decimal point."),
|
||||||
componentProperties: {
|
componentProperties: {
|
||||||
title: localize('tableDesigner.columnScaleTitle', "Scale"),
|
title: localize('tableDesigner.columnScaleTitle', "Scale"),
|
||||||
width: 60
|
width: 60
|
||||||
@@ -256,7 +293,7 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
|||||||
designers.TableColumnProperty.DefaultValue,
|
designers.TableColumnProperty.DefaultValue,
|
||||||
];
|
];
|
||||||
|
|
||||||
const columnsTab = <DesignerTab>{
|
return <DesignerTab>{
|
||||||
title: localize('tableDesigner.columnsTabTitle', "Columns"),
|
title: localize('tableDesigner.columnsTabTitle', "Columns"),
|
||||||
components: [
|
components: [
|
||||||
{
|
{
|
||||||
@@ -274,26 +311,154 @@ export class TableDesignerComponentInput implements DesignerComponentInput {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const tabs = [columnsTab, generalTab];
|
private getForeignKeysTab(designerInfo: azdata.designers.TableDesignerInfo): DesignerTab {
|
||||||
if (designerInfo.view.additionalTabs) {
|
|
||||||
tabs.push(...tabs);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._view = {
|
const foreignKeyColumnMappingProperties: DesignerDataPropertyInfo[] = [
|
||||||
components: [{
|
{
|
||||||
componentType: 'input',
|
componentType: 'dropdown',
|
||||||
propertyName: designers.TableColumnProperty.Name,
|
propertyName: designers.ForeignKeyColumnMappingProperty.ForeignKeyColumn,
|
||||||
description: TablePropertyDescriptions.NAME,
|
|
||||||
componentProperties: {
|
componentProperties: {
|
||||||
title: localize('tableDesigner.nameTitle', "Table name"),
|
title: localize('tableDesigner.foreignKeyColumn', "Foreign Key Column"),
|
||||||
|
width: 150
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentType: 'dropdown',
|
||||||
|
propertyName: designers.ForeignKeyColumnMappingProperty.PrimaryKeyColumn,
|
||||||
|
componentProperties: {
|
||||||
|
title: localize('tableDesigner.primaryKeyColumn', "Primary Key Column"),
|
||||||
|
width: 150
|
||||||
|
}
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const foreignKeyProperties: DesignerDataPropertyInfo[] = [
|
||||||
|
{
|
||||||
|
componentType: 'input',
|
||||||
|
propertyName: designers.TableForeignKeyProperty.Name,
|
||||||
|
description: localize('designer.foreignkey.description.name', "The name of the foreign key."),
|
||||||
|
componentProperties: {
|
||||||
|
title: localize('tableDesigner.foreignKeyNameTitle', "Name"),
|
||||||
|
width: 300
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentType: 'dropdown',
|
||||||
|
propertyName: designers.TableForeignKeyProperty.PrimaryKeyTable,
|
||||||
|
description: localize('designer.foreignkey.description.primaryKeyTable', "The table which contains the primary or unique key column."),
|
||||||
|
componentProperties: {
|
||||||
|
title: localize('tableDesigner.PrimaryKeyTableName', "Primary Key Table"),
|
||||||
width: 200
|
width: 200
|
||||||
}
|
}
|
||||||
}],
|
},
|
||||||
tabs: tabs
|
{
|
||||||
|
componentType: 'dropdown',
|
||||||
|
propertyName: designers.TableForeignKeyProperty.OnUpdateAction,
|
||||||
|
description: localize('designer.foreignkey.description.onUpdateAction', "The behavior when a user tries to update a row with data that is involved in a foreign key relationship."),
|
||||||
|
componentProperties: {
|
||||||
|
title: localize('tableDesigner.foreignKeyOnUpdateAction', "On Update Action"),
|
||||||
|
width: 100
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentType: 'dropdown',
|
||||||
|
propertyName: designers.TableForeignKeyProperty.OnDeleteAction,
|
||||||
|
description: localize('designer.foreignkey.description.onDeleteAction', "The behavior when a user tries to delete a row with data that is involved in a foreign key relationship."),
|
||||||
|
componentProperties: {
|
||||||
|
title: localize('tableDesigner.foreignKeyOnDeleteAction', "On Delete Action"),
|
||||||
|
width: 100
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentType: 'table',
|
||||||
|
propertyName: designers.TableForeignKeyProperty.Columns,
|
||||||
|
group: localize('tableDesigner.foreignKeyColumns', "Column Mapping"),
|
||||||
|
componentProperties: <DesignerTableProperties>{
|
||||||
|
ariaLabel: localize('tableDesigner.foreignKeyColumns', "Column Mapping"),
|
||||||
|
columns: [designers.ForeignKeyColumnMappingProperty.ForeignKeyColumn, designers.ForeignKeyColumnMappingProperty.PrimaryKeyColumn],
|
||||||
|
itemProperties: foreignKeyColumnMappingProperties,
|
||||||
|
objectTypeDisplayName: '',
|
||||||
|
canAddRows: designerInfo.view.canAddForeignKeys,
|
||||||
|
canRemoveRows: designerInfo.view.canRemoveColumns,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
if (designerInfo.view.additionalForeignKeyProperties) {
|
||||||
|
foreignKeyProperties.push(...designerInfo.view.additionalForeignKeyProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
const foreignKeysTableProperties = designerInfo.view.foreignKeysTableProperties?.length > 0 ? designerInfo.view.foreignKeysTableProperties : [
|
||||||
|
designers.TableForeignKeyProperty.Name,
|
||||||
|
designers.TableForeignKeyProperty.PrimaryKeyTable,
|
||||||
|
];
|
||||||
|
|
||||||
|
return <DesignerTab>{
|
||||||
|
title: localize('tableDesigner.foreignKeysTabTitle', "Foreign Keys"),
|
||||||
|
components: [
|
||||||
|
{
|
||||||
|
componentType: 'table',
|
||||||
|
propertyName: designers.TableProperty.ForeignKeys,
|
||||||
|
showInPropertiesView: false,
|
||||||
|
componentProperties: <DesignerTableProperties>{
|
||||||
|
ariaLabel: localize('tableDesigner.foreignKeysTabTitle', "Foreign Keys"),
|
||||||
|
columns: foreignKeysTableProperties,
|
||||||
|
itemProperties: foreignKeyProperties,
|
||||||
|
objectTypeDisplayName: localize('tableDesigner.ForeignKeyTypeName', "Foreign Key"),
|
||||||
|
canAddRows: designerInfo.view.canAddForeignKeys,
|
||||||
|
canRemoveRows: designerInfo.view.canRemoveForeignKeys
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getCheckConstraintsTab(designerInfo: azdata.designers.TableDesignerInfo): DesignerTab {
|
||||||
|
const checkConstraintProperties: DesignerDataPropertyInfo[] = [
|
||||||
|
{
|
||||||
|
componentType: 'input',
|
||||||
|
propertyName: designers.TableCheckConstraintProperty.Name,
|
||||||
|
description: localize('designer.checkConstraint.description.name', "The name of the check constraint."),
|
||||||
|
componentProperties: {
|
||||||
|
title: localize('tableDesigner.checkConstraintNameTitle', "Name"),
|
||||||
|
width: 200
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
componentType: 'input',
|
||||||
|
propertyName: designers.TableCheckConstraintProperty.Expression,
|
||||||
|
description: localize('designer.checkConstraint.description.expression', "The expression defining the check constraint."),
|
||||||
|
componentProperties: {
|
||||||
|
title: localize('tableDesigner.checkConstraintExpressionTitle', "Expression"),
|
||||||
|
width: 300
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
if (designerInfo.view.additionalCheckConstraintProperties) {
|
||||||
|
checkConstraintProperties.push(...designerInfo.view.additionalCheckConstraintProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <DesignerTab>{
|
||||||
|
title: localize('tableDesigner.checkConstraintsTabTitle', "Check Constraints"),
|
||||||
|
components: [
|
||||||
|
{
|
||||||
|
componentType: 'table',
|
||||||
|
propertyName: designers.TableProperty.CheckConstraints,
|
||||||
|
showInPropertiesView: false,
|
||||||
|
componentProperties: <DesignerTableProperties>{
|
||||||
|
ariaLabel: localize('tableDesigner.checkConstraintsTabTitle', "Check Constraints"),
|
||||||
|
columns: [designers.TableCheckConstraintProperty.Name, designers.TableCheckConstraintProperty.Expression],
|
||||||
|
itemProperties: checkConstraintProperties,
|
||||||
|
objectTypeDisplayName: localize('tableDesigner.checkConstraintTypeName', "Check Constraint"),
|
||||||
|
canAddRows: designerInfo.view.canAddCheckConstraints,
|
||||||
|
canRemoveRows: designerInfo.view.canRemoveCheckConstraints
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
private setDefaultData(): void {
|
private setDefaultData(): void {
|
||||||
const properties = Object.keys(this._viewModel);
|
const properties = Object.keys(this._viewModel);
|
||||||
this.setDefaultInputData(properties, designers.TableProperty.Name);
|
this.setDefaultInputData(properties, designers.TableProperty.Name);
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
import { localize } from 'vs/nls';
|
|
||||||
|
|
||||||
export const TablePropertyDescriptions = {
|
|
||||||
NAME: localize('designer.table.description.name', "The name of the table object."),
|
|
||||||
DESCRIPTION: localize('designer.table.description.description', "Description for the table."),
|
|
||||||
SCHEMA: localize('designer.table.description.schema', "The schema that contains the table.")
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ColumnPropertyDescriptions = {
|
|
||||||
NAME: localize('designer.column.description.name', "The name of the column object."),
|
|
||||||
ALLOW_NULLS: localize('designer.column.description.allowNulls', "Specifies whether the column may have a NULL value."),
|
|
||||||
DATA_TYPE: localize('designer.column.description.dataType', "Displays the data type name for the column"),
|
|
||||||
DEFAULT_VALUE_OR_BINDING: localize('designer.column.description.defaultValueBinding', "A predefined global default value for the column or binding."),
|
|
||||||
DESCRIPTION: localize('designer.column.description.description', "Description for the column."),
|
|
||||||
LENGTH: localize('designer.column.description.length', "The maximum length (in characters) that can be stored in this database object."),
|
|
||||||
PRECISION: localize('designer.column.description.precision', "For numeric data, the maximum number of decimal digits that can be stored in this database object."),
|
|
||||||
PRIMARY_KEY: localize('designer.column.description.primaryKey', "Specifies whether the column is included in the primary key for the table.")
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user