diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs index b2241352..5cb28ee4 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs @@ -8509,6 +8509,78 @@ namespace Microsoft.SqlTools.ServiceLayer } } + public static string TableDesignerIsEnabledPropertyTitle + { + get + { + return Keys.GetString(Keys.TableDesignerIsEnabledPropertyTitle); + } + } + + public static string ForeignKeyIsEnabledDescription + { + get + { + return Keys.GetString(Keys.ForeignKeyIsEnabledDescription); + } + } + + public static string ForeignKeyIsNotForReplicationTitle + { + get + { + return Keys.GetString(Keys.ForeignKeyIsNotForReplicationTitle); + } + } + + public static string ForeignKeyIsNotForReplicationDescription + { + get + { + return Keys.GetString(Keys.ForeignKeyIsNotForReplicationDescription); + } + } + + public static string SqlForeignKeyAction_NoAction + { + get + { + return Keys.GetString(Keys.SqlForeignKeyAction_NoAction); + } + } + + public static string SqlForeignKeyAction_Cascade + { + get + { + return Keys.GetString(Keys.SqlForeignKeyAction_Cascade); + } + } + + public static string SqlForeignKeyAction_SetNull + { + get + { + return Keys.GetString(Keys.SqlForeignKeyAction_SetNull); + } + } + + public static string SqlForeignKeyAction_SetDefault + { + get + { + return Keys.GetString(Keys.SqlForeignKeyAction_SetDefault); + } + } + + public static string CheckConstraintIsEnabledDescription + { + get + { + return Keys.GetString(Keys.CheckConstraintIsEnabledDescription); + } + } + public static string ConnectionServiceListDbErrorNotConnected(string uri) { return Keys.GetString(Keys.ConnectionServiceListDbErrorNotConnected, uri); @@ -8794,6 +8866,11 @@ namespace Microsoft.SqlTools.ServiceLayer return Keys.GetString(Keys.InvalidTableEditPathException, path, editType); } + public static string UnKnownSqlForeignKeyAction(string name) + { + return Keys.GetString(Keys.UnKnownSqlForeignKeyAction, name); + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Keys { @@ -12153,6 +12230,36 @@ namespace Microsoft.SqlTools.ServiceLayer public const string TableColumnIdentitySeedPropertyDescription = "TableColumnIdentitySeedPropertyDescription"; + public const string TableDesignerIsEnabledPropertyTitle = "TableDesignerIsEnabledPropertyTitle"; + + + public const string ForeignKeyIsEnabledDescription = "ForeignKeyIsEnabledDescription"; + + + public const string ForeignKeyIsNotForReplicationTitle = "ForeignKeyIsNotForReplicationTitle"; + + + public const string ForeignKeyIsNotForReplicationDescription = "ForeignKeyIsNotForReplicationDescription"; + + + public const string SqlForeignKeyAction_NoAction = "SqlForeignKeyAction_NoAction"; + + + public const string SqlForeignKeyAction_Cascade = "SqlForeignKeyAction_Cascade"; + + + public const string SqlForeignKeyAction_SetNull = "SqlForeignKeyAction_SetNull"; + + + public const string SqlForeignKeyAction_SetDefault = "SqlForeignKeyAction_SetDefault"; + + + public const string UnKnownSqlForeignKeyAction = "UnKnownSqlForeignKeyAction"; + + + public const string CheckConstraintIsEnabledDescription = "CheckConstraintIsEnabledDescription"; + + private Keys() { } diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx index d031a41b..a2e5b6db 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx @@ -4643,4 +4643,45 @@ Displays the initial row value for an identity column. + + Is Enabled + + + + Specifies whether the foreign key is Enabled + + + + Not For Replication + + + + Enables or disables an IDENTITY constraint for data inserted by a replication process. + + + + No Action + + + + Cascade + + + + Set Null + + + + Set Default + + + + '{0}' is not a supported SqlForeignKeyAction. + . + Parameters: 0 - name (string) + + + Specifies whether the check constraint is Enabled + + diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings index b8ce42a0..72c0a886 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings @@ -2231,3 +2231,13 @@ TableColumnIdentityIncrementPropertyTitle = Identity Increment TableColumnIdentityIncrementPropertyDescription = Displays the value added to the maximum existing row identity value when generating the next identity value. TableColumnIdentitySeedPropertyTitle = Identity Seed TableColumnIdentitySeedPropertyDescription = Displays the initial row value for an identity column. +TableDesignerIsEnabledPropertyTitle = Is Enabled +ForeignKeyIsEnabledDescription = Specifies whether the foreign key is Enabled +ForeignKeyIsNotForReplicationTitle = Not For Replication +ForeignKeyIsNotForReplicationDescription = Enables or disables an IDENTITY constraint for data inserted by a replication process. +SqlForeignKeyAction_NoAction = No Action +SqlForeignKeyAction_Cascade = Cascade +SqlForeignKeyAction_SetNull = Set Null +SqlForeignKeyAction_SetDefault = Set Default +UnKnownSqlForeignKeyAction(string name) = '{0}' is not a supported SqlForeignKeyAction. +CheckConstraintIsEnabledDescription = Specifies whether the check constraint is Enabled diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf index ef980a78..cb483dde 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf @@ -5645,6 +5645,57 @@ . Parameters: 0 - actual (string), 1 - estimated (string), 2 - percent (decimal) + + Is Enabled + Is Enabled + + + + Specifies whether the foreign key is Enabled + Specifies whether the foreign key is Enabled + + + + Not For Replication + Not For Replication + + + + Enables or disables an IDENTITY constraint for data inserted by a replication process. + Enables or disables an IDENTITY constraint for data inserted by a replication process. + + + + No Action + No Action + + + + Cascade + Cascade + + + + Set Null + Set Null + + + + Set Default + Set Default + + + + '{0}' is not a supported SqlForeignKeyAction. + '{0}' is not a supported SqlForeignKeyAction. + . + Parameters: 0 - name (string) + + + Specifies whether the check constraint is Enabled + Specifies whether the check constraint is Enabled + + \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Constants.cs b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Constants.cs index b1267acb..eba038b5 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Constants.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Constants.cs @@ -11,6 +11,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner public const string Schema = "schema"; public const string Description = "description"; public const string Columns = "columns"; + public const string ForeignKeys = "foreignKeys"; } public static class TableColumnPropertyNames @@ -27,4 +28,28 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner public const string IdentityIncrement = "identityIncrement"; public const string IdentitySeed = "identitySeed"; } + + public static class ForeignKeyPropertyNames + { + public const string Name = "name"; + public const string Enabled = "enabled"; + public const string OnDeleteAction = "onDeleteAction"; + public const string OnUpdateAction = "onUpdateAction"; + public const string ColumnMapping = "columnMapping"; + public const string PrimaryKeyTable = "primaryKeyTable"; + public const string IsNotForReplication = "isNotForReplication"; + } + + public static class CheckConstraintPropertyNames + { + public const string Name = "name"; + public const string Enabled = "enabled"; + public const string Expression = "expression"; + } + + public static class ForeignKeyColumnMappingPropertyNames + { + public const string PrimaryKeyColumn = "primaryKeyColumn"; + public const string ForeignKeyColumn = "foreignKeyColumn"; + } } \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/Components/TableProperties.cs b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/Components/TableProperties.cs index 00b8263c..a70f697c 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/Components/TableProperties.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/Components/TableProperties.cs @@ -12,7 +12,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts /// /// Table component properties /// - public abstract class TableComponentProperties : ComponentPropertiesBase where T : ObjectViewModelBase + public class TableComponentProperties : ComponentPropertiesBase { /// /// The column names to be displayed @@ -33,32 +33,5 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts /// The object list. /// public List Data { get; set; } = new List(); - - /// - /// Add a new object into the Data property - /// - public void AddNew() - { - this.Data.Add(this.CreateNew(this.GetDefaultNewObjectName())); - } - - protected abstract string NewObjectNamePrefix { get; } - - protected abstract T CreateNew(string name); - - /// - /// Get the next available name for a new item - /// - protected string GetDefaultNewObjectName() - { - int i = 1; - string newName; - do - { - newName = string.Format("{0}{1}", this.NewObjectNamePrefix, i); - i++; - } while (this.Data?.AsEnumerable().FirstOrDefault(obj => string.Equals(obj.Name?.Value, newName, StringComparison.InvariantCultureIgnoreCase)) != null); - return newName; - } } } \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/DesignerDataPropertyInfo.cs b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/DesignerDataPropertyInfo.cs index 3ca91355..6d134873 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/DesignerDataPropertyInfo.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/DesignerDataPropertyInfo.cs @@ -37,7 +37,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts /// /// The name of the group the property will be placed in whe displayed in /// - public bool ShowInPropertiesView { get; set; } + public bool ShowInPropertiesView { get; set; } = true; /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/TableDesignerView.cs b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/TableDesignerView.cs index 202b2a85..52b2c551 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/TableDesignerView.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/TableDesignerView.cs @@ -14,13 +14,17 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts public class TableDesignerView { public List AdditionalTableProperties { get; set; } = new List(); + public BuiltinTableOptions ColumnTableOptions { get; set; } = new BuiltinTableOptions(); + public BuiltinTableOptions ForeignKeyTableOptions { get; set; } = new BuiltinTableOptions(); + public BuiltinTableOptions CheckConstraintTableOptions { get; set; } = new BuiltinTableOptions(); + } - public List AdditionalTableColumnProperties { get; set; } = new List(); - - public List ColumnsTableProperties { get; set; } = new List(); - - public bool CanAddColumns { get; set; } - - public bool CanRemoveColumns { get; set; } + public class BuiltinTableOptions + { + public bool ShowTable { get; set; } = true; + public List PropertiesToDisplay { get; set; } = new List(); + public bool canAddRows { get; set; } = true; + public bool canRemoveRows { get; set; } = true; + public List AdditionalProperties { get; set; } = new List(); } } \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/ViewModel/CheckConstraintViewModel.cs b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/ViewModel/CheckConstraintViewModel.cs new file mode 100644 index 00000000..1be45252 --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/ViewModel/CheckConstraintViewModel.cs @@ -0,0 +1,18 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using Newtonsoft.Json; + +namespace Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts +{ + /// + /// The view model of check constraint + /// + public class CheckConstraintViewModel : ObjectViewModelBase + { + public InputBoxProperties Expression { get; set; } = new InputBoxProperties(); + public CheckBoxProperties Enabled { get; set; } = new CheckBoxProperties(); + } +} \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/ViewModel/ForeignKeyViewModel.cs b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/ViewModel/ForeignKeyViewModel.cs new file mode 100644 index 00000000..77c222c1 --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/ViewModel/ForeignKeyViewModel.cs @@ -0,0 +1,34 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using Newtonsoft.Json; + +namespace Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts +{ + /// + /// The view model of foreign key. + /// + public class ForeignKeyViewModel : ObjectViewModelBase + { + public CheckBoxProperties Enabled { get; set; } = new CheckBoxProperties(); + + public DropdownProperties OnDeleteAction { get; set; } = new DropdownProperties(); + + public DropdownProperties OnUpdateAction { get; set; } = new DropdownProperties(); + + public DropdownProperties PrimaryKeyTable { get; set; } = new DropdownProperties(); + + public CheckBoxProperties IsNotForReplication { get; set; } = new CheckBoxProperties(); + + public TableComponentProperties Columns { get; set; } = new TableComponentProperties(); + } + + public class ForeignKeyColumnMapping + { + public DropdownProperties PrimaryKeyColumn { get; set; } = new DropdownProperties(); + + public DropdownProperties ForeignKeyColumn { get; set; } = new DropdownProperties(); + } +} \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/ViewModel/TableViewModel.cs b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/ViewModel/TableViewModel.cs index ca37b054..61271f39 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/ViewModel/TableViewModel.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/Contracts/ViewModel/TableViewModel.cs @@ -16,22 +16,12 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts public InputBoxProperties Description { get; set; } = new InputBoxProperties(); - public TableColumnCollection Columns { get; set; } = new TableColumnCollection(); + public TableComponentProperties Columns { get; set; } = new TableComponentProperties(); + + public TableComponentProperties ForeignKeys { get; set; } = new TableComponentProperties(); + + public TableComponentProperties CheckConstraints { get; set; } = new TableComponentProperties(); public InputBoxProperties Script { get; set; } = new InputBoxProperties(); } - - public class TableColumnCollection : TableComponentProperties - { - [JsonIgnore] - protected override string NewObjectNamePrefix { get { return "column"; } } - - protected override TableColumnViewModel CreateNew(string name) - { - //TODO: Add the default values - var column = new TableColumnViewModel(); - column.Name.Value = this.GetDefaultNewObjectName(); - return column; - } - } } \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/TableDesignerService.cs b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/TableDesignerService.cs index 01ee588a..7c9a547a 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/TableDesignerService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/TableDesignerService.cs @@ -11,7 +11,7 @@ using Microsoft.Data.SqlClient; using Microsoft.SqlTools.Hosting.Protocol; using Microsoft.SqlTools.ServiceLayer.Hosting; using Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts; -using Table = Microsoft.Data.Tools.Sql.DesignServices.TableDesigner.TableDesignerViewModel; +using Dac = Microsoft.Data.Tools.Sql.DesignServices.TableDesigner; namespace Microsoft.SqlTools.ServiceLayer.TableDesigner { @@ -20,7 +20,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner /// public sealed class TableDesignerService : IDisposable { - private Dictionary idTableMap = new Dictionary(); + private Dictionary idTableMap = new Dictionary(); private bool disposed = false; private static readonly Lazy instance = new Lazy(() => new TableDesignerService()); @@ -81,7 +81,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner var connectinStringbuilder = new SqlConnectionStringBuilder(tableInfo.ConnectionString); connectinStringbuilder.InitialCatalog = tableInfo.Database; var connectionString = connectinStringbuilder.ToString(); - var table = new Table(connectionString, tableInfo.Schema, tableInfo.Name, tableInfo.IsNewTable); + var table = new Dac.TableDesignerViewModel(connectionString, tableInfo.Schema, tableInfo.Name, tableInfo.IsNewTable); this.idTableMap.Add(tableInfo.Id, table); var viewModel = this.GetTableViewModel(tableInfo); var view = this.GetDesignerViewInfo(tableInfo); @@ -230,7 +230,8 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner private TableDesignerView GetDesignerViewInfo(TableInfo tableInfo) { var view = new TableDesignerView(); - view.AdditionalTableColumnProperties.Add(new DesignerDataPropertyInfo() + view.ColumnTableOptions.AdditionalProperties.AddRange(new DesignerDataPropertyInfo[] { + new DesignerDataPropertyInfo() { PropertyName = TableColumnPropertyNames.IsIdentity, Description = SR.TableColumnIsIdentityPropertyDescription, @@ -240,8 +241,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner { Title = SR.TableColumnIsIdentityPropertyTitle } - }); - view.AdditionalTableColumnProperties.Add(new DesignerDataPropertyInfo() + }, new DesignerDataPropertyInfo() { PropertyName = TableColumnPropertyNames.IdentitySeed, Description = SR.TableColumnIdentitySeedPropertyDescription, @@ -251,8 +251,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner { Title = SR.TableColumnIdentitySeedPropertyTitle } - }); - view.AdditionalTableColumnProperties.Add(new DesignerDataPropertyInfo() + },new DesignerDataPropertyInfo() { PropertyName = TableColumnPropertyNames.IdentityIncrement, Description = SR.TableColumnIdentityIncrementPropertyDescription, @@ -262,15 +261,52 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner { Title = SR.TableColumnIdentityIncrementPropertyTitle } - }); - view.CanAddColumns = true; - view.CanRemoveColumns = true; + }}); + view.ColumnTableOptions.canAddRows = true; + view.ColumnTableOptions.canRemoveRows = true; + + view.ForeignKeyTableOptions.AdditionalProperties.AddRange(new DesignerDataPropertyInfo[] { + new DesignerDataPropertyInfo() + { + PropertyName = ForeignKeyPropertyNames.Enabled, + Description = SR.ForeignKeyIsEnabledDescription, + ComponentType = DesignerComponentType.Checkbox, + ComponentProperties = new CheckBoxProperties() + { + Title = SR.TableDesignerIsEnabledPropertyTitle + } + }, + new DesignerDataPropertyInfo() + { + PropertyName = ForeignKeyPropertyNames.IsNotForReplication, + Description = SR.ForeignKeyIsNotForReplicationDescription, + ComponentType = DesignerComponentType.Checkbox, + ComponentProperties = new CheckBoxProperties() + { + Title = SR.ForeignKeyIsNotForReplicationTitle + } + }}); + view.ForeignKeyTableOptions.canAddRows = true; + view.ForeignKeyTableOptions.canRemoveRows = true; + view.CheckConstraintTableOptions.AdditionalProperties.Add( + new DesignerDataPropertyInfo() + { + PropertyName = CheckConstraintPropertyNames.Enabled, + Description = SR.CheckConstraintIsEnabledDescription, + ComponentType = DesignerComponentType.Checkbox, + ComponentProperties = new CheckBoxProperties() + { + Title = SR.TableDesignerIsEnabledPropertyTitle + } + }); + view.CheckConstraintTableOptions.canAddRows = true; + view.CheckConstraintTableOptions.canRemoveRows = true; return view; } - private Table GetTable(TableInfo tableInfo) + private Dac.TableDesignerViewModel GetTable(TableInfo tableInfo) { - Table table; + Dac.TableDesignerViewModel table; if (this.idTableMap.TryGetValue(tableInfo.Id, out table)) { return table; diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/TableDesigner/TableColumnCollectionTest.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/TableDesigner/TableColumnCollectionTest.cs deleted file mode 100644 index 89e786ea..00000000 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/TableDesigner/TableColumnCollectionTest.cs +++ /dev/null @@ -1,30 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; -using Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts; -using NUnit.Framework; -using Newtonsoft.Json; - -namespace Microsoft.SqlTools.ServiceLayer.UnitTests.TableDesigner -{ - public class TableColumnCollectionTest - { - [Test] - public void AutoNameForNewItemTest() - { - var collection = new TableColumnCollection(); - collection.AddNew(); - Assert.AreEqual(1, collection.Data.Count, "The item count should be 1"); - Assert.AreEqual("column1", collection.Data[0].Name.Value); - collection.Data.Add(new TableColumnViewModel() { Name = new InputBoxProperties() { Value = "column3" } }); - Assert.AreEqual(2, collection.Data.Count, "The item count should be 2"); - collection.AddNew(); - Assert.AreEqual(3, collection.Data.Count, "The item count should be 3"); - // the name that is not yet used should be picked - Assert.AreEqual("column2", collection.Data[2].Name.Value); - } - } -}