Fix for multiple parameter error. (#1082)

* Clearing first use of parameters

* restore space

* added finally block

* Added try catch block in correct position

* fixed spacing

* added space before try

* duplicate row check simplified by Alan

* Revert "duplicate row check simplified by Alan"

This reverts commit 445ac506bd96b353266778abd0cf9bad2be2a3c3.

* removed exception and changed message

* added exception back for test purposes

* added working executescalar

* Added "<=" for delete action that deletes nothing.

* spacing fix for check duplicate

* Added comments and changed function logic.

* added clarifying message

* Added new extended class

* small space fix
This commit is contained in:
Alex Ma
2020-09-25 10:52:59 -07:00
committed by GitHub
parent fd4d067e71
commit 47e7a2f492
3 changed files with 90 additions and 23 deletions

View File

@@ -89,9 +89,9 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
WhereClause where = GetWhereClause(true);
string commandText = GetCommandText(where.CommandText);
string verifyText = GetVerifyText(where.CommandText);
if (!CheckForDuplicateDeleteRows(where, verifyText, connection))
if (HasDuplicateRows(where, verifyText, connection))
{
throw new EditDataDeleteException("This action will delete more than one row!");
throw new EditDataDeleteException("Cannot delete: Action will delete more than one row");
}
DbCommand command = connection.CreateCommand();
@@ -103,34 +103,23 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
/// <summary>
/// Runs a query using the where clause to determine if duplicates are found (causes issues when deleting).
/// If no duplicates are found, the check passes, else it returns false;
/// If duplicates are found, the check returns true, else it returns false;
/// </summary>
private bool CheckForDuplicateDeleteRows(WhereClause where, string input, DbConnection connection)
private bool HasDuplicateRows(WhereClause where, string input, DbConnection connection)
{
using (DbCommand command = connection.CreateCommand())
{
command.CommandText = input;
command.Parameters.AddRange(where.Parameters.ToArray());
using (DbDataReader reader = command.ExecuteReader())
try
{
try
{
while (reader.Read())
{
//If the count of the row is
if (reader.GetInt32(0) != 1)
{
return false;
}
}
}
catch (Exception ex)
{
Logger.Write(TraceEventType.Error, ex.ToString());
}
return (Convert.ToInt32(command.ExecuteScalar())) > 1;
}
finally
{
command.Parameters.Clear();
}
}
return true;
}
/// <summary>

View File

@@ -83,7 +83,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
RowDelete rd = new RowDelete(0, rs, data.TableMetadata);
// ... Mock db connection for building the command
var mockConn = new TestSqlConnection(null);
var mockConn = new TestEditDataSqlConnection(null);
// If: I attempt to get a command for the edit
DbCommand cmd = rd.GetCommand(mockConn);
@@ -235,7 +235,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
Assert.AreEqual(expectedKeys, whereComponents.Length);
// ... Mock db connection for building the command
var mockConn = new TestSqlConnection(new[] { testResultSet });
var mockConn = new TestEditDataSqlConnection(new[] { testResultSet });
// If: I attempt to get a command for a simulated delete of a row with duplicates.
// Then: The Command will throw an exception as it detects there are

View File

@@ -190,6 +190,63 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Utility
private List<DbParameter> listParams = new List<DbParameter>();
}
/// <summary>
/// Test mock class for IDbCommand (Modified for Edit Data)
/// </summary>
public class TestEditDataSqlCommand : TestSqlCommand
{
internal TestEditDataSqlCommand(TestResultSet[] data) : base(data)
{
}
/// <summary>
/// Function to check for duplicates in Data's rows.
/// Returns the max duplicate count for a unique row value (int).
/// </summary>
public override object ExecuteScalar()
{
if (Data != null)
{
//Get row data and set up row count map.
object[] rowData = Data[0].Rows[0];
Dictionary<object, int> rowCountMap = new Dictionary<object, int>();
//Go through each row value.
foreach (object rowValue in rowData)
{
if (rowCountMap.ContainsKey(rowValue))
{
// Add to existing count
rowCountMap[rowValue] += 1;
}
else
{
// New unique value found, add to map with 1 count.
rowCountMap.Add(rowValue, 1);
}
}
// Find the greatest number of duplicates among unique values
// in the map and return it.
int maxCount = 0;
foreach (var rowCount in rowCountMap)
{
if (rowCount.Value > maxCount)
{
maxCount = rowCount.Value;
}
}
return maxCount;
}
else
{
// Return 0 if Data is not provided.
return 0;
}
}
}
/// <summary>
/// Test mock class for SqlConnection wrapper
/// </summary>
@@ -270,6 +327,27 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Utility
}
}
/// <summary>
/// Test mock class for SqlConnection wrapper (Modified for Edit Data)
/// </summary>
public class TestEditDataSqlConnection : TestSqlConnection
{
public TestEditDataSqlConnection()
{
}
public TestEditDataSqlConnection(TestResultSet[] data) : base(data)
{
}
protected override DbCommand CreateDbCommand()
{
return new TestEditDataSqlCommand(Data);
}
}
/// <summary>
/// Test mock class for SqlConnection factory
/// </summary>