refactor: address code review findings across all projects
Apply comprehensive fixes from code reviews including: - Extract shared utilities (SqlFormatHelper, CellValueConverter, DbDestinationBase) - Add interface abstractions (IAuthenticationService, IDatabaseMigrator, IMisQueryBuilder) - Implement SecureStore for encrypted secrets storage - Fix error handling with proper HTTP status codes and logging - Optimize double enumeration in DevEtlRegistry - Add DataSync.Dev README for developer onboarding - Extract filter panel base classes to reduce duplication - Update code review docs to mark all issues as fixed
This commit is contained in:
+61
-103
@@ -15,141 +15,99 @@ public partial class LotFinderRepository
|
||||
/// <inheritdoc/>
|
||||
public async Task<List<Search>> GetUserSearchesAsync(string userName, CancellationToken ct = default)
|
||||
{
|
||||
const string operation = nameof(GetUserSearchesAsync);
|
||||
try
|
||||
{
|
||||
await using var connection = await _connectionFactory.CreateLotFinderConnectionAsync(ct);
|
||||
var result = await connection.QueryAsync<Search>(
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(userName);
|
||||
|
||||
return await ExecuteQueryAsync(
|
||||
nameof(GetUserSearchesAsync),
|
||||
"SQL_GET_USER_SEARCHES",
|
||||
async connection => (await connection.QueryAsync<Search>(
|
||||
LotFinderQueries.SqlGetUserSearches,
|
||||
new { userName },
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds);
|
||||
return result.ToList();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAndThrow(ex, operation, "SQL_GET_USER_SEARCHES");
|
||||
throw; // Unreachable but satisfies compiler
|
||||
}
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds)).ToList(),
|
||||
ct);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<List<Search>> GetQueuedSearchesAsync(CancellationToken ct = default)
|
||||
{
|
||||
const string operation = nameof(GetQueuedSearchesAsync);
|
||||
try
|
||||
{
|
||||
await using var connection = await _connectionFactory.CreateLotFinderConnectionAsync(ct);
|
||||
var result = await connection.QueryAsync<Search>(
|
||||
return await ExecuteQueryAsync(
|
||||
nameof(GetQueuedSearchesAsync),
|
||||
"SQL_GET_QUEUED_SEARCHES",
|
||||
async connection => (await connection.QueryAsync<Search>(
|
||||
LotFinderQueries.SqlGetQueuedSearches,
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds);
|
||||
return result.ToList();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAndThrow(ex, operation, "SQL_GET_QUEUED_SEARCHES");
|
||||
throw;
|
||||
}
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds)).ToList(),
|
||||
ct);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<Search?> GetSearchAsync(int id, CancellationToken ct = default)
|
||||
{
|
||||
const string operation = nameof(GetSearchAsync);
|
||||
try
|
||||
{
|
||||
await using var connection = await _connectionFactory.CreateLotFinderConnectionAsync(ct);
|
||||
var result = await connection.QueryFirstOrDefaultAsync<Search>(
|
||||
LotFinderQueries.SqlGetSearch,
|
||||
new { id },
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds);
|
||||
|
||||
if (result != null)
|
||||
return await ExecuteQueryAsync(
|
||||
nameof(GetSearchAsync),
|
||||
"SQL_GET_SEARCH",
|
||||
async connection =>
|
||||
{
|
||||
result.Id = id;
|
||||
}
|
||||
var result = await connection.QueryFirstOrDefaultAsync<Search>(
|
||||
LotFinderQueries.SqlGetSearch,
|
||||
new { id },
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds);
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAndThrow(ex, operation, "SQL_GET_SEARCH");
|
||||
throw;
|
||||
}
|
||||
if (result != null)
|
||||
{
|
||||
result.Id = id;
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
ct);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<byte[]?> GetSearchResultsAsync(int id, CancellationToken ct = default)
|
||||
{
|
||||
const string operation = nameof(GetSearchResultsAsync);
|
||||
try
|
||||
{
|
||||
await using var connection = await _connectionFactory.CreateLotFinderConnectionAsync(ct);
|
||||
return await connection.QueryFirstOrDefaultAsync<byte[]>(
|
||||
return await ExecuteQueryAsync(
|
||||
nameof(GetSearchResultsAsync),
|
||||
"SQL_GET_SEARCH_RESULTS",
|
||||
connection => connection.QueryFirstOrDefaultAsync<byte[]>(
|
||||
LotFinderQueries.SqlGetSearchResults,
|
||||
new { id },
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAndThrow(ex, operation, "SQL_GET_SEARCH_RESULTS");
|
||||
throw;
|
||||
}
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds),
|
||||
ct);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<int> SubmitSearchAsync(Search search, CancellationToken ct = default)
|
||||
{
|
||||
const string operation = nameof(SubmitSearchAsync);
|
||||
try
|
||||
{
|
||||
search.Status = SearchStatus.Queued;
|
||||
search.SubmitDt = DateTime.UtcNow;
|
||||
ArgumentNullException.ThrowIfNull(search);
|
||||
|
||||
await using var connection = await _connectionFactory.CreateLotFinderConnectionAsync(ct);
|
||||
await using var command = new SqlCommand(SqlObjects.SubmitSearch, connection)
|
||||
search.Status = SearchStatus.Queued;
|
||||
search.SubmitDt = DateTime.UtcNow;
|
||||
|
||||
return await ExecuteQueryAsync(
|
||||
nameof(SubmitSearchAsync),
|
||||
SqlObjects.SubmitSearch,
|
||||
async connection =>
|
||||
{
|
||||
CommandType = CommandType.StoredProcedure,
|
||||
CommandTimeout = _options.Value.DefaultTimeoutSeconds
|
||||
};
|
||||
await using var command = new SqlCommand(SqlObjects.SubmitSearch, connection)
|
||||
{
|
||||
CommandType = CommandType.StoredProcedure,
|
||||
CommandTimeout = _options.Value.DefaultTimeoutSeconds
|
||||
};
|
||||
|
||||
command.Parameters.AddWithValue("p_UserName", search.UserName);
|
||||
command.Parameters.AddWithValue("p_Name", search.Name);
|
||||
command.Parameters.AddWithValue("p_Criteria", search.CriteriaJson);
|
||||
command.Parameters.AddWithValue("p_UserName", search.UserName);
|
||||
command.Parameters.AddWithValue("p_Name", search.Name);
|
||||
command.Parameters.AddWithValue("p_Criteria", search.CriteriaJson);
|
||||
|
||||
var searchIdParam = new SqlParameter("o_SearchID", SqlDbType.Int)
|
||||
{
|
||||
Direction = ParameterDirection.Output
|
||||
};
|
||||
command.Parameters.Add(searchIdParam);
|
||||
var searchIdParam = new SqlParameter("o_SearchID", SqlDbType.Int)
|
||||
{
|
||||
Direction = ParameterDirection.Output
|
||||
};
|
||||
command.Parameters.Add(searchIdParam);
|
||||
|
||||
await command.ExecuteNonQueryAsync(ct);
|
||||
return Convert.ToInt32(searchIdParam.Value);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAndThrow(ex, operation, SqlObjects.SubmitSearch);
|
||||
throw;
|
||||
}
|
||||
await command.ExecuteNonQueryAsync(ct);
|
||||
return Convert.ToInt32(searchIdParam.Value);
|
||||
},
|
||||
ct);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user