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

@@ -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,