|
3 | 3 | using Npgsql; |
4 | 4 | using System.Data; |
5 | 5 | using System.Text; |
| 6 | +using System.Text.RegularExpressions; |
| 7 | +using System.Threading; |
6 | 8 |
|
7 | 9 | namespace Medallion.Threading.Postgres; |
8 | 10 |
|
@@ -226,11 +228,11 @@ private static async ValueTask<bool> ShouldDefineSavePoint(DatabaseConnection co |
226 | 228 | if (!connection.IsExernallyOwned) { return connection.HasTransaction; } |
227 | 229 |
|
228 | 230 | // If the connection is externally-owned with an established transaction, |
229 | | - // it means that the connection came through the transactional locking APIs (see PostgresDistributedLock.Extensions class). |
| 231 | + // it means that the connection came through the transactional locking APIs (see PostgresDistributedLock.Transactions.cs). |
230 | 232 | if (connection.HasTransaction) { return true; } |
231 | 233 |
|
232 | 234 | // The externally-owned connection might still be part of a transaction that we can't see. |
233 | | - // This can only be the case if the externally-owned connection didn't came through the transactional locking APIs (see PostgresDistributedLock.Extensions class). |
| 235 | + // This can only be the case if the externally-owned connection didn't came through the transactional locking APIs (see PostgresDistributedLock.Transactions.cs). |
234 | 236 | // In that case, the only real way to detect the transaction is to begin a new one. |
235 | 237 | try |
236 | 238 | { |
@@ -299,7 +301,7 @@ private static string AddKeyParametersAndGetKeyArguments(DatabaseCommand command |
299 | 301 |
|
300 | 302 | private static bool UseTransactionScopedLock(DatabaseConnection connection) => |
301 | 303 | // Transaction-scoped locking is supported on internally-owned connections and externally-owned connections which explicitly have a transaction |
302 | | - // (meaning that the external connection came through the transactional locking APIs, see PostgresDistributedLock.Extensions class). |
| 304 | + // (meaning that the external connection came through the transactional locking APIs, see PostgresDistributedLock.Transactions.cs). |
303 | 305 | connection.HasTransaction; |
304 | 306 |
|
305 | 307 | private static string AddPGLocksFilterParametersAndGetFilterExpression(DatabaseCommand command, PostgresAdvisoryLockKey key) |
@@ -331,34 +333,15 @@ private static string AddPGLocksFilterParametersAndGetFilterExpression(DatabaseC |
331 | 333 | return $"(l.classid = @{classIdParameter} AND l.objid = @{objIdParameter} AND l.objsubid = {objSubId})"; |
332 | 334 | } |
333 | 335 |
|
334 | | - private readonly struct CapturedTimeoutSettings |
| 336 | + private readonly struct CapturedTimeoutSettings(string statementTimeout, string lockTimeout) |
335 | 337 | { |
336 | | - public CapturedTimeoutSettings(string statementTimeout, string lockTimeout) |
337 | | - { |
338 | | - this.StatementTimeout = ParsePostgresTimeout(statementTimeout); |
339 | | - this.LockTimeout = ParsePostgresTimeout(lockTimeout); |
340 | | - } |
341 | | - |
342 | | - public int StatementTimeout { get; } |
343 | | - |
344 | | - public int LockTimeout { get; } |
345 | | - |
346 | | - private static int ParsePostgresTimeout(string timeout) |
347 | | - { |
348 | | - if (timeout == "0") { return 0; } // This will be the case if the timeout is disabled. |
| 338 | + public int StatementTimeout { get; } = ParsePostgresTimeout(statementTimeout); |
349 | 339 |
|
350 | | - // In any other case we need to extract the timeout from the string, since Postgres returns timeouts with their unit attached, e.g. "5000ms". |
351 | | - var timeoutOnlyDigits = string.Empty; |
| 340 | + public int LockTimeout { get; } = ParsePostgresTimeout(lockTimeout); |
352 | 341 |
|
353 | | - for (var i = 0; i < timeout.Length; ++i) |
354 | | - { |
355 | | - if (char.IsDigit(timeout[i])) |
356 | | - { |
357 | | - timeoutOnlyDigits += timeout[i]; |
358 | | - } |
359 | | - } |
360 | | - |
361 | | - return int.Parse(timeoutOnlyDigits); |
362 | | - } |
| 342 | + private static int ParsePostgresTimeout(string timeout) => |
| 343 | + Regex.Match(timeout, @"^\d+(?=(?:ms)?$)") is { Success: true, Value: var value } |
| 344 | + ? int.Parse(value) |
| 345 | + : throw new FormatException($"Unexpected timeout setting value '{timeout}'"); |
363 | 346 | } |
364 | 347 | } |
0 commit comments