Skip to content

Commit

Permalink
Support arrays in parameters value logging (#24596)
Browse files Browse the repository at this point in the history
Closes #24595
  • Loading branch information
roji authored Apr 8, 2021
1 parent 7a7df5f commit 784624e
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections;
using System.Data;
using System.Data.Common;
using System.Globalization;
Expand Down Expand Up @@ -140,54 +141,79 @@ public static string FormatParameter(

private static void FormatParameterValue(StringBuilder builder, object? parameterValue)
{
if (parameterValue == null
|| parameterValue == DBNull.Value)
switch (parameterValue)
{
builder.Append("NULL");
}
else if (parameterValue.GetType() == typeof(DateTime))
{
builder
.Append('\'')
.Append(((DateTime)parameterValue).ToString("o"))
.Append('\'');
}
else if (parameterValue.GetType() == typeof(DateTimeOffset))
{
builder
.Append('\'')
.Append(((DateTimeOffset)parameterValue).ToString("o"))
.Append('\'');
}
else if (parameterValue.GetType() == typeof(byte[]))
{
builder.AppendBytes((byte[])parameterValue);
}
else
{
var valueProperty = parameterValue.GetType().GetRuntimeProperty("Value");
if (valueProperty != null
&& valueProperty.PropertyType != parameterValue.GetType())
{
var isNullProperty = parameterValue.GetType().GetRuntimeProperty("IsNull");
if (isNullProperty != null
&& isNullProperty.GetValue(parameterValue) is bool isNull
&& isNull)
case null:
case DBNull:
builder.Append("NULL");
return;

case DateTime dateTime:
builder
.Append('\'')
.Append(dateTime.ToString("o"))
.Append('\'');
return;

case DateTimeOffset dateTimeOffset:
builder
.Append('\'')
.Append(dateTimeOffset.ToString("o"))
.Append('\'');
return;

case byte[] byteArray:
builder.AppendBytes(byteArray);
return;

case IList list:
builder.Append("{ ");

for (var i = 0; i < list.Count; i++)
{
if (i > 4)
{
builder.Append("...");
break;
}

FormatParameterValue(builder, list[i]);

if (i < list.Count - 1)
{
builder.Append(", ");
}
}

builder.Append(" }");
return;

default:
var type = parameterValue.GetType();
var valueProperty = type.GetRuntimeProperty("Value");
if (valueProperty != null
&& valueProperty.PropertyType != type)
{
builder.Append("''");
var isNullProperty = type.GetRuntimeProperty("IsNull");
if (isNullProperty != null
&& isNullProperty.GetValue(parameterValue) is bool isNull
&& isNull)
{
builder.Append("''");
}
else
{
FormatParameterValue(builder, valueProperty.GetValue(parameterValue));
}
}
else
{
FormatParameterValue(builder, valueProperty.GetValue(parameterValue));
builder
.Append('\'')
.Append(Convert.ToString(parameterValue, CultureInfo.InvariantCulture))
.Append('\'');
}
}
else
{
builder
.Append('\'')
.Append(Convert.ToString(parameterValue, CultureInfo.InvariantCulture))
.Append('\'');
}
return;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Microsoft.EntityFrameworkCore.Storage.Internal;
Expand All @@ -11,34 +12,6 @@ namespace Microsoft.EntityFrameworkCore.Storage
{
public class DbParameterCollectionExtensionsTest
{
[ConditionalFact]
public void Short_byte_arrays_are_not_truncated()
{
var shortArray = new Guid("21EC2020-3AEA-4069-A2DD-08002B30309D").ToByteArray();
var longerShortArray = shortArray.Concat(shortArray).ToArray();

Assert.Equal(
"@param='0x2020EC21EA3A6940A2DD08002B30309D'",
DbParameterCollectionExtensions.FormatParameter(
"@param", shortArray, true, ParameterDirection.Input, DbType.Binary, true, 0, 0, 0));

Assert.Equal(
"@param='0x2020EC21EA3A6940A2DD08002B30309D2020EC21EA3A6940A2DD08002B30309D'",
DbParameterCollectionExtensions.FormatParameter(
"@param", longerShortArray, true, ParameterDirection.Input, DbType.Binary, true, 0, 0, 0));
}

[ConditionalFact]
public void Long_byte_arrays_are_truncated()
{
var shortArray = new Guid("21EC2020-3AEA-4069-A2DD-08002B30309D").ToByteArray();
var longArray = shortArray.Concat(shortArray).Concat(shortArray).ToArray();

Assert.Equal(
"@param='0x2020EC21EA3A6940A2DD08002B30309D2020EC21EA3A6940A2DD08002B30309D...'",
DbParameterCollectionExtensions.FormatParameter(
"@param", longArray, true, ParameterDirection.Input, DbType.Binary, true, 0, 0, 0));
}

[ConditionalFact]
public void Formats_string_parameter()
Expand Down Expand Up @@ -565,5 +538,78 @@ public void Formats_TimeSpan_parameter_with_unusual_type()
DbParameterCollectionExtensions.FormatParameter(
"@param", new TimeSpan(-8, 0, 0), true, ParameterDirection.Input, DbType.DateTime, false, 0, 0, 0));
}

[ConditionalFact]
public void Short_byte_arrays_are_not_truncated()
{
var shortArray = new Guid("21EC2020-3AEA-4069-A2DD-08002B30309D").ToByteArray();
var longerShortArray = shortArray.Concat(shortArray).ToArray();

Assert.Equal(
"@param='0x2020EC21EA3A6940A2DD08002B30309D'",
DbParameterCollectionExtensions.FormatParameter(
"@param", shortArray, true, ParameterDirection.Input, DbType.Binary, true, 0, 0, 0));

Assert.Equal(
"@param='0x2020EC21EA3A6940A2DD08002B30309D2020EC21EA3A6940A2DD08002B30309D'",
DbParameterCollectionExtensions.FormatParameter(
"@param", longerShortArray, true, ParameterDirection.Input, DbType.Binary, true, 0, 0, 0));
}

[ConditionalFact]
public void Long_byte_arrays_are_truncated()
{
var shortArray = new Guid("21EC2020-3AEA-4069-A2DD-08002B30309D").ToByteArray();
var longArray = shortArray.Concat(shortArray).Concat(shortArray).ToArray();

Assert.Equal(
"@param='0x2020EC21EA3A6940A2DD08002B30309D2020EC21EA3A6940A2DD08002B30309D...'",
DbParameterCollectionExtensions.FormatParameter(
"@param", longArray, true, ParameterDirection.Input, DbType.Binary, true, 0, 0, 0));
}

[ConditionalFact]
public void Short_arrays_are_not_truncated()
{
var array = new[] { 1, 2, 3, 4, 5 };

Assert.Equal(
"@param={ '1', '2', '3', '4', '5' } (DbType = Object)",
DbParameterCollectionExtensions.FormatParameter(
"@param", array, true, ParameterDirection.Input, DbType.Object, true, 0, 0, 0));
}

[ConditionalFact]
public void Long_arrays_are_truncated()
{
var array = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

Assert.Equal(
"@param={ '1', '2', '3', '4', '5', ... } (DbType = Object)",
DbParameterCollectionExtensions.FormatParameter(
"@param", array, true, ParameterDirection.Input, DbType.Object, true, 0, 0, 0));
}

[ConditionalFact]
public void Short_generic_lists_are_not_truncated()
{
var array = new List<int> { 1, 2, 3, 4, 5 };

Assert.Equal(
"@param={ '1', '2', '3', '4', '5' } (DbType = Object)",
DbParameterCollectionExtensions.FormatParameter(
"@param", array, true, ParameterDirection.Input, DbType.Object, true, 0, 0, 0));
}

[ConditionalFact]
public void Long_generic_lists_are_truncated()
{
var array = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

Assert.Equal(
"@param={ '1', '2', '3', '4', '5', ... } (DbType = Object)",
DbParameterCollectionExtensions.FormatParameter(
"@param", array, true, ParameterDirection.Input, DbType.Object, true, 0, 0, 0));
}
}
}

0 comments on commit 784624e

Please # to comment.