Skip to content

Commit

Permalink
Clean up PR #24588
Browse files Browse the repository at this point in the history
  • Loading branch information
bricelam committed Apr 26, 2021
1 parent 9e17139 commit 3e2db5e
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 18 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/Microsoft.Data.Sqlite.Core/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -219,4 +219,7 @@
<data name="UnknownCollection" xml:space="preserve">
<value>The requested collection '{collectionName}' is not defined.</value>
</data>
<data name="AmbiguousColumnName" xml:space="preserve">
<value>The name '{name}' is ambiguous between columns '{column1}' and '{column2}'. Specify one using its exact case.</value>
</data>
</root>
3 changes: 1 addition & 2 deletions src/Microsoft.Data.Sqlite.Core/SqliteDataReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,8 @@ public override int RecordsAffected
/// <summary>
/// Gets the value of the specified column.
/// </summary>
/// <param name="name">The name of the column.</param>
/// <param name="name">The name of the column. The value is case-sensitive.</param>
/// <returns>The value.</returns>
/// <remarks>Performs a case-sensitive lookup first. If it fails, a second, case-insensitive search occurs.</remarks>
/// <seealso href="https://docs.microsoft.com/dotnet/standard/data/sqlite/types">Data Types</seealso>
public override object this[string name]
=> _record == null
Expand Down
27 changes: 21 additions & 6 deletions src/Microsoft.Data.Sqlite.Core/SqliteDataRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,17 +127,32 @@ public virtual int GetOrdinal(string name)
_columnNameOrdinalCache[GetName(i)] = i;
}
}

if (_columnNameOrdinalCache.TryGetValue(name, out var ordinal))
{
return ordinal;
}

var insensitiveMatchingColumns = _columnNameOrdinalCache.Where(kv => kv.Key.Equals(name, StringComparison.OrdinalIgnoreCase));
if(insensitiveMatchingColumns.Count() == 1) {
ordinal = insensitiveMatchingColumns.First().Value;
_columnNameOrdinalCache.Add(name, ordinal);
return ordinal;
KeyValuePair<string, int>? match = null;
foreach (var item in _columnNameOrdinalCache)
{
if (string.Equals(name, item.Key, StringComparison.OrdinalIgnoreCase))
{
if (match != null)
{
throw new InvalidOperationException(
Resources.AmbiguousColumnName(name, match.Value.Key, item.Key));
}

match = item;
}
}

if (match != null)
{
_columnNameOrdinalCache.Add(name, match.Value.Value);

return match.Value.Value;
}

// NB: Message is provided by framework
Expand Down
30 changes: 20 additions & 10 deletions test/Microsoft.Data.Sqlite.Tests/SqliteDataReaderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1276,25 +1276,35 @@ public void GetOrdinal_works()
}
}

[Theory]
[InlineData("SELECT 1;", "Name")]
[InlineData("SELECT 1 as Id, 2 as ID;", "id")]
public void GetOrdinal_throws_when_out_of_range(string query, string columnName)
[Fact]
public void GetOrdinal_throws_when_out_of_range()
{
using (var connection = new SqliteConnection("Data Source=:memory:"))
{
connection.Open();

using (var reader = connection.ExecuteReader(query))
using (var reader = connection.ExecuteReader("SELECT 1;"))
{
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => reader.GetOrdinal(columnName));
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => reader.GetOrdinal("Name"));
Assert.NotNull(ex.Message);
Assert.Equal("name", ex.ParamName);
Assert.Equal(columnName, ex.ActualValue);
Assert.Equal("Name", ex.ActualValue);
}
}
}

[Fact]
public void GetOrdinal_throws_when_ambiguous()
{
using var connection = new SqliteConnection("Data Source=:memory:");
connection.Open();

using var reader = connection.ExecuteReader("SELECT 1 AS Id, 2 AS ID");
var ex = Assert.Throws<InvalidOperationException>(() => reader.GetOrdinal("id"));

Assert.Contains(Resources.AmbiguousColumnName("id", "Id", "ID"), ex.Message);
}

[Fact]
public void GetOrdinal_throws_when_closed()
{
Expand Down Expand Up @@ -1586,9 +1596,9 @@ public void Item_by_ordinal_throws_when_non_query()
}

[Theory]
[InlineData("SELECT 1 as Id;", "Id", 1L)]
[InlineData("SELECT 1 as Id;", "id", 1L)]
[InlineData("SELECT 1 as Id, 2 as id;", "id", 2L)]
[InlineData("SELECT 1 AS Id;", "Id", 1L)]
[InlineData("SELECT 1 AS Id;", "id", 1L)]
[InlineData("SELECT 1 AS Id, 2 AS id;", "id", 2L)]
public void Item_by_name_works(string query, string column, long expected)
{
using (var connection = new SqliteConnection("Data Source=:memory:"))
Expand Down

0 comments on commit 3e2db5e

Please sign in to comment.