Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/SqlAsyncCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,12 @@ private static void GenerateDataQueryForMerge(TableInformation table, IEnumerabl
else
{
// ToDo: add check for duplicate primary keys once we find a way to get primary keys.
// JObjects ignore serializer settings (https://web.archive.org/web/20171005181503/http://json.codeplex.com/workitem/23853)
// so we have to manually convert property names to lower case before inserting into the query in that case
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about case sensitive collations?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(even if this works, clarifying that it works in a comment would be helpful to readers)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Case sensitive has always been up to the caller to get right - we have no way of knowing what the expected case is. Case insensitive is just always converted to lower case for comparisons for convenience (since the casing still has to be the same, but we can control that for case insensitive)

https://github.com/Azure/azure-functions-sql-extension/blob/main/src/SqlAsyncCollector.cs#L526

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This behavior should be documented somewhere but I don't think this is the right place to get into that fine of detail. I'll see if I can find a better place to do that)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (table.Comparer == StringComparer.OrdinalIgnoreCase)
{
(row as JObject).LowercasePropertyNames();
}
rowsToUpsert.Add(row);
}
}
Expand Down
33 changes: 33 additions & 0 deletions src/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Linq;
using Microsoft.Extensions.Configuration;
using MoreLinq;
using Newtonsoft.Json.Linq;

namespace Microsoft.Azure.WebJobs.Extensions.Sql
{
Expand Down Expand Up @@ -60,5 +63,35 @@ private static bool AsBool(this string str, bool defaultValue = false)
return defaultValue;
}
}

/// <summary>
/// Recursively converts the property names for a JObject to lowercase
/// </summary>
/// <param name="obj">The JToken to convert</param>
public static void LowercasePropertyNames(this JToken token)
{
if (token is JObject jObj)
{
token.LowercasePropertyNames();
}
else if (token is JArray jArray)
{
token.ForEach(x => x.LowercasePropertyNames());
}
}

/// <summary>
/// Recursively converts the property names for a JObject to lowercase
/// </summary>
/// <param name="obj">The JObject to convert</param>
public static void LowercasePropertyNames(this JObject obj)
{
foreach (JProperty property in obj.Properties().ToList())
{
property.Value.LowercasePropertyNames();
// properties are read-only, so we have to replace them
property.Replace(new JProperty(property.Name.ToLowerInvariant(), property.Value));
}
}
}
}