Skip to content

Commit 3ca79de

Browse files
authored
Remove all commonly rooted linq usage from main project (#5203)
1 parent 78ee2c2 commit 3ca79de

25 files changed

+298
-136
lines changed

src/Npgsql/Internal/Converters/FullTextSearch/TsVectorConverter.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Linq;
43
using System.Text;
54
using System.Threading;
65
using System.Threading.Tasks;
@@ -68,7 +67,13 @@ async ValueTask<NpgsqlTsVector> Read(bool async, PgReader reader, CancellationTo
6867
}
6968

7069
public override Size GetSize(SizeContext context, NpgsqlTsVector value, ref object? writeState)
71-
=> 4 + value.Sum(l => _encoding.GetByteCount(l.Text) + 1 + 2 + l.Count * 2);
70+
{
71+
var size = 4;
72+
foreach (var l in value)
73+
size += _encoding.GetByteCount(l.Text) + 1 + 2 + l.Count * 2;
74+
75+
return size;
76+
}
7277

7378
public override void Write(PgWriter writer, NpgsqlTsVector value)
7479
=> Write(async: false, writer, value, CancellationToken.None).GetAwaiter().GetResult();

src/Npgsql/Internal/NpgsqlConnector.Auth.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Diagnostics;
4-
using System.Linq;
54
using System.Net.Security;
65
using System.Security.Cryptography;
76
using System.Security.Cryptography.X509Certificates;
@@ -239,7 +238,9 @@ internal void AuthenticateSASLSha256Plus(ref string mechanism, ref string cbindF
239238
var cbindFlagBytes = Encoding.UTF8.GetBytes($"{cbindFlag},,");
240239

241240
var certificateHash = hashAlgorithm.ComputeHash(remoteCertificate.GetRawCertData());
242-
var cbindBytes = cbindFlagBytes.Concat(certificateHash).ToArray();
241+
var cbindBytes = new byte[cbindFlagBytes.Length + certificateHash.Length];
242+
cbindFlagBytes.CopyTo(cbindBytes, 0);
243+
certificateHash.CopyTo(cbindBytes, cbindFlagBytes.Length);
243244
cbind = Convert.ToBase64String(cbindBytes);
244245
successfulBind = true;
245246
IsScramPlus = true;

src/Npgsql/Internal/NpgsqlConnector.FrontendMessages.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Diagnostics;
4-
using System.Linq;
54
using System.Threading;
65
using System.Threading.Tasks;
76

@@ -11,7 +10,7 @@ partial class NpgsqlConnector
1110
{
1211
internal Task WriteDescribe(StatementOrPortal statementOrPortal, string name, bool async, CancellationToken cancellationToken = default)
1312
{
14-
Debug.Assert(name.All(c => c < 128));
13+
NpgsqlWriteBuffer.AssertASCIIOnly(name);
1514

1615
var len = sizeof(byte) + // Message code
1716
sizeof(int) + // Length
@@ -98,7 +97,7 @@ void Write(int maxRows)
9897

9998
internal async Task WriteParse(string sql, string statementName, List<NpgsqlParameter> inputParameters, bool async, CancellationToken cancellationToken = default)
10099
{
101-
Debug.Assert(statementName.All(c => c < 128));
100+
NpgsqlWriteBuffer.AssertASCIIOnly(statementName);
102101

103102
int queryByteLen;
104103
try
@@ -152,8 +151,8 @@ internal async Task WriteBind(
152151
bool async,
153152
CancellationToken cancellationToken = default)
154153
{
155-
Debug.Assert(statement.All(c => c < 128));
156-
Debug.Assert(portal.All(c => c < 128));
154+
NpgsqlWriteBuffer.AssertASCIIOnly(statement);
155+
NpgsqlWriteBuffer.AssertASCIIOnly(portal);
157156

158157
var headerLength =
159158
sizeof(byte) + // Message code

src/Npgsql/Internal/NpgsqlConnector.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System.Data;
55
using System.Diagnostics;
66
using System.IO;
7-
using System.Linq;
87
using System.Net;
98
using System.Net.Security;
109
using System.Net.Sockets;
@@ -958,7 +957,7 @@ void Connect(NpgsqlTimeout timeout)
958957
// Note that there aren't any timeout-able or cancellable DNS methods
959958
var endpoints = NpgsqlConnectionStringBuilder.IsUnixSocket(Host, Port, out var socketPath)
960959
? new EndPoint[] { new UnixDomainSocketEndPoint(socketPath) }
961-
: Dns.GetHostAddresses(Host).Select(a => new IPEndPoint(a, Port)).ToArray();
960+
: IPAddressesToEndpoints(Dns.GetHostAddresses(Host), Port);
962961
timeout.Check();
963962

964963
// Give each endpoint an equal share of the remaining time
@@ -997,7 +996,7 @@ void Connect(NpgsqlTimeout timeout)
997996
var errorCode = (int) socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Error)!;
998997
if (errorCode != 0)
999998
throw new SocketException(errorCode);
1000-
if (!write.Any())
999+
if (write.Count is 0)
10011000
throw new TimeoutException("Timeout during connection attempt");
10021001
socket.Blocking = true;
10031002
SetSocketOptions(socket);
@@ -1035,8 +1034,8 @@ Task<IPAddress[]> GetHostAddressesAsync(CancellationToken ct) =>
10351034
// and raises the exception, while the actual task may be left running.
10361035
var endpoints = NpgsqlConnectionStringBuilder.IsUnixSocket(Host, Port, out var socketPath)
10371036
? new EndPoint[] { new UnixDomainSocketEndPoint(socketPath) }
1038-
: (await TaskTimeoutAndCancellation.ExecuteAsync(GetHostAddressesAsync, timeout, cancellationToken))
1039-
.Select(a => new IPEndPoint(a, Port)).ToArray();
1037+
: IPAddressesToEndpoints(await TaskTimeoutAndCancellation.ExecuteAsync(GetHostAddressesAsync, timeout, cancellationToken),
1038+
Port);
10401039

10411040
// Give each IP an equal share of the remaining time
10421041
var perIpTimespan = default(TimeSpan);
@@ -1103,6 +1102,14 @@ Task ConnectAsync(CancellationToken ct) =>
11031102
}
11041103
}
11051104

1105+
IPEndPoint[] IPAddressesToEndpoints(IPAddress[] ipAddresses, int port)
1106+
{
1107+
var result = new IPEndPoint[ipAddresses.Length];
1108+
for (var i = 0; i < ipAddresses.Length; i++)
1109+
result[i] = new IPEndPoint(ipAddresses[i], port);
1110+
return result;
1111+
}
1112+
11061113
void SetSocketOptions(Socket socket)
11071114
{
11081115
if (socket.AddressFamily == AddressFamily.InterNetwork || socket.AddressFamily == AddressFamily.InterNetworkV6)

src/Npgsql/Internal/NpgsqlDatabaseInfo.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Diagnostics.CodeAnalysis;
4-
using System.Linq;
54
using System.Threading.Tasks;
65
using Npgsql.Internal.Postgres;
76
using Npgsql.PostgresTypes;
@@ -215,7 +214,11 @@ public bool TryGetPostgresTypeByName(string pgName, [NotNullWhen(true)] out Post
215214
if (ByFullName.TryGetValue($"pg_catalog.{pgName}", out pgType))
216215
return true;
217216

218-
var ambiguousTypes = ByFullName.Keys.Where(n => n.EndsWith($".{pgName}", StringComparison.Ordinal));
217+
var ambiguousTypes = new List<string>();
218+
foreach (var key in ByFullName.Keys)
219+
if (key.EndsWith($".{pgName}", StringComparison.Ordinal))
220+
ambiguousTypes.Add(key);
221+
219222
throw new ArgumentException($"More than one PostgreSQL type was found with the name {pgName}, " +
220223
$"please specify a full name including schema: {string.Join(", ", ambiguousTypes)}");
221224
}

src/Npgsql/Internal/NpgsqlWriteBuffer.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.Buffers.Binary;
33
using System.Diagnostics;
44
using System.IO;
5-
using System.Linq;
65
using System.Net.Sockets;
76
using System.Runtime.CompilerServices;
87
using System.Text;
@@ -472,7 +471,7 @@ public async Task WriteStreamRaw(Stream stream, int count, bool async, Cancellat
472471

473472
public void WriteNullTerminatedString(string s)
474473
{
475-
Debug.Assert(s.All(c => c < 128), "Method only supports ASCII strings");
474+
AssertASCIIOnly(s);
476475
Debug.Assert(WriteSpaceLeft >= s.Length + 1);
477476
WritePosition += Encoding.ASCII.GetBytes(s, 0, s.Length, Buffer, WritePosition);
478477
WriteByte(0);
@@ -581,5 +580,13 @@ internal byte[] GetContents()
581580
return buf;
582581
}
583582

583+
[Conditional("DEBUG")]
584+
internal static void AssertASCIIOnly(string s)
585+
{
586+
foreach (var c in s)
587+
if (c >= 128)
588+
Debug.Fail("Method only supports ASCII strings");
589+
}
590+
584591
#endregion
585592
}

src/Npgsql/Internal/Resolvers/UnmappedEnumTypeInfoResolver.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Diagnostics.CodeAnalysis;
4-
using System.Linq;
54
using System.Reflection;
65
using Npgsql.Internal.Converters;
76
using Npgsql.Internal.Postgres;
@@ -25,7 +24,7 @@ class UnmappedEnumTypeInfoResolver : DynamicTypeInfoResolver
2524
var labelToEnum = new Dictionary<string, Enum>();
2625
foreach (var field in mapping.Type.GetFields(BindingFlags.Static | BindingFlags.Public))
2726
{
28-
var attribute = (PgNameAttribute?)field.GetCustomAttributes(typeof(PgNameAttribute), false).FirstOrDefault();
27+
var attribute = (PgNameAttribute?)field.GetCustomAttribute(typeof(PgNameAttribute), false);
2928
var enumName = attribute?.PgName ?? options.DefaultNameTranslator.TranslateMemberName(field.Name);
3029
var enumValue = (Enum)field.GetValue(null)!;
3130

src/Npgsql/Internal/TypeInfoResolverChain.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Linq;
43
using Npgsql.Internal.Postgres;
54

65
namespace Npgsql.Internal;
@@ -10,7 +9,7 @@ sealed class TypeInfoResolverChain : IPgTypeInfoResolver
109
readonly IPgTypeInfoResolver[] _resolvers;
1110

1211
public TypeInfoResolverChain(IEnumerable<IPgTypeInfoResolver> resolvers)
13-
=> _resolvers = resolvers.ToArray();
12+
=> _resolvers = new List<IPgTypeInfoResolver>(resolvers).ToArray();
1413

1514
public PgTypeInfo? GetTypeInfo(Type? type, DataTypeName? dataTypeName, PgSerializerOptions options)
1615
{

src/Npgsql/KerberosUsernameProvider.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Diagnostics;
33
using System.IO;
4-
using System.Linq;
54
using System.Threading;
65
using System.Threading.Tasks;
76
using Microsoft.Extensions.Logging;
@@ -112,8 +111,15 @@ sealed class KerberosUsernameProvider
112111
return includeRealm ? _principalWithRealm : _principalWithoutRealm;
113112
}
114113

115-
static string? FindInPath(string name) => Environment.GetEnvironmentVariable("PATH")
116-
?.Split(Path.PathSeparator)
117-
.Select(p => Path.Combine(p, name))
118-
.FirstOrDefault(File.Exists);
114+
static string? FindInPath(string name)
115+
{
116+
foreach (var p in Environment.GetEnvironmentVariable("PATH")?.Split(Path.PathSeparator) ?? Array.Empty<string>())
117+
{
118+
var path = Path.Combine(p, name);
119+
if (File.Exists(path))
120+
return path;
121+
}
122+
123+
return null;
124+
}
119125
}

src/Npgsql/NameTranslation/NpgsqlSnakeCaseNameTranslator.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Globalization;
3-
using System.Linq;
44
using System.Text;
55

66
namespace Npgsql.NameTranslation;
@@ -59,8 +59,17 @@ public string TranslateMemberName(string clrName)
5959
throw new ArgumentNullException(nameof(clrName));
6060

6161
return LegacyMode
62-
? string.Concat(clrName.Select((c, i) => i > 0 && char.IsUpper(c) ? "_" + c.ToString() : c.ToString())).ToLower(_culture)
62+
? string.Concat(LegacyModeMap(clrName)).ToLower(_culture)
6363
: ConvertToSnakeCase(clrName, _culture);
64+
65+
IEnumerable<string> LegacyModeMap(string clrName)
66+
{
67+
for (var i = 0; i < clrName.Length; i++)
68+
{
69+
var c = clrName[i];
70+
yield return i > 0 && char.IsUpper(c) ? "_" + c.ToString() : c.ToString();
71+
}
72+
}
6473
}
6574

6675
/// <summary>

0 commit comments

Comments
 (0)