mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-31 17:24:37 -05:00
use path to identify edit target (#1292)
* use path to identify edit target * async action * revert RequestContext change * comments * address comments * fix test
This commit is contained in:
@@ -8445,6 +8445,70 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
}
|
||||
}
|
||||
|
||||
public static string TableEditPathNotProvidedException
|
||||
{
|
||||
get
|
||||
{
|
||||
return Keys.GetString(Keys.TableEditPathNotProvidedException);
|
||||
}
|
||||
}
|
||||
|
||||
public static string TableColumnIdentityGroupName
|
||||
{
|
||||
get
|
||||
{
|
||||
return Keys.GetString(Keys.TableColumnIdentityGroupName);
|
||||
}
|
||||
}
|
||||
|
||||
public static string TableColumnIsIdentityPropertyTitle
|
||||
{
|
||||
get
|
||||
{
|
||||
return Keys.GetString(Keys.TableColumnIsIdentityPropertyTitle);
|
||||
}
|
||||
}
|
||||
|
||||
public static string TableColumnIsIdentityPropertyDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
return Keys.GetString(Keys.TableColumnIsIdentityPropertyDescription);
|
||||
}
|
||||
}
|
||||
|
||||
public static string TableColumnIdentityIncrementPropertyTitle
|
||||
{
|
||||
get
|
||||
{
|
||||
return Keys.GetString(Keys.TableColumnIdentityIncrementPropertyTitle);
|
||||
}
|
||||
}
|
||||
|
||||
public static string TableColumnIdentityIncrementPropertyDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
return Keys.GetString(Keys.TableColumnIdentityIncrementPropertyDescription);
|
||||
}
|
||||
}
|
||||
|
||||
public static string TableColumnIdentitySeedPropertyTitle
|
||||
{
|
||||
get
|
||||
{
|
||||
return Keys.GetString(Keys.TableColumnIdentitySeedPropertyTitle);
|
||||
}
|
||||
}
|
||||
|
||||
public static string TableColumnIdentitySeedPropertyDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
return Keys.GetString(Keys.TableColumnIdentitySeedPropertyDescription);
|
||||
}
|
||||
}
|
||||
|
||||
public static string ConnectionServiceListDbErrorNotConnected(string uri)
|
||||
{
|
||||
return Keys.GetString(Keys.ConnectionServiceListDbErrorNotConnected, uri);
|
||||
@@ -8710,6 +8774,16 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
return Keys.GetString(Keys.NameValuePair, name, value);
|
||||
}
|
||||
|
||||
public static string TableNotInitializedException(string tableId)
|
||||
{
|
||||
return Keys.GetString(Keys.TableNotInitializedException, tableId);
|
||||
}
|
||||
|
||||
public static string InvalidTableEditPathException(string path, string editType)
|
||||
{
|
||||
return Keys.GetString(Keys.InvalidTableEditPathException, path, editType);
|
||||
}
|
||||
|
||||
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
public class Keys
|
||||
{
|
||||
@@ -12033,6 +12107,36 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
public const string SizeInTeraBytesFormat = "SizeInTeraBytesFormat";
|
||||
|
||||
|
||||
public const string TableNotInitializedException = "TableNotInitializedException";
|
||||
|
||||
|
||||
public const string TableEditPathNotProvidedException = "TableEditPathNotProvidedException";
|
||||
|
||||
|
||||
public const string InvalidTableEditPathException = "InvalidTableEditPathException";
|
||||
|
||||
|
||||
public const string TableColumnIdentityGroupName = "TableColumnIdentityGroupName";
|
||||
|
||||
|
||||
public const string TableColumnIsIdentityPropertyTitle = "TableColumnIsIdentityPropertyTitle";
|
||||
|
||||
|
||||
public const string TableColumnIsIdentityPropertyDescription = "TableColumnIsIdentityPropertyDescription";
|
||||
|
||||
|
||||
public const string TableColumnIdentityIncrementPropertyTitle = "TableColumnIdentityIncrementPropertyTitle";
|
||||
|
||||
|
||||
public const string TableColumnIdentityIncrementPropertyDescription = "TableColumnIdentityIncrementPropertyDescription";
|
||||
|
||||
|
||||
public const string TableColumnIdentitySeedPropertyTitle = "TableColumnIdentitySeedPropertyTitle";
|
||||
|
||||
|
||||
public const string TableColumnIdentitySeedPropertyDescription = "TableColumnIdentitySeedPropertyDescription";
|
||||
|
||||
|
||||
private Keys()
|
||||
{ }
|
||||
|
||||
|
||||
@@ -4590,4 +4590,46 @@
|
||||
<value>{0} TB</value>
|
||||
<comment>Size in TeraBytes format</comment>
|
||||
</data>
|
||||
<data name="TableNotInitializedException" xml:space="preserve">
|
||||
<value>Initialization is not properly done for table with id '{0}'</value>
|
||||
<comment>.
|
||||
Parameters: 0 - tableId (string) </comment>
|
||||
</data>
|
||||
<data name="TableEditPathNotProvidedException" xml:space="preserve">
|
||||
<value>The path in the table change information cannot be empty</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="InvalidTableEditPathException" xml:space="preserve">
|
||||
<value>The path '{0}' in the table change information is not valid for edit type: '{1}'</value>
|
||||
<comment>.
|
||||
Parameters: 0 - path (string), 1 - editType (string) </comment>
|
||||
</data>
|
||||
<data name="TableColumnIdentityGroupName" xml:space="preserve">
|
||||
<value>Identity Specification</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="TableColumnIsIdentityPropertyTitle" xml:space="preserve">
|
||||
<value>Is Identity</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="TableColumnIsIdentityPropertyDescription" xml:space="preserve">
|
||||
<value>Specifies whether the column is the identity column for the table.</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="TableColumnIdentityIncrementPropertyTitle" xml:space="preserve">
|
||||
<value>Identity Increment</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="TableColumnIdentityIncrementPropertyDescription" xml:space="preserve">
|
||||
<value>Displays the value added to the maximum existing row identity value when generating the next identity value.</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="TableColumnIdentitySeedPropertyTitle" xml:space="preserve">
|
||||
<value>Identity Seed</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="TableColumnIdentitySeedPropertyDescription" xml:space="preserve">
|
||||
<value>Displays the initial row value for an identity column.</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2212,4 +2212,18 @@ SizeInMegaBytesFormat = {0} MB
|
||||
;Size in GigaBytes format
|
||||
SizeInGigaBytesFormat = {0} GB
|
||||
;Size in TeraBytes format
|
||||
SizeInTeraBytesFormat = {0} TB
|
||||
SizeInTeraBytesFormat = {0} TB
|
||||
|
||||
############################################################################
|
||||
# Table Designer
|
||||
|
||||
TableNotInitializedException(string tableId) = Initialization is not properly done for table with id '{0}'
|
||||
TableEditPathNotProvidedException = The path in the table change information cannot be empty
|
||||
InvalidTableEditPathException(string path, string editType) = The path '{0}' in the table change information is not valid for edit type: '{1}'
|
||||
TableColumnIdentityGroupName = Identity Specification
|
||||
TableColumnIsIdentityPropertyTitle = Is Identity
|
||||
TableColumnIsIdentityPropertyDescription = Specifies whether the column is the identity column for the table.
|
||||
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.
|
||||
|
||||
@@ -5579,6 +5579,58 @@
|
||||
<target state="new">{0} TB</target>
|
||||
<note>Size in TeraBytes format</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="TableNotInitializedException">
|
||||
<source>Initialization is not properly done for table with id '{0}'</source>
|
||||
<target state="new">Initialization is not properly done for table with id '{0}'</target>
|
||||
<note>.
|
||||
Parameters: 0 - tableId (string) </note>
|
||||
</trans-unit>
|
||||
<trans-unit id="TableColumnIdentityGroupName">
|
||||
<source>Identity Specification</source>
|
||||
<target state="new">Identity Specification</target>
|
||||
<note></note>
|
||||
</trans-unit>
|
||||
<trans-unit id="TableColumnIsIdentityPropertyTitle">
|
||||
<source>Is Identity</source>
|
||||
<target state="new">Is Identity</target>
|
||||
<note></note>
|
||||
</trans-unit>
|
||||
<trans-unit id="TableColumnIsIdentityPropertyDescription">
|
||||
<source>Specifies whether the column is the identity column for the table.</source>
|
||||
<target state="new">Specifies whether the column is the identity column for the table.</target>
|
||||
<note></note>
|
||||
</trans-unit>
|
||||
<trans-unit id="TableColumnIdentityIncrementPropertyTitle">
|
||||
<source>Identity Increment</source>
|
||||
<target state="new">Identity Increment</target>
|
||||
<note></note>
|
||||
</trans-unit>
|
||||
<trans-unit id="TableColumnIdentityIncrementPropertyDescription">
|
||||
<source>Displays the value added to the maximum existing row identity value when generating the next identity value.</source>
|
||||
<target state="new">Displays the value added to the maximum existing row identity value when generating the next identity value.</target>
|
||||
<note></note>
|
||||
</trans-unit>
|
||||
<trans-unit id="TableColumnIdentitySeedPropertyTitle">
|
||||
<source>Identity Seed</source>
|
||||
<target state="new">Identity Seed</target>
|
||||
<note></note>
|
||||
</trans-unit>
|
||||
<trans-unit id="TableColumnIdentitySeedPropertyDescription">
|
||||
<source>Displays the initial row value for an identity column.</source>
|
||||
<target state="new">Displays the initial row value for an identity column.</target>
|
||||
<note></note>
|
||||
</trans-unit>
|
||||
<trans-unit id="TableEditPathNotProvidedException">
|
||||
<source>The path in the table change information cannot be empty</source>
|
||||
<target state="new">The path in the table change information cannot be empty</target>
|
||||
<note></note>
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidTableEditPathException">
|
||||
<source>The path '{0}' in the table change information is not valid for edit type: '{1}'</source>
|
||||
<target state="new">The path '{0}' in the table change information is not valid for edit type: '{1}'</target>
|
||||
<note>.
|
||||
Parameters: 0 - path (string), 1 - editType (string) </note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -3,12 +3,6 @@
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.Hosting.Protocol;
|
||||
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
||||
using Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.TableDesigner
|
||||
{
|
||||
public static class TablePropertyNames
|
||||
@@ -29,5 +23,8 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner
|
||||
public const string IsPrimaryKey = "isPrimaryKey";
|
||||
public const string Precision = "precision";
|
||||
public const string Scale = "scale";
|
||||
public const string IsIdentity = "isIdentity";
|
||||
public const string IdentityIncrement = "identityIncrement";
|
||||
public const string IdentitySeed = "identitySeed";
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,10 @@
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Runtime.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
@@ -23,17 +27,35 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts
|
||||
/// <summary>
|
||||
/// The component type of the property
|
||||
/// </summary>
|
||||
public string ComponentType { get; set; }
|
||||
public DesignerComponentType ComponentType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the group the property will be placed in whe displayed in
|
||||
/// </summary>
|
||||
public string Group { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the group the property will be placed in whe displayed in
|
||||
/// </summary>
|
||||
public bool ShowInPropertiesView { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The properties of component
|
||||
/// </summary>
|
||||
public ComponentPropertiesBase ComponentProperties { get; set; }
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public enum DesignerComponentType
|
||||
{
|
||||
[EnumMember(Value = "checkbox")]
|
||||
Checkbox,
|
||||
[EnumMember(Value = "dropdown")]
|
||||
Dropdown,
|
||||
[EnumMember(Value = "input")]
|
||||
Input,
|
||||
[EnumMember(Value = "table")]
|
||||
Table
|
||||
}
|
||||
}
|
||||
@@ -28,41 +28,8 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts
|
||||
{
|
||||
public DesignerEditType Type { get; set; }
|
||||
|
||||
[JsonConverter(typeof(TableDesignerPropertyConverter))]
|
||||
public object Property { get; set; }
|
||||
public object[] Path { get; set; }
|
||||
|
||||
public object Value { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The property "Property" of <c>TableDesignerChangeInfo</c> could be string or <c>TableDesignerPropertyIdentifier</c>, use this custom converter to set the property value.
|
||||
/// </summary>
|
||||
public class TableDesignerPropertyConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
object property;
|
||||
if (reader.TokenType == JsonToken.StartObject)
|
||||
{
|
||||
TableDesignerPropertyIdentifier obj = serializer.Deserialize(reader, typeof(TableDesignerPropertyIdentifier)) as TableDesignerPropertyIdentifier;
|
||||
property = obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
property = reader.Value;
|
||||
}
|
||||
return property;
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
// We don't need to serialize this class.
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// The information that can identify a property in a collection.
|
||||
/// </summary>
|
||||
public class TableDesignerPropertyIdentifier
|
||||
{
|
||||
public string ParentProperty { get; set; }
|
||||
|
||||
public int Index { get; set; }
|
||||
|
||||
public string Property { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
@@ -11,8 +13,14 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts
|
||||
/// </summary>
|
||||
public class TableDesignerView
|
||||
{
|
||||
public DesignerDataPropertyInfo[] AdditionalTableProperties { get; set; }
|
||||
public List<DesignerDataPropertyInfo> AdditionalTableProperties { get; set; } = new List<DesignerDataPropertyInfo>();
|
||||
|
||||
public DesignerDataPropertyInfo[] AdditionalTableColumnProperties { get; set; }
|
||||
public List<DesignerDataPropertyInfo> AdditionalTableColumnProperties { get; set; } = new List<DesignerDataPropertyInfo>();
|
||||
|
||||
public List<string> ColumnsTableProperties { get; set; } = new List<string>();
|
||||
|
||||
public bool CanAddColumns { get; set; }
|
||||
|
||||
public bool CanRemoveColumns { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -25,5 +25,11 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts
|
||||
public InputBoxProperties DefaultValue { get; set; } = new InputBoxProperties();
|
||||
|
||||
public CheckBoxProperties IsPrimaryKey { get; set; } = new CheckBoxProperties();
|
||||
|
||||
public CheckBoxProperties IsIdentity { get; set; } = new CheckBoxProperties();
|
||||
|
||||
public InputBoxProperties IdentitySeed { get; set; } = new InputBoxProperties();
|
||||
|
||||
public InputBoxProperties IdentityIncrement { get; set; } = new InputBoxProperties();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// 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 System.Collections;
|
||||
using System.Linq;
|
||||
using Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.TableDesigner
|
||||
{
|
||||
public static class DesignerPathUtils
|
||||
{
|
||||
///<summary>
|
||||
/// validate the path in the table designer change information.
|
||||
/// Below are the 3 scenarios and their expected path.
|
||||
/// Note: 'index-{x}' in the description below are numbers represent the index of the object in the list.
|
||||
/// 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,'propertyName2',index-2]. Example: remove a column mapping from a foreign key's column mapping table: ['foreignKeys',0,'mappings',0].
|
||||
///<summary>
|
||||
public static void Validate(object[] path, DesignerEditType editType)
|
||||
{
|
||||
if (path == null || path.Length == 0)
|
||||
{
|
||||
throw new ArgumentException(SR.TableEditPathNotProvidedException);
|
||||
}
|
||||
|
||||
// Length validation
|
||||
int[] validLengthList;
|
||||
if (editType == DesignerEditType.Add)
|
||||
{
|
||||
validLengthList = new int[] { 1, 3 };
|
||||
}
|
||||
else if (editType == DesignerEditType.Update)
|
||||
{
|
||||
validLengthList = new int[] { 1, 3, 5 };
|
||||
}
|
||||
else
|
||||
{
|
||||
validLengthList = new int[] { 2, 4 };
|
||||
}
|
||||
|
||||
bool isValid = validLengthList.ToList<int>().Contains(path.Length);
|
||||
if (isValid)
|
||||
{
|
||||
for (int i = 0; i < path.Length; i++)
|
||||
{
|
||||
// On odd number positions, the value must be a number.
|
||||
if (i % 2 != 0)
|
||||
{
|
||||
int val;
|
||||
isValid = Int32.TryParse(path[i]?.ToString(), out val);
|
||||
}
|
||||
else
|
||||
{
|
||||
isValid = path[i] is string;
|
||||
}
|
||||
if (!isValid)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isValid)
|
||||
{
|
||||
throw new ArgumentException(SR.InvalidTableEditPathException(string.Join(',', path), editType.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,102 +57,92 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner
|
||||
this.ServiceHost.SetRequestHandler(SaveTableChangesRequest.Type, HandleSaveTableChangesRequest);
|
||||
this.ServiceHost.SetRequestHandler(DisposeTableDesignerRequest.Type, HandleDisposeTableDesignerRequest);
|
||||
}
|
||||
|
||||
private async Task HandleGetTableDesignerInfoRequest(TableInfo tableInfo, RequestContext<TableDesignerInfo> requestContext)
|
||||
private Task HandleRequest<T>(RequestContext<T> requestContext, Func<Task> action)
|
||||
{
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var schemas = this.GetSchemas(tableInfo);
|
||||
var viewModel = this.GetTableViewModel(tableInfo, schemas);
|
||||
var view = this.GetDesignerViewInfo(tableInfo);
|
||||
await requestContext.SendResult(new TableDesignerInfo()
|
||||
{
|
||||
ViewModel = viewModel,
|
||||
View = view,
|
||||
ColumnTypes = this.GetSupportedColumnTypes(tableInfo),
|
||||
Schemas = schemas
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await requestContext.SendError(e);
|
||||
}
|
||||
});
|
||||
// The request handling will take some time to return, we need to use a separate task to run the request handler so that it won't block the main thread.
|
||||
// For any specific table designer instance, ADS UI can make sure there are at most one request being processed at any given time, so we don't have to worry about race conditions.
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await action();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await requestContext.SendError(e);
|
||||
}
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task HandleProcessTableDesignerEditRequest(ProcessTableDesignerEditRequestParams requestParams, RequestContext<ProcessTableDesignerEditResponse> requestContext)
|
||||
private Task HandleGetTableDesignerInfoRequest(TableInfo tableInfo, RequestContext<TableDesignerInfo> requestContext)
|
||||
{
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (requestParams.TableChangeInfo.Type)
|
||||
{
|
||||
case DesignerEditType.Add:
|
||||
this.HandleAddItemRequest(requestParams);
|
||||
break;
|
||||
case DesignerEditType.Remove:
|
||||
// TODO: Handle 'Remove' request
|
||||
break;
|
||||
default:
|
||||
// TODO: Handle 'Update' request
|
||||
break;
|
||||
}
|
||||
await requestContext.SendResult(new ProcessTableDesignerEditResponse()
|
||||
{
|
||||
ViewModel = requestParams.ViewModel,
|
||||
IsValid = true
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await requestContext.SendError(e);
|
||||
}
|
||||
});
|
||||
return this.HandleRequest<TableDesignerInfo>(requestContext, async () =>
|
||||
{
|
||||
var schemas = this.GetSchemas(tableInfo);
|
||||
var viewModel = this.GetTableViewModel(tableInfo, schemas);
|
||||
var view = this.GetDesignerViewInfo(tableInfo);
|
||||
await requestContext.SendResult(new TableDesignerInfo()
|
||||
{
|
||||
ViewModel = viewModel,
|
||||
View = view,
|
||||
ColumnTypes = this.GetSupportedColumnTypes(tableInfo),
|
||||
Schemas = schemas
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private async Task HandleSaveTableChangesRequest(SaveTableChangesRequestParams requestParams, RequestContext<SaveTableChangesResponse> requestContext)
|
||||
private Task HandleProcessTableDesignerEditRequest(ProcessTableDesignerEditRequestParams requestParams, RequestContext<ProcessTableDesignerEditResponse> requestContext)
|
||||
{
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// TODO: Handle the save changes request.
|
||||
await requestContext.SendResult(new SaveTableChangesResponse());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await requestContext.SendError(e);
|
||||
}
|
||||
});
|
||||
return this.HandleRequest<ProcessTableDesignerEditResponse>(requestContext, async () =>
|
||||
{
|
||||
DesignerPathUtils.Validate(requestParams.TableChangeInfo.Path, requestParams.TableChangeInfo.Type);
|
||||
switch (requestParams.TableChangeInfo.Type)
|
||||
{
|
||||
case DesignerEditType.Add:
|
||||
this.HandleAddItemRequest(requestParams);
|
||||
break;
|
||||
case DesignerEditType.Remove:
|
||||
this.HandleRemoveItemRequest(requestParams);
|
||||
break;
|
||||
default:
|
||||
// TODO: Handle 'Update' request
|
||||
break;
|
||||
}
|
||||
await requestContext.SendResult(new ProcessTableDesignerEditResponse()
|
||||
{
|
||||
ViewModel = requestParams.ViewModel,
|
||||
IsValid = true
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private Task HandleSaveTableChangesRequest(SaveTableChangesRequestParams requestParams, RequestContext<SaveTableChangesResponse> requestContext)
|
||||
{
|
||||
return this.HandleRequest<SaveTableChangesResponse>(requestContext, async () =>
|
||||
{
|
||||
// TODO: Handle the save changes request.
|
||||
await requestContext.SendResult(new SaveTableChangesResponse());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private async Task HandleDisposeTableDesignerRequest(TableInfo tableInfo, RequestContext<DisposeTableDesignerResponse> requestContext)
|
||||
private Task HandleDisposeTableDesignerRequest(TableInfo tableInfo, RequestContext<DisposeTableDesignerResponse> requestContext)
|
||||
{
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// TODO: Handle the dispose table designer request.
|
||||
await requestContext.SendResult(new DisposeTableDesignerResponse());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await requestContext.SendError(e);
|
||||
}
|
||||
});
|
||||
return this.HandleRequest<DisposeTableDesignerResponse>(requestContext, async () =>
|
||||
{
|
||||
// TODO: Handle the save changes request.
|
||||
await requestContext.SendResult(new DisposeTableDesignerResponse());
|
||||
});
|
||||
}
|
||||
|
||||
private void HandleAddItemRequest(ProcessTableDesignerEditRequestParams requestParams)
|
||||
{
|
||||
var property = requestParams.TableChangeInfo.Property;
|
||||
var path = requestParams.TableChangeInfo.Path;
|
||||
// Handle the add item request on top level table properties, e.g. Columns, Indexes.
|
||||
if (property.GetType() == typeof(string))
|
||||
if (path.Length == 1)
|
||||
{
|
||||
string propertyName = property as string;
|
||||
var propertyName = path[0] as string;
|
||||
switch (propertyName)
|
||||
{
|
||||
case TablePropertyNames.Columns:
|
||||
@@ -168,6 +158,28 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleRemoveItemRequest(ProcessTableDesignerEditRequestParams requestParams)
|
||||
{
|
||||
var path = requestParams.TableChangeInfo.Path;
|
||||
// Handle the add item request on top level table properties, e.g. Columns, Indexes.
|
||||
if (path.Length == 2)
|
||||
{
|
||||
var propertyName = path[0] as string;
|
||||
switch (propertyName)
|
||||
{
|
||||
case TablePropertyNames.Columns:
|
||||
requestParams.ViewModel.Columns.Data.RemoveAt(Convert.ToInt32(path[1]));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Handle the add item request on second level properties, e.g. Adding a column to an index
|
||||
}
|
||||
}
|
||||
|
||||
private List<string> GetSupportedColumnTypes(TableInfo tableInfo)
|
||||
{
|
||||
//TODO: get the supported column types.
|
||||
@@ -200,8 +212,42 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner
|
||||
|
||||
private TableDesignerView GetDesignerViewInfo(TableInfo tableInfo)
|
||||
{
|
||||
// TODO: set the view information
|
||||
var view = new TableDesignerView();
|
||||
view.AdditionalTableColumnProperties.Add(new DesignerDataPropertyInfo()
|
||||
{
|
||||
PropertyName = TableColumnPropertyNames.IsIdentity,
|
||||
Description = SR.TableColumnIsIdentityPropertyDescription,
|
||||
Group = SR.TableColumnIdentityGroupName,
|
||||
ComponentType = DesignerComponentType.Checkbox,
|
||||
ComponentProperties = new CheckBoxProperties()
|
||||
{
|
||||
Title = SR.TableColumnIsIdentityPropertyTitle
|
||||
}
|
||||
});
|
||||
view.AdditionalTableColumnProperties.Add(new DesignerDataPropertyInfo()
|
||||
{
|
||||
PropertyName = TableColumnPropertyNames.IdentitySeed,
|
||||
Description = SR.TableColumnIdentitySeedPropertyDescription,
|
||||
Group = SR.TableColumnIdentityGroupName,
|
||||
ComponentType = DesignerComponentType.Input,
|
||||
ComponentProperties = new InputBoxProperties()
|
||||
{
|
||||
Title = SR.TableColumnIdentitySeedPropertyTitle
|
||||
}
|
||||
});
|
||||
view.AdditionalTableColumnProperties.Add(new DesignerDataPropertyInfo()
|
||||
{
|
||||
PropertyName = TableColumnPropertyNames.IdentityIncrement,
|
||||
Description = SR.TableColumnIdentityIncrementPropertyDescription,
|
||||
Group = SR.TableColumnIdentityGroupName,
|
||||
ComponentType = DesignerComponentType.Input,
|
||||
ComponentProperties = new InputBoxProperties()
|
||||
{
|
||||
Title = SR.TableColumnIdentityIncrementPropertyTitle
|
||||
}
|
||||
});
|
||||
view.CanAddColumns = true;
|
||||
view.CanRemoveColumns = true;
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// 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;
|
||||
using Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.TableDesigner
|
||||
{
|
||||
public class DesignerPathUtilsTest
|
||||
{
|
||||
[Test]
|
||||
public void ParseDesignerPathTest()
|
||||
{
|
||||
DesignerEditType editType = DesignerEditType.Add;
|
||||
this.RunTest(new object[] { "property1" }, editType, true);
|
||||
this.RunTest(new object[] { "property1", 1, "property2" }, editType, true);
|
||||
this.RunTest(new object[] { "property1", "xx", "property2" }, editType, false);
|
||||
this.RunTest(new object[] { "property1", 1 }, editType, false);
|
||||
this.RunTest(new object[] { "property1", 1, "property2", 1 }, editType, false);
|
||||
this.RunTest(new object[] { "property1", 1, "property2", 1, "property3" }, editType, false);
|
||||
this.RunTest(new object[] { }, editType, false);
|
||||
this.RunTest(null, editType, false);
|
||||
|
||||
editType = DesignerEditType.Remove;
|
||||
this.RunTest(new object[] { "property1", 0 }, editType, true);
|
||||
this.RunTest(new object[] { "property1", 1, "property2", 1 }, editType, true);
|
||||
this.RunTest(new object[] { "property1" }, editType, false);
|
||||
this.RunTest(new object[] { "property1", 1, "property2" }, editType, false);
|
||||
this.RunTest(new object[] { "property1", 1, "property2", 1, "property3", 1 }, editType, false);
|
||||
this.RunTest(new object[] { }, editType, false);
|
||||
this.RunTest(null, editType, false);
|
||||
|
||||
editType = DesignerEditType.Update;
|
||||
this.RunTest(new object[] { "property1" }, editType, true);
|
||||
this.RunTest(new object[] { "property1", 1, "property2" }, editType, true);
|
||||
this.RunTest(new object[] { "property1", 1, "property2", 1, "property3" }, editType, true);
|
||||
this.RunTest(new object[] { "property1", "abc" }, editType, false);
|
||||
this.RunTest(new object[] { "property1", 1, "property2", 1 }, editType, false);
|
||||
this.RunTest(new object[] { "property1", 1, "property2", 1, "property3", 2, "property4" }, editType, false);
|
||||
this.RunTest(new object[] { }, editType, false);
|
||||
this.RunTest(null, editType, false);
|
||||
}
|
||||
|
||||
private void RunTest(object[] path, DesignerEditType editType, bool isValidPath)
|
||||
{
|
||||
if (isValidPath)
|
||||
{
|
||||
Assert.DoesNotThrow(() =>
|
||||
{
|
||||
DesignerPathUtils.Validate(path, editType);
|
||||
}, string.Format("Path '{0}' should be a valid path for edit type: '{1}'.", path, editType.ToString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
{
|
||||
DesignerPathUtils.Validate(path, editType);
|
||||
}, string.Format("Path '{0}' should not be a valid path for edit type: '{1}'.", path, editType.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 TableDesignerChangeInfoTest
|
||||
{
|
||||
[Test]
|
||||
public void DeserializeTableChangeProperty()
|
||||
{
|
||||
string testJsonStringType = "{\"type\": 1, \"property\": \"columns\"}";
|
||||
TableDesignerChangeInfo changeInfo = JsonConvert.DeserializeObject<TableDesignerChangeInfo>(testJsonStringType);
|
||||
Assert.IsNotNull(changeInfo, "string property: the changeInfo shouldn't be null.");
|
||||
Assert.IsNotNull(changeInfo.Property, "string property: the property shouldn't be null.");
|
||||
Assert.IsTrue(changeInfo.Property.GetType() == typeof(string));
|
||||
string testJsonObjectType = "{\"type\": 1, \"property\": {\"parentProperty\": \"columns\",\"index\": 0,\"property\": \"length\"}}";
|
||||
changeInfo = JsonConvert.DeserializeObject<TableDesignerChangeInfo>(testJsonObjectType);
|
||||
Assert.IsNotNull(changeInfo, "object property: the changeInfo shouldn't be null.");
|
||||
Assert.IsNotNull(changeInfo.Property, "object property: the property shouldn't be null.");
|
||||
Assert.IsTrue(changeInfo.Property.GetType() == typeof(TableDesignerPropertyIdentifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user