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:
@@ -42,10 +42,11 @@ public static class DataAccessDependencyInjection
|
||||
// Register SqlKata compiler (singleton, thread-safe)
|
||||
services.AddSingleton<SqlServerCompiler>();
|
||||
|
||||
// Register query builder (scoped)
|
||||
// Register query builders (scoped)
|
||||
// Note: Filter criteria are extracted from database JSON using SQL functions,
|
||||
// eliminating the need for filter handler classes.
|
||||
services.AddScoped<ISearchQueryBuilder, SqlKataSearchQueryBuilder>();
|
||||
services.AddScoped<IMisQueryBuilder, MisQueryBuilder>();
|
||||
|
||||
// Register search processing services (scoped)
|
||||
services.AddScoped<IWorkOrderTraversalService, WorkOrderTraversalService>();
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace JdeScoping.DataAccess.QueryBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// Interface for building MIS (Manufacturing Information System) extraction queries.
|
||||
/// </summary>
|
||||
public interface IMisQueryBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Builds the complete MIS extraction SQL including temp table setup and data population.
|
||||
/// Uses extraction functions to get filter criteria from the database.
|
||||
/// </summary>
|
||||
/// <param name="searchId">The search ID to extract criteria from.</param>
|
||||
/// <returns>The SQL statements for MIS extraction.</returns>
|
||||
IReadOnlyList<string> BuildMisExtractionSql(int searchId);
|
||||
}
|
||||
@@ -6,7 +6,7 @@ namespace JdeScoping.DataAccess.QueryBuilders;
|
||||
/// Builds MIS extraction queries for work order step matching.
|
||||
/// Uses SQL extraction functions to retrieve criteria from Search.Criteria JSON.
|
||||
/// </summary>
|
||||
public sealed class MisQueryBuilder
|
||||
public sealed class MisQueryBuilder : IMisQueryBuilder
|
||||
{
|
||||
private readonly SqlServerCompiler _compiler;
|
||||
|
||||
|
||||
@@ -12,23 +12,12 @@ public partial class LotFinderRepository
|
||||
/// <inheritdoc/>
|
||||
public async Task<List<DataUpdate>> GetLastDataUpdatesAsync(CancellationToken ct = default)
|
||||
{
|
||||
const string operation = nameof(GetLastDataUpdatesAsync);
|
||||
try
|
||||
{
|
||||
await using var connection = await _connectionFactory.CreateLotFinderConnectionAsync(ct);
|
||||
var result = await connection.QueryAsync<DataUpdate>(
|
||||
return await ExecuteQueryAsync(
|
||||
nameof(GetLastDataUpdatesAsync),
|
||||
"SQL_GET_LAST_DATA_UPDATES",
|
||||
async connection => (await connection.QueryAsync<DataUpdate>(
|
||||
LotFinderQueries.SqlGetLastDataUpdates,
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds);
|
||||
return result.ToList();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAndThrow(ex, operation, "SQL_GET_LAST_DATA_UPDATES");
|
||||
throw;
|
||||
}
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds)).ToList(),
|
||||
ct);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,175 +16,112 @@ public partial class LotFinderRepository
|
||||
/// <inheritdoc/>
|
||||
public async Task<List<Item>> SearchItemsAsync(string filter, CancellationToken ct = default)
|
||||
{
|
||||
const string operation = nameof(SearchItemsAsync);
|
||||
try
|
||||
{
|
||||
await using var connection = await _connectionFactory.CreateLotFinderConnectionAsync(ct);
|
||||
var result = await connection.QueryAsync<Item>(
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(filter);
|
||||
|
||||
return await ExecuteQueryAsync(
|
||||
nameof(SearchItemsAsync),
|
||||
"SQL_SEARCH_ITEMS",
|
||||
async connection => (await connection.QueryAsync<Item>(
|
||||
LotFinderQueries.SqlSearchItems,
|
||||
new { filter },
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds);
|
||||
return result.ToList();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAndThrow(ex, operation, "SQL_SEARCH_ITEMS");
|
||||
throw;
|
||||
}
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds)).ToList(),
|
||||
ct);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<List<Item>> LookupItemsAsync(List<string> itemNumbers, CancellationToken ct = default)
|
||||
{
|
||||
const string operation = nameof(LookupItemsAsync);
|
||||
try
|
||||
{
|
||||
var itemNumbersCsv = string.Join(",", itemNumbers);
|
||||
ArgumentNullException.ThrowIfNull(itemNumbers);
|
||||
|
||||
await using var connection = await _connectionFactory.CreateLotFinderConnectionAsync(ct);
|
||||
var result = await connection.QueryAsync<Item>(
|
||||
var itemNumbersCsv = string.Join(",", itemNumbers);
|
||||
|
||||
return await ExecuteQueryAsync(
|
||||
nameof(LookupItemsAsync),
|
||||
"SQL_LOOKUP_ITEMS",
|
||||
async connection => (await connection.QueryAsync<Item>(
|
||||
LotFinderQueries.SqlLookupItems,
|
||||
new { itemNumbers = itemNumbersCsv },
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds);
|
||||
return result.ToList();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAndThrow(ex, operation, "SQL_LOOKUP_ITEMS");
|
||||
throw;
|
||||
}
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds)).ToList(),
|
||||
ct);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<List<WorkOrder>> LookupWorkordersAsync(List<long> workorderNumbers, CancellationToken ct = default)
|
||||
{
|
||||
const string operation = nameof(LookupWorkordersAsync);
|
||||
try
|
||||
{
|
||||
var workOrderNumbersCsv = string.Join(",", workorderNumbers);
|
||||
ArgumentNullException.ThrowIfNull(workorderNumbers);
|
||||
|
||||
await using var connection = await _connectionFactory.CreateLotFinderConnectionAsync(ct);
|
||||
var result = await connection.QueryAsync<WorkOrder>(
|
||||
var workOrderNumbersCsv = string.Join(",", workorderNumbers);
|
||||
|
||||
return await ExecuteQueryAsync(
|
||||
nameof(LookupWorkordersAsync),
|
||||
"SQL_LOOKUP_WORKORDERS",
|
||||
async connection => (await connection.QueryAsync<WorkOrder>(
|
||||
LotFinderQueries.SqlLookupWorkorders,
|
||||
new { workOrderNumbers = workOrderNumbersCsv },
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds);
|
||||
return result.ToList();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAndThrow(ex, operation, "SQL_LOOKUP_WORKORDERS");
|
||||
throw;
|
||||
}
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds)).ToList(),
|
||||
ct);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<List<WorkCenter>> SearchWorkCentersAsync(string filter, CancellationToken ct = default)
|
||||
{
|
||||
const string operation = nameof(SearchWorkCentersAsync);
|
||||
try
|
||||
{
|
||||
await using var connection = await _connectionFactory.CreateLotFinderConnectionAsync(ct);
|
||||
var result = await connection.QueryAsync<WorkCenter>(
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(filter);
|
||||
|
||||
return await ExecuteQueryAsync(
|
||||
nameof(SearchWorkCentersAsync),
|
||||
"SQL_SEARCH_WORK_CENTERS",
|
||||
async connection => (await connection.QueryAsync<WorkCenter>(
|
||||
LotFinderQueries.SqlSearchWorkCenters,
|
||||
new { filter },
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds);
|
||||
return result.ToList();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAndThrow(ex, operation, "SQL_SEARCH_WORK_CENTERS");
|
||||
throw;
|
||||
}
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds)).ToList(),
|
||||
ct);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<List<ProfitCenter>> SearchProfitCentersAsync(string filter, CancellationToken ct = default)
|
||||
{
|
||||
const string operation = nameof(SearchProfitCentersAsync);
|
||||
try
|
||||
{
|
||||
await using var connection = await _connectionFactory.CreateLotFinderConnectionAsync(ct);
|
||||
var result = await connection.QueryAsync<ProfitCenter>(
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(filter);
|
||||
|
||||
return await ExecuteQueryAsync(
|
||||
nameof(SearchProfitCentersAsync),
|
||||
"SQL_SEARCH_PROFIT_CENTERS",
|
||||
async connection => (await connection.QueryAsync<ProfitCenter>(
|
||||
LotFinderQueries.SqlSearchProfitCenters,
|
||||
new { filter },
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds);
|
||||
return result.ToList();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAndThrow(ex, operation, "SQL_SEARCH_PROFIT_CENTERS");
|
||||
throw;
|
||||
}
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds)).ToList(),
|
||||
ct);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<List<JdeUser>> SearchUsersAsync(string filter, CancellationToken ct = default)
|
||||
{
|
||||
const string operation = nameof(SearchUsersAsync);
|
||||
try
|
||||
{
|
||||
await using var connection = await _connectionFactory.CreateLotFinderConnectionAsync(ct);
|
||||
var result = await connection.QueryAsync<JdeUser>(
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(filter);
|
||||
|
||||
return await ExecuteQueryAsync(
|
||||
nameof(SearchUsersAsync),
|
||||
"SQL_SEARCH_USERS",
|
||||
async connection => (await connection.QueryAsync<JdeUser>(
|
||||
LotFinderQueries.SqlSearchUsers,
|
||||
new { filter },
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds);
|
||||
return result.ToList();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAndThrow(ex, operation, "SQL_SEARCH_USERS");
|
||||
throw;
|
||||
}
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds)).ToList(),
|
||||
ct);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<List<Lot>> LookupLotsAsync(List<LotViewModel> lots, CancellationToken ct = default)
|
||||
{
|
||||
const string operation = nameof(LookupLotsAsync);
|
||||
try
|
||||
{
|
||||
var lotsJson = System.Text.Json.JsonSerializer.Serialize(
|
||||
lots.Select(l => new { l.LotNumber, l.ItemNumber }));
|
||||
ArgumentNullException.ThrowIfNull(lots);
|
||||
|
||||
await using var connection = await _connectionFactory.CreateLotFinderConnectionAsync(ct);
|
||||
var result = await connection.QueryAsync<Lot>(
|
||||
var lotsJson = System.Text.Json.JsonSerializer.Serialize(
|
||||
lots.Select(l => new { l.LotNumber, l.ItemNumber }));
|
||||
|
||||
return await ExecuteQueryAsync(
|
||||
nameof(LookupLotsAsync),
|
||||
"SQL_LOOKUP_LOTS",
|
||||
async connection => (await connection.QueryAsync<Lot>(
|
||||
LotFinderQueries.SqlLookupLots,
|
||||
new { lotsJson },
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds);
|
||||
return result.ToList();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAndThrow(ex, operation, "SQL_LOOKUP_LOTS");
|
||||
throw;
|
||||
}
|
||||
commandTimeout: _options.Value.DefaultTimeoutSeconds)).ToList(),
|
||||
ct);
|
||||
}
|
||||
}
|
||||
|
||||
+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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -66,4 +66,35 @@ public partial class LotFinderRepository : ILotFinderRepository
|
||||
// SQL Server timeout error number: -2
|
||||
return ex.Number == -2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a database query with standard error handling.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The return type of the query.</typeparam>
|
||||
/// <param name="operation">The name of the calling operation for logging.</param>
|
||||
/// <param name="queryName">The name of the query for logging.</param>
|
||||
/// <param name="queryAction">The async function that executes the query.</param>
|
||||
/// <param name="ct">Cancellation token.</param>
|
||||
/// <returns>The result of the query action.</returns>
|
||||
private async Task<T> ExecuteQueryAsync<T>(
|
||||
string operation,
|
||||
string queryName,
|
||||
Func<SqlConnection, Task<T>> queryAction,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var connection = await _connectionFactory.CreateLotFinderConnectionAsync(ct);
|
||||
return await queryAction(connection);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAndThrow(ex, operation, queryName);
|
||||
throw; // Unreachable but satisfies compiler
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ using JdeScoping.DataAccess.QueryBuilders;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using SqlKata.Compilers;
|
||||
|
||||
namespace JdeScoping.DataAccess.Services;
|
||||
|
||||
@@ -21,7 +20,7 @@ public sealed class SearchProcessor : ISearchProcessor
|
||||
private readonly IDbConnectionFactory _connectionFactory;
|
||||
private readonly ISearchQueryBuilder _queryBuilder;
|
||||
private readonly IWorkOrderTraversalService _traversalService;
|
||||
private readonly MisQueryBuilder _misQueryBuilder;
|
||||
private readonly IMisQueryBuilder _misQueryBuilder;
|
||||
private readonly SearchProcessingConfiguration _options;
|
||||
private readonly ILogger<SearchProcessor> _logger;
|
||||
|
||||
@@ -32,14 +31,14 @@ public sealed class SearchProcessor : ISearchProcessor
|
||||
IDbConnectionFactory connectionFactory,
|
||||
ISearchQueryBuilder queryBuilder,
|
||||
IWorkOrderTraversalService traversalService,
|
||||
SqlServerCompiler compiler,
|
||||
IMisQueryBuilder misQueryBuilder,
|
||||
IOptions<SearchProcessingConfiguration> options,
|
||||
ILogger<SearchProcessor> logger)
|
||||
{
|
||||
_connectionFactory = connectionFactory;
|
||||
_queryBuilder = queryBuilder;
|
||||
_traversalService = traversalService;
|
||||
_misQueryBuilder = new MisQueryBuilder(compiler);
|
||||
_misQueryBuilder = misQueryBuilder;
|
||||
_options = options.Value;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user