using System; using System.Configuration; using System.Data; using System.Data.SqlClient; using System.IO; using Dapper; using DataModel.Helpers; using DataModel.Models; using DataModel.Process; using WorkerService.Helpers; using WorkerService.Models.Reporting; namespace WorkerService.Process { /// /// Worker service-specific functionality for LotFinderDB interface /// public class LotFinderDBExt : LotFinderDB { /// /// Query to get next queued search /// private const string SQL_GET_NEXT_SEARCH = @" SELECT TOP 1 s.ID, s.UserName, s.Name, s.Status, s.SubmitDT, s.StartDT, s.EndDT, s.Criteria AS CriteriaJSON FROM dbo.Search s WHERE s.Status = 1 ORDER BY s.SubmitDT"; /// /// Gets next queued search /// /// Next queue search public static Search GetNextSearch() { Search nextSearch = null; try { using (SqlConnection connection = GetConnection()) { nextSearch = connection.QueryFirstOrDefault(SQL_GET_NEXT_SEARCH); if (nextSearch != null && !string.IsNullOrEmpty(nextSearch.CriteriaJSON)) { nextSearch.Criteria = JsonHelpers.FromJSON(nextSearch.CriteriaJSON); } } } catch (Exception error) { //Log but do not forward error logger.Error("GetNextSearch: failed to get next queued search: {0}.", error.Message); } return nextSearch; } /// /// Resets the status of partially completed searches /// public static void ResetPartialSearches() { try { using (SqlConnection connection = GetConnection()) { connection.Execute("ResetPartialSearches", commandType: CommandType.StoredProcedure); } } catch (Exception error) { //Log but do not forward error logger.Error("ResetPartialSearches: failed to reset partial searches: {0}.", error.Message); } } /// /// Updates the status of the search to 'Start' /// /// Search to start public static void StartSearch(Search search) { try { search.Status = SearchStatus.Started; search.StartDT = DateTime.Now; using (SqlConnection connection = GetConnection()) { connection.Execute("StartSearch", new { p_SearchID = search.ID }, commandType: CommandType.StoredProcedure); } } catch (Exception error) { //Log but do not forward error logger.Error("StartSearch: failed to mark search as started: {0}.", error.Message); } } /// /// Update the status of the search to 'Complete' and stores the results /// /// Search to complete /// Whether or not the search was successful public static void CompleteSearch(Search search, bool wasSuccessful) { try { search.Status = wasSuccessful ? SearchStatus.Ended : SearchStatus.Error; using (SqlConnection connection = GetConnection()) { connection.Execute("CompleteSearch", new { p_SearchID = search.ID, p_WasSuccessful = wasSuccessful, p_Results = search.Results }, commandType: CommandType.StoredProcedure); } } catch (Exception error) { //Log but do not forward error logger.Error("CompleteSearch: failed to mark search as completed: {0}.", error.Message); } } /// /// Performs search and extracts results into given model /// /// Search parameter & result model public static void Search(SearchModel searchModel) { try { //Get configured timeout int queryTimeout = 600; try { string queryTimeoutStr = ConfigurationManager.AppSettings["querytimeout"]; queryTimeout = int.Parse(queryTimeoutStr); } catch { //Ignore } //Generate query to execute string query = searchModel.GetQuery(); File.WriteAllText($"search_{searchModel.ID}.sql", query); searchModel.StartDT = DateTime.Now; using (SqlConnection connection = GetConnection()) { var results = connection.QueryMultiple(query, new { p_MinimumDT = searchModel.MinimumDT, p_MaximumDT = searchModel.MaximumDT, p_WorkOrderFilter = searchModel.CreateWorkOrderFilterParameter(), p_ItemNumberFilter = searchModel.CreateItemNumberFilterParameter(), p_ProfitCenterFilter = searchModel.CreateProfitCenterFilterParameter(), p_WorkCenterFilter = searchModel.CreateWorkCenterFilterParameter(), p_ComponentLotFilter = searchModel.CreateComponentLotFilterParameter(), p_OperatorFilter = searchModel.CreateOperatorFilterParameter(), p_ItemOperationMisFilter = searchModel.CreateItemOperationMisFilterParameter(), p_ExtractMisData = searchModel.ExtractMisData }, commandTimeout: queryTimeout); //Parse search results searchModel.Results.AddRange(results.Read()); //Parse MIS data if extracted if (searchModel.ExtractMisData) { searchModel.MisResults.AddRange(results.Read()); searchModel.MisNonMatchResults.AddRange(results.Read()); } } searchModel.EndDT = DateTime.Now; } catch (Exception error) { //Log but do not forward error logger.Error("Search: failed to perform search: {0}.", error.Message); throw; } } } }