Skip to content

Commit

Permalink
Fix bug SchemaTableBuilder to not skip valid table which partial addr…
Browse files Browse the repository at this point in the history
…ess issue # 188 by include the IsUnique as well as IsKey in the validation to determine hasKey

Address issue DataAction#192 for duplicate parameter name
Update test cases
  • Loading branch information
Tien Nguyen committed Sep 5, 2020
1 parent fb33c73 commit c5e9bb4
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 40 deletions.
7 changes: 5 additions & 2 deletions src/AdoNetCore.AseClient/AseCommandBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,12 +224,15 @@ private static DataTable GetSchemaTableWithKeyInfo(DbCommand sourceCommand)
if (dataTable != null)
{
// If there is no primary key on the table, then throw MissingPrimaryKeyException.
var isKeyColumn = dataTable.Columns["IsKey"];
var isKeyColumn = dataTable.Columns[SchemaTableColumn.IsKey];
var isUniqueColumn = dataTable.Columns[SchemaTableColumn.IsUnique];

var hasKey = false;

foreach (DataRow columnDescriptorRow in dataTable.Rows)
{
hasKey |= (bool)columnDescriptorRow[isKeyColumn];
hasKey |= (bool)columnDescriptorRow[isKeyColumn] ||
(bool)columnDescriptorRow[isUniqueColumn];

if (hasKey)
{
Expand Down
28 changes: 18 additions & 10 deletions src/AdoNetCore.AseClient/AseParameterCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -263,10 +263,10 @@ public AseParameter Add(string parameterName, AseDbType dbType, int size, Parame
/// <returns>A new <see cref="AseParameter" /> object.</returns>
public AseParameter Add(AseParameter parameter)
{
if (parameter != null)
{
_parameters.Add(parameter);
}
if (parameter == null) throw new ArgumentNullException(nameof(parameter));
if (Contains(parameter)) throw new ArgumentException($"parameter name '{parameter.ParameterName}' is already in the collection");

_parameters.Add(parameter);
return parameter;
}

Expand Down Expand Up @@ -379,6 +379,7 @@ public override int Add(object value)
{
if (value is AseParameter p)
{
if (Contains(p)) throw new ArgumentException($"Parameter name: '{p.ParameterName}' is already registered", nameof(value));
return ((IList)_parameters).Add(p);
}
return -1;
Expand Down Expand Up @@ -438,15 +439,23 @@ public override int IndexOf(object value)
/// Returns -1 when the object does not exist in the <see cref="AseParameterCollection" />.</returns>
public int IndexOf(AseParameter value)
{
if (value != null)
if (value == null) return -1;
for (var i = 0; i < _parameters.Count; i++)
{
for (var i = 0; i < _parameters.Count; i++)
if (string.IsNullOrWhiteSpace(value.ParameterName))
{
if (value == _parameters[i])
{
return i;
}
}
else
{
if (value == _parameters[i] || value.ParameterName == _parameters[i].ParameterName)
{
return i;
}
}
}

return -1;
Expand All @@ -459,6 +468,7 @@ public int IndexOf(AseParameter value)
/// <param name="parameter">The <see cref="AseParameter" /> object to add to the collection.</param>
public override void Insert(int index, object parameter)
{
if (Contains(parameter)) throw new ArgumentException($"parameter name '{parameter}' is already in the collection");
((IList)_parameters).Insert(index, parameter);
}

Expand All @@ -469,6 +479,7 @@ public override void Insert(int index, object parameter)
/// <param name="parameter">The <see cref="AseParameter" /> object to add to the collection.</param>
public void Insert(int index, AseParameter parameter)
{
if (Contains(parameter)) throw new ArgumentException($"parameter name '{parameter.ParameterName}' is already in the collection");
((IList)_parameters).Insert(index, parameter);
}

Expand Down Expand Up @@ -521,10 +532,7 @@ public override void RemoveAt(int index)
/// <param name="index">The starting index of the array.</param>
public override void CopyTo(Array array, int index)
{
if (array != null)
{
((IList)_parameters).CopyTo(array, index);
}
((IList)_parameters).CopyTo(array, index);
}

/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions src/AdoNetCore.AseClient/Internal/FormatItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ public string ParameterName

public static FormatItem CreateForParameter(AseParameter parameter, DbEnvironment env, AseCommand command)
{
parameter.AseDbType = TypeMap.InferType(parameter);

var dbType = parameter.DbType;
var length = TypeMap.GetFormatLength(dbType, parameter, env.Encoding);

parameter.AseDbType = TypeMap.InferType(parameter);

var format = command.FormatItem;
var parameterName = parameter.ParameterName ?? command.Parameters.IndexOf(parameter).ToString();
if (!(command.FormatItem != null && command.FormatItem.ParameterName == parameterName &&
Expand Down
7 changes: 1 addition & 6 deletions src/AdoNetCore.AseClient/Internal/SchemaTableBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,17 +130,12 @@ private FillTableResults FillTableFromFormats(DataTable table)
private void TryLoadKeyInfo(DataTable table, string baseTableNameValue, string baseSchemaNameValue, string baseCatalogNameValue)
{
if (_connection == null)
{
throw new InvalidOperationException("Invalid AseCommand.Connection");
}

if (_connection.State != ConnectionState.Open)
{
throw new InvalidOperationException("Invalid AseCommand.Connection.ConnectionState");
}

if (!string.IsNullOrWhiteSpace(baseTableNameValue) &&
!string.IsNullOrWhiteSpace(baseCatalogNameValue))
if (string.IsNullOrWhiteSpace(baseTableNameValue))
return;

using (var command = _connection.CreateCommand())
Expand Down
58 changes: 38 additions & 20 deletions test/AdoNetCore.AseClient.Tests/Integration/AseCommandTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Xml;
using AdoNetCore.AseClient.Internal;
using AdoNetCore.AseClient.Tests.Util;
Expand Down Expand Up @@ -236,28 +237,45 @@ public void Command_Reuse_ShouldWork_For_NonNull_Value(System.Data.DbType dbType
}
}
}

[Test]
public void Command_Duplicate_Parameter_Name_Should_Throws_ArgumentException()
{
using (var connection = GetConnection())
{
connection.Open();
var sql = "select @p1, @p2";
var aseCommand = connection.CreateCommand();
aseCommand.CommandText = sql;
aseCommand.CommandType = CommandType.Text;
aseCommand.Parameters.Add("@p1", "test");
aseCommand.Parameters.Add("@p2", "test2");
Assert.Throws<ArgumentException>(() => aseCommand.Parameters.Add("@p1", "test3"));
}
}

private static IEnumerable<TestCaseData> ReUseCommandTypeData()
{
yield return new TestCaseData(System.Data.DbType.Boolean, typeof(bool), false);
yield return new TestCaseData(System.Data.DbType.Byte, typeof(byte), 12);
yield return new TestCaseData(System.Data.DbType.SByte, typeof(sbyte), 2);
yield return new TestCaseData(System.Data.DbType.Int16, typeof(short), 3);
yield return new TestCaseData(System.Data.DbType.UInt16, typeof(ushort), 4);
yield return new TestCaseData(System.Data.DbType.Int32, typeof(int), 23);
yield return new TestCaseData(System.Data.DbType.UInt32, typeof(uint), 45);
yield return new TestCaseData(System.Data.DbType.Int64, typeof(long), 76434755);
yield return new TestCaseData(System.Data.DbType.UInt64, typeof(ulong), 1223);
yield return new TestCaseData(System.Data.DbType.String, typeof(string), "If it could only be like this always—always summer, always alone, the fruit always ripe");
yield return new TestCaseData(System.Data.DbType.AnsiString, typeof(string), "Doubt thou the stars are fire; Doubt that the sun doth move; Doubt truth to be a liar; But never doubt I love");
yield return new TestCaseData(System.Data.DbType.AnsiStringFixedLength, typeof(string), "For never was a story of more woe than this of Juliet and her Romeo.");
yield return new TestCaseData(System.Data.DbType.Guid, typeof(string), "e2207b47-3fce-4187-808f-e206398a9133");
yield return new TestCaseData(System.Data.DbType.Decimal, typeof(decimal), 342.23);
yield return new TestCaseData(System.Data.DbType.Currency, typeof(decimal), 1233.3);
yield return new TestCaseData(System.Data.DbType.Single, typeof(float), 20.34f);
yield return new TestCaseData(System.Data.DbType.Double, typeof(double), 3423.234d);
yield return new TestCaseData(System.Data.DbType.DateTime, typeof(DateTime), "2019-03-13 03:20:35.23 AM");
yield return new TestCaseData(System.Data.DbType.Date, typeof(DateTime), "2018-07-04 23:20:35.23 PM");
yield return new TestCaseData(System.Data.DbType.Time, typeof(DateTime), "2014-09-10 23:20:35");
yield return new TestCaseData(DbType.Boolean, typeof(bool), false);
yield return new TestCaseData(DbType.Byte, typeof(byte), 12);
yield return new TestCaseData(DbType.SByte, typeof(sbyte), 2);
yield return new TestCaseData(DbType.Int16, typeof(short), 3);
yield return new TestCaseData(DbType.UInt16, typeof(ushort), 4);
yield return new TestCaseData(DbType.Int32, typeof(int), 23);
yield return new TestCaseData(DbType.UInt32, typeof(uint), 45);
yield return new TestCaseData(DbType.Int64, typeof(long), 76434755);
yield return new TestCaseData(DbType.UInt64, typeof(ulong), 1223);
yield return new TestCaseData(DbType.String, typeof(string), "If it could only be like this always—always summer, always alone, the fruit always ripe");
yield return new TestCaseData(DbType.AnsiString, typeof(string), "Doubt thou the stars are fire; Doubt that the sun doth move; Doubt truth to be a liar; But never doubt I love");
yield return new TestCaseData(DbType.AnsiStringFixedLength, typeof(string), "For never was a story of more woe than this of Juliet and her Romeo.");
yield return new TestCaseData(DbType.Guid, typeof(string), "e2207b47-3fce-4187-808f-e206398a9133");
yield return new TestCaseData(DbType.Decimal, typeof(decimal), 342.23);
yield return new TestCaseData(DbType.Currency, typeof(decimal), 1233.3);
yield return new TestCaseData(DbType.Single, typeof(float), 20.34f);
yield return new TestCaseData(DbType.Double, typeof(double), 3423.234d);
yield return new TestCaseData(DbType.DateTime, typeof(DateTime), "2019-03-13 03:20:35.23 AM");
yield return new TestCaseData(DbType.Date, typeof(DateTime), "2018-07-04 23:20:35.23 PM");
yield return new TestCaseData(DbType.Time, typeof(DateTime), "2014-09-10 23:20:35");

}

Expand Down

0 comments on commit c5e9bb4

Please sign in to comment.