edit/revertCell (#268)

// edit/dispose -------------------------------------------------------------------------------
export interface EditDisposeParams extends IEditSessionOperationParams { }
export interface EditDisposeResult { }

* Initial plumbing for edit/revertCell

* Implementation of revert cell in the parents of the row edit base

* Adding unit tests
This commit is contained in:
Benjamin Russell
2017-03-08 14:49:13 -08:00
committed by GitHub
parent 666ee98582
commit c0468e763f
17 changed files with 469 additions and 39 deletions

View File

@@ -0,0 +1,26 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
namespace Microsoft.SqlTools.ServiceLayer.EditData.Contracts
{
public class EditRevertCellParams : RowOperationParams
{
public int ColumnId { get; set; }
}
public class EditRevertCellResult
{
public string NewValue { get; set; }
}
public class EditRevertCellRequest
{
public static readonly
RequestType<EditRevertCellParams, EditRevertCellResult> Type =
RequestType<EditRevertCellParams, EditRevertCellResult>.Create("edit/revertCell");
}
}

View File

@@ -89,6 +89,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData
serviceHost.SetRequestHandler(EditDeleteRowRequest.Type, HandleDeleteRowRequest);
serviceHost.SetRequestHandler(EditDisposeRequest.Type, HandleDisposeRequest);
serviceHost.SetRequestHandler(EditInitializeRequest.Type, HandleInitializeRequest);
serviceHost.SetRequestHandler(EditRevertCellRequest.Type, HandleRevertCellRequest);
serviceHost.SetRequestHandler(EditRevertRowRequest.Type, HandleRevertRowRequest);
serviceHost.SetRequestHandler(EditUpdateCellRequest.Type, HandleUpdateCellRequest);
}
@@ -217,6 +218,19 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData
}
}
internal Task HandleRevertCellRequest(EditRevertCellParams revertParams,
RequestContext<EditRevertCellResult> requestContext)
{
return HandleSessionRequest(revertParams, requestContext, session =>
{
string newValue = session.RevertCell(revertParams.RowId, revertParams.ColumnId);
return new EditRevertCellResult
{
NewValue = newValue
};
});
}
internal Task HandleRevertRowRequest(EditRevertRowParams revertParams,
RequestContext<EditRevertRowResult> requestContext)
{

View File

@@ -186,6 +186,25 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData
}
}
/// <summary>
/// Reverts a cell in a pending edit
/// </summary>
/// <param name="rowId">Internal ID of the row to have its edits reverted</param>
/// <param name="columnId">Ordinal ID of the column to revert</param>
/// <returns>String version of the old value for the cell</returns>
public string RevertCell(long rowId, int columnId)
{
// Attempt to get the row edit with the given ID
RowEditBase pendingEdit;
if (!EditCache.TryGetValue(rowId, out pendingEdit))
{
throw new ArgumentOutOfRangeException(nameof(rowId), SR.EditDataUpdateNotPending);
}
// Have the edit base revert the cell
return pendingEdit.RevertCell(columnId);
}
/// <summary>
/// Removes a pending row update from the update cache.
/// </summary>

View File

@@ -27,7 +27,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
private const string InsertCompleteScript = "{0} VALUES ({1})";
private const string InsertCompleteOutput = "{0} OUTPUT {1} VALUES ({2})";
private readonly CellUpdate[] newCells;
internal readonly CellUpdate[] newCells;
/// <summary>
/// Creates a new Row Creation edit to the result set
@@ -159,6 +159,21 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
return string.Format(InsertCompleteScript, start, joinedValues);
}
/// <summary>
/// Reverts a cell to an unset value.
/// </summary>
/// <param name="columnId">The ordinal ID of the cell to reset</param>
/// <returns>The default value for the column, or null if no default is defined</returns>
public override string RevertCell(int columnId)
{
// Validate that the column can be reverted
Validate.IsWithinRange(nameof(columnId), columnId, 0, newCells.Length - 1);
// Remove the cell update from list of set cells
newCells[columnId] = null;
return null; // @TODO: Return default value when we have support checked in
}
/// <summary>
/// Sets the value of a cell in the row to be added
/// </summary>

View File

@@ -81,6 +81,16 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
return GetCommandText(GetWhereClause(false).CommandText);
}
/// <summary>
/// This method should not be called. A cell cannot be reverted on a row that is pending
/// deletion.
/// </summary>
/// <param name="columnId">Ordinal of the column to update</param>
public override string RevertCell(int columnId)
{
throw new InvalidOperationException(SR.EditDataDeleteSetCell);
}
/// <summary>
/// This method should not be called. A cell cannot be updated on a row that is pending
/// deletion.

View File

@@ -91,6 +91,13 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
/// <returns>A SQL statement</returns>
public abstract string GetScript();
/// <summary>
/// Reverts a specific cell in row with pending edits
/// </summary>
/// <param name="columnId">Ordinal ID of the column to revert</param>
/// <returns>String value of the original value of the cell</returns>
public abstract string RevertCell(int columnId);
/// <summary>
/// Changes the value a cell in the row.
/// </summary>

View File

@@ -4,6 +4,7 @@
//
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
@@ -29,7 +30,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
private const string UpdateScript = @"{0} SET {1} {2}";
private const string UpdateScriptOutput = @"{0} SET {1} OUTPUT {2} {3}";
private readonly Dictionary<int, CellUpdate> cellUpdates;
internal readonly ConcurrentDictionary<int, CellUpdate> cellUpdates;
private readonly IList<DbCellValue> associatedRow;
/// <summary>
@@ -41,7 +42,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
public RowUpdate(long rowId, ResultSet associatedResultSet, IEditTableMetadata associatedMetadata)
: base(rowId, associatedResultSet, associatedMetadata)
{
cellUpdates = new Dictionary<int, CellUpdate>();
cellUpdates = new ConcurrentDictionary<int, CellUpdate>();
associatedRow = associatedResultSet.GetRow(rowId);
}
@@ -137,6 +138,22 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
return string.Format(UpdateScript, statementStart, setClause, whereClause);
}
/// <summary>
/// Reverts the value of a cell to its original value
/// </summary>
/// <param name="columnId">Ordinal of the column to revert</param>
/// <returns>The value that was </returns>
public override string RevertCell(int columnId)
{
Validate.IsWithinRange(nameof(columnId), columnId, 0, associatedRow.Count - 1);
// Remove the cell update
CellUpdate cellUpdate;
cellUpdates.TryRemove(columnId, out cellUpdate);
return associatedRow[columnId].DisplayValue;
}
/// <summary>
/// Sets the value of the cell in the associated row. If <paramref name="newValue"/> is
/// identical to the original value, this will remove the cell update from the row update.
@@ -157,11 +174,9 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
// NOTE: We must use .Equals in order to ignore object to object comparisons
if (update.Value.Equals(associatedRow[columnId].RawObject))
{
// Remove any pending change and stop processing this
if (cellUpdates.ContainsKey(columnId))
{
cellUpdates.Remove(columnId);
}
// Remove any pending change and stop processing this (we don't care if we fail to remove something)
CellUpdate cu;
cellUpdates.TryRemove(columnId, out cu);
return new EditUpdateCellResult
{
HasCorrections = false,
@@ -172,7 +187,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
}
// The change is real, so set it
cellUpdates[columnId] = update;
cellUpdates.AddOrUpdate(columnId, update, (i, cu) => update);
return new EditUpdateCellResult
{
HasCorrections = update.ValueAsString != newValue,

View File

@@ -421,6 +421,14 @@ namespace Microsoft.SqlTools.ServiceLayer
}
}
public static string EditDataColumnUpdateNotPending
{
get
{
return Keys.GetString(Keys.EditDataColumnUpdateNotPending);
}
}
public static string EditDataObjectMetadataNotFound
{
get
@@ -1032,6 +1040,9 @@ namespace Microsoft.SqlTools.ServiceLayer
public const string EditDataUpdateNotPending = "EditDataUpdateNotPending";
public const string EditDataColumnUpdateNotPending = "EditDataColumnUpdateNotPending";
public const string EditDataObjectMetadataNotFound = "EditDataObjectMetadataNotFound";

View File

@@ -380,7 +380,11 @@
<comment></comment>
</data>
<data name="EditDataUpdateNotPending" xml:space="preserve">
<value>Given row ID does not have pending updated</value>
<value>Given row ID does not have pending update</value>
<comment></comment>
</data>
<data name="EditDataColumnUpdateNotPending" xml:space="preserve">
<value>Give column ID does not have pending update</value>
<comment></comment>
</data>
<data name="EditDataObjectMetadataNotFound" xml:space="preserve">

View File

@@ -178,7 +178,9 @@ EditDataRowOutOfRange = Given row ID is outside the range of rows in the edit ca
EditDataUpdatePending = An update is already pending for this row and must be reverted first
EditDataUpdateNotPending = Given row ID does not have pending updated
EditDataUpdateNotPending = Given row ID does not have pending update
EditDataColumnUpdateNotPending = Give column ID does not have pending update
EditDataObjectMetadataNotFound = Table or view metadata could not be found

View File

@@ -460,7 +460,7 @@
<note></note>
</trans-unit>
<trans-unit id="EditDataUpdateNotPending">
<source>Given row ID does not have pending updated</source>
<source>Given row ID does not have pending update</source>
<target state="new">Given row ID does not have pending updated</target>
<note></note>
</trans-unit>
@@ -536,6 +536,11 @@
<target state="new">&lt;TBD&gt;</target>
<note></note>
</trans-unit>
<trans-unit id="EditDataColumnUpdateNotPending">
<source>Give column ID does not have pending update</source>
<target state="new">Give column ID does not have pending update</target>
<note></note>
</trans-unit>
<trans-unit id="EditDataInitializeInProgress">
<source>Another edit data initialize is in progress for this owner URI. Please wait for completion.</source>
<target state="new">Another edit data initialize is in progress for this owner URI. Please wait for completion.</target>

View File

@@ -6,10 +6,13 @@
using System;
using System.Data.Common;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.EditData;
using Microsoft.SqlTools.ServiceLayer.EditData.Contracts;
using Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement;
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility;
using Xunit;
@@ -22,8 +25,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup: Create the values to store
const long rowId = 100;
ResultSet rs = QueryExecution.Common.GetBasicExecutedBatch().ResultSets[0];
IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns);
DbColumn[] columns = Common.GetColumns(false);
ResultSet rs = Common.GetResultSet(columns, false);
IEditTableMetadata etm = Common.GetStandardMetadata(columns);
// If: I create a RowCreate instance
RowCreate rc = new RowCreate(rowId, rs, etm);
@@ -72,14 +76,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public void GetScriptMissingCell()
{
// Setup: Generate the parameters for the row create
const long rowId = 100;
DbColumn[] columns = Common.GetColumns(false);
ResultSet rs = Common.GetResultSet(columns, false);
IEditTableMetadata etm = Common.GetStandardMetadata(columns);
RowCreate rc = GetStandardRowCreate();
// If: I ask for a script to be generated without setting any values
// Then: An exception should be thrown for missing cells
RowCreate rc = new RowCreate(rowId, rs, etm);
Assert.Throws<InvalidOperationException>(() => rc.GetScript());
}
@@ -161,11 +161,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public void GetCommandNullConnection()
{
// Setup: Create a row create
const long rowId = 100;
var columns = Common.GetColumns(false);
var rs = Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
RowCreate rc = new RowCreate(rowId, rs, etm);
RowCreate rc = GetStandardRowCreate();
// If: I attempt to create a command with a null connection
// Then: It should throw an exception
@@ -176,16 +173,166 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public void GetCommandMissingCell()
{
// Setup: Generate the parameters for the row create
const long rowId = 100;
var columns = Common.GetColumns(false);
var rs = Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
RowCreate rc = GetStandardRowCreate();
var mockConn = new TestSqlConnection(null);
// If: I ask for a script to be generated without setting any values
// Then: An exception should be thrown for missing cells
RowCreate rc = new RowCreate(rowId, rs, etm);
Assert.Throws<InvalidOperationException>(() => rc.GetCommand(mockConn));
}
[Theory]
[InlineData(-1)] // Negative
[InlineData(3)] // At edge of acceptable values
[InlineData(100)] // Way too large value
public void SetCellOutOfRange(int columnId)
{
// Setup: Generate a row create
RowCreate rc = GetStandardRowCreate();
// If: I attempt to set a cell on a column that is out of range, I should get an exception
Assert.Throws<ArgumentOutOfRangeException>(() => rc.SetCell(columnId, string.Empty));
}
[Fact]
public void SetCellNoChange()
{
// Setup: Generate a row create
RowCreate rc = GetStandardRowCreate();
// If: I set a cell in the newly created row to something that doesn't need changing
EditUpdateCellResult eucr = rc.SetCell(0, "1");
// Then:
// ... The returned value should not have corrections
Assert.False(eucr.HasCorrections);
Assert.Null(eucr.NewValue);
// ... The set value is not null
Assert.False(eucr.IsNull);
// ... The result is not an implicit revert
Assert.False(eucr.IsRevert);
// ... There should be a cell update in the cell list
Assert.NotNull(rc.newCells[0]);
}
[Fact]
public void SetCellHasCorrections()
{
// Setup:
// ... Generate a result set with a single binary column
DbColumn[] cols = {new TestDbColumn("bin", "binary", typeof(byte[]))};
object[][] rows = {};
var testResultSet = new TestResultSet(cols, rows);
var testReader = new TestDbDataReader(new[] {testResultSet});
var rs = new ResultSet(0, 0, MemoryFileSystem.GetFileStreamFactory());
rs.ReadResultToEnd(testReader, CancellationToken.None).Wait();
// ... Generate the metadata
var etm = Common.GetStandardMetadata(cols);
// ... Create the row create
RowCreate rc = new RowCreate(100, rs, etm);
// If: I set a cell in the newly created row to something that will be corrected
EditUpdateCellResult eucr = rc.SetCell(0, "1000");
// Then:
// ... The returned value should have corrections
Assert.True(eucr.HasCorrections);
Assert.NotEmpty(eucr.NewValue);
// ... The set value is not null
Assert.False(eucr.IsNull);
// ... The result is not an implicit revert
Assert.False(eucr.IsRevert);
// ... There should be a cell update in the cell list
Assert.NotNull(rc.newCells[0]);
}
[Fact]
public void SetCellNull()
{
// Setup: Generate a row create
RowCreate rc = GetStandardRowCreate();
// If: I set a cell in the newly created row to null
EditUpdateCellResult eucr = rc.SetCell(0, "NULL");
// Then:
// ... The returned value should not have corrections
Assert.False(eucr.HasCorrections);
Assert.Null(eucr.NewValue);
// ... The set value is null
Assert.True(eucr.IsNull);
// ... The result is not an implicit revert
Assert.False(eucr.IsRevert);
// ... There should be a cell update in the cell list
Assert.NotNull(rc.newCells[0]);
}
[Theory]
[InlineData(-1)] // Negative
[InlineData(3)] // At edge of acceptable values
[InlineData(100)] // Way too large value
public void RevertCellOutOfRange(int columnId)
{
// Setup: Generate the row create
RowCreate rc = GetStandardRowCreate();
// If: I attempt to revert a cell that is out of range
// Then: I should get an exception
Assert.Throws<ArgumentOutOfRangeException>(() => rc.RevertCell(columnId));
}
[Fact]
public void RevertCellNotSet()
{
// Setup: Generate the row create
RowCreate rc = GetStandardRowCreate();
// If: I attempt to revert a cell that has not been set
string result = rc.RevertCell(0);
// Then: We should get null back
// @TODO: Check for a default value when we support it
Assert.Null(result);
// ... The cell should no longer be set
Assert.Null(rc.newCells[0]);
}
[Fact]
public void RevertCellThatWasSet()
{
// Setup: Generate the row create
RowCreate rc = GetStandardRowCreate();
rc.SetCell(0, "1");
// If: I attempt to revert a cell that was set
string result = rc.RevertCell(0);
// Then:
// ... We should get null back
Assert.Null(result);
// ... The cell should no longer be set
Assert.Null(rc.newCells[0]);
}
private static RowCreate GetStandardRowCreate()
{
var cols = Common.GetColumns(false);
var rs = Common.GetResultSet(cols, false);
var etm = Common.GetStandardMetadata(cols);
return new RowCreate(100, rs, etm);
}
}
}

View File

@@ -153,5 +153,19 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
RowDelete rd = new RowDelete(0, rs, etm);
Assert.Throws<InvalidOperationException>(() => rd.SetCell(0, null));
}
[Fact]
public void RevertCell()
{
// Setup: Create a row delete
DbColumn[] cols = Common.GetColumns(false);
ResultSet rs = Common.GetResultSet(cols, false);
IEditTableMetadata etm = Common.GetStandardMetadata(cols);
RowDelete rd = new RowDelete(0, rs, etm);
// If: I revert a cell on a delete row edit
// Then: It should throw
Assert.Throws<InvalidOperationException>(() => rd.RevertCell(0));
}
}
}

View File

@@ -267,6 +267,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
throw new NotImplementedException();
}
public override string RevertCell(int columnId)
{
throw new NotImplementedException();
}
public override EditUpdateCellResult SetCell(int columnId, string newValue)
{
throw new NotImplementedException();

View File

@@ -6,10 +6,13 @@
using System;
using System.Data.Common;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.EditData;
using Microsoft.SqlTools.ServiceLayer.EditData.Contracts;
using Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement;
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility;
using Xunit;
@@ -35,7 +38,72 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
}
[Fact]
public void ImplicitRevertTest()
public void SetCell()
{
// Setup: Create a row update
var columns = Common.GetColumns(false);
var rs = Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
// If: I set a cell that can be updated
EditUpdateCellResult eucr = ru.SetCell(0, "col1");
// Then:
// ... The returned value should not have corrections
Assert.False(eucr.HasCorrections);
Assert.Null(eucr.NewValue);
// ... The set value is not null
Assert.False(eucr.IsNull);
// ... The result is not an implicit revert
Assert.False(eucr.IsRevert);
// ... There should be a cell update in the cell list
Assert.Contains(0, ru.cellUpdates.Keys);
Assert.NotNull(ru.cellUpdates[0]);
}
[Fact]
public void SetCellHasCorrections()
{
// Setup:
// ... Generate a result set with a single binary column
DbColumn[] cols = { new TestDbColumn("bin", "binary", typeof(byte[])) };
object[][] rows = { new object[]{new byte[] {0x00}}};
var testResultSet = new TestResultSet(cols, rows);
var testReader = new TestDbDataReader(new[] { testResultSet });
var rs = new ResultSet(0, 0, MemoryFileSystem.GetFileStreamFactory());
rs.ReadResultToEnd(testReader, CancellationToken.None).Wait();
// ... Generate the metadata
var etm = Common.GetStandardMetadata(cols);
// ... Create the row update
RowUpdate ru = new RowUpdate(0, rs, etm);
// If: I set a cell in the newly created row to something that will be corrected
EditUpdateCellResult eucr = ru.SetCell(0, "1000");
// Then:
// ... The returned value should have corrections
Assert.True(eucr.HasCorrections);
Assert.NotEmpty(eucr.NewValue);
// ... The set value is not null
Assert.False(eucr.IsNull);
// ... The result is not an implicit revert
Assert.False(eucr.IsRevert);
// ... There should be a cell update in the cell list
Assert.Contains(0, ru.cellUpdates.Keys);
Assert.NotNull(ru.cellUpdates[0]);
}
[Fact]
public void SetCellImplicitRevertTest()
{
// Setup: Create a fake table to update
DbColumn[] columns = Common.GetColumns(true);
@@ -216,5 +284,65 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// Then: I should get an exception
await Assert.ThrowsAsync<ArgumentNullException>(() => ru.ApplyChanges(null));
}
[Theory]
[InlineData(-1)] // Negative
[InlineData(3)] // At edge of acceptable values
[InlineData(100)] // Way too large value
public void RevertCellOutOfRange(int columnId)
{
// Setup:
// ... Create a row update (no cell updates needed)
var columns = Common.GetColumns(false);
var rs = Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
// If: I attempt to revert a cell that is out of range
// Then: I should get an exception
Assert.Throws<ArgumentOutOfRangeException>(() => ru.RevertCell(columnId));
}
[Fact]
public void RevertCellNotSet()
{
// Setup:
// ... Create a row update (no cell updates needed)
var columns = Common.GetColumns(true);
var rs = Common.GetResultSet(columns, true);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
// If: I attempt to revert a cell that has not been set
string result = ru.RevertCell(0);
// Then: We should get the original value back
Assert.NotEmpty(result);
// ... The cell should no longer be set
Assert.DoesNotContain(0, ru.cellUpdates.Keys);
}
[Fact]
public void RevertCellThatWasSet()
{
// Setup:
// ... Create a row update
var columns = Common.GetColumns(false);
var rs = Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
ru.SetCell(0, "1");
// If: I attempt to revert a cell that was set
string result = ru.RevertCell(0);
// Then:
// ... We should get the original value back
Assert.NotEmpty(result);
// ... The cell should no longer be set
Assert.DoesNotContain(0, ru.cellUpdates.Keys);
}
}
}

View File

@@ -6,14 +6,11 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
using Microsoft.SqlTools.ServiceLayer.EditData;
using Microsoft.SqlTools.ServiceLayer.EditData.Contracts;
using Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement;
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.Execution;
using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility;
using Moq;
using Xunit;

View File

@@ -117,7 +117,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Utility
/// <returns>Collection of test columns in the current result set</returns>
public ReadOnlyCollection<DbColumn> GetColumnSchema()
{
if (ResultSetEnumerator?.Current == null || ResultSetEnumerator.Current.Rows.Count <= 0)
if (ResultSetEnumerator?.Current == null)
{
return new ReadOnlyCollection<DbColumn>(new List<DbColumn>());
}
@@ -125,6 +125,22 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Utility
return new ReadOnlyCollection<DbColumn>(ResultSetEnumerator.Current.Columns);
}
public override long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length)
{
if (ResultSetEnumerator.Current.Columns[ordinal].DataType == typeof(byte[]))
{
byte[] data = (byte[]) this[ordinal];
if (buffer == null)
{
return data.Length;
}
Array.Copy(data, (int)dataOffset, buffer, bufferOffset, length);
return Math.Min(length, data.Length);
}
throw new InvalidOperationException();
}
#endregion
#region Not Implemented
@@ -139,11 +155,6 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Utility
throw new NotImplementedException();
}
public override long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length)
{
throw new NotImplementedException();
}
public override char GetChar(int ordinal)
{
throw new NotImplementedException();