using OI.Metrology.Shared.DataModels; using OI.Metrology.Shared.Models.Stateless; using OI.Metrology.Shared.Repositories; using System.Data; using System.Data.Common; using System.Text; using System.Text.Json; using System.Text.RegularExpressions; namespace OI.Metrology.Server.Repository; public class WorkMaterialRepository : IWorkMaterialRepository { private readonly string _MockRoot; private readonly string _RepositoryName; private readonly IDbConnectionFactory _DBConnectionFactory; public WorkMaterialRepository(string mockRoot, IDbConnectionFactory dbConnectionFactory) { _MockRoot = mockRoot; _DBConnectionFactory = dbConnectionFactory; _RepositoryName = nameof(WorkMaterialRepository)[..^10]; } string IWorkMaterialRepository.GetCommandText(int? workOrderNumber, int? workOrderStep, int? workOrderCassette) { StringBuilder result = new(); _ = result.Append("select ( "). Append(" select wi.rds_no, "). Append(" rr.reactor, "). Append(" wi.pocket_no, "). Append(" wi.zone, "). Append(" wi.in_cass_no, "). Append(" wi.slot_no [in_slot_no], "). Append(" isnull(wo.out_cass_no, -1) [out_cass_no], "). Append(" isnull(wo.slot_no, -1) [out_slot_no], "). Append(" rr.ps_no, "). Append(" rr.recipe_name, "). Append(" rr.recipe_no, "). Append(" rr.spec_type "). Append(" from lsl2sql.dbo.wm_in_slot_no wi "). Append(" inner join lsl2sql.dbo.react_run rr "). Append(" on wi.wo_no = rr.wo_no "). Append(" and wi.rds_no = rr.rds_no "). Append(" left join lsl2sql.dbo.wm_out_slot wo "). Append(" on wo.wo_no = wi.wo_no "). Append(" and wo.rds = wi.rds_no "). Append(" and wo.in_cass_no = wi.in_cass_no "). Append(" and wo.in_slot_no = wi.slot_no "). Append(" where wi.wo_no = ").Append(workOrderNumber is null ? -1 : workOrderNumber.Value).Append(' '). Append(" and wi.rds_no = wm.rds "). Append(" order by wi.in_cass_no, wi.slot_no "). Append(" for json path "). Append(" ) [group] "). Append("from lsl2sql.dbo.wm_out_slot wm "). Append("where wm.wo_no = ").Append(workOrderNumber is null ? -1 : workOrderNumber.Value).Append(' '). Append(" and wm.proc_step_no = ").Append(workOrderStep is null ? -1 : workOrderStep.Value).Append(' '). Append(" and wm.out_cass_no = ").Append(workOrderCassette is null ? -1 : workOrderCassette.Value).Append(' '). Append("group by wm.rds "). Append("order by wm.rds "). Append("for json path "); return result.ToString(); } private static StringBuilder GetForJsonPath(IDbConnectionFactory dbConnectionFactory, string commandText) { StringBuilder stringBuilder = new(); using DbConnection dbConnection = dbConnectionFactory.GetDbConnection(useOI2Sql: true); DbCommand dbCommand = dbConnection.CreateCommand(); dbCommand.CommandText = commandText; DbDataReader dbDataReader = dbCommand.ExecuteReader(CommandBehavior.SequentialAccess); while (dbDataReader.Read()) _ = stringBuilder.Append(dbDataReader.GetString(0)); return stringBuilder; } private static (int?, int?, int?, bool) GetWorkOrder(string mid) { int? workOrderStep = null; int? workOrderNumber = null; MatchCollection[] collection; int? workOrderCassette = null; if (string.IsNullOrEmpty(mid)) collection = Array.Empty(); else { string pattern = @"^([oiOI])?([0-9]{6,7})\.([0-5]{1})\.([0-9]{1,2})$"; // o171308.1.51 collection = (from l in mid.Split('-') select Regex.Matches(l, pattern)).ToArray(); } foreach (MatchCollection matchCollection in collection) { if (matchCollection.Count == 0) continue; if (!matchCollection[0].Success || matchCollection[0].Groups.Count != 5) continue; if (!int.TryParse(matchCollection[0].Groups[3].Value, out int workOrderStepValue)) continue; if (!int.TryParse(matchCollection[0].Groups[2].Value, out int workOrderNumberValue)) continue; if (!int.TryParse(matchCollection[0].Groups[4].Value, out int workOrderCassetteValue)) continue; workOrderStep = workOrderStepValue; workOrderNumber = workOrderNumberValue; workOrderCassette = workOrderCassetteValue; break; } return new(workOrderNumber, workOrderStep, workOrderCassette, workOrderStep is not null || workOrderNumber is not null || workOrderCassette is not null); } Result IWorkMaterialRepository.GetCassette(string mid) { Result? result; if (!string.IsNullOrEmpty(_MockRoot)) { string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IWorkMaterialRepository.GetCassette)}.json")); result = JsonSerializer.Deserialize>(json); if (result is null) throw new NullReferenceException(nameof(result)); } else { WorkMaterialV2[] results; (int? workOrderNumber, int? workOrderStep, int? workOrderCassette, bool isWorkOrder) = GetWorkOrder(mid); if (!isWorkOrder) results = Array.Empty(); else { WorkMaterial[]? group; JsonProperty[] jsonProperties; List collection = new(); IWorkMaterialRepository workMaterialRepository = this; string commandText = workMaterialRepository.GetCommandText(workOrderNumber, workOrderStep, workOrderCassette); StringBuilder stringBuilder = GetForJsonPath(_DBConnectionFactory, commandText); JsonElement[]? jsonElements = JsonSerializer.Deserialize(stringBuilder.ToString()); if (jsonElements is null) throw new NullReferenceException(nameof(jsonElements)); foreach (JsonElement jsonElement in jsonElements) { if (jsonElement.ValueKind != JsonValueKind.Object) continue; jsonProperties = jsonElement.EnumerateObject().ToArray(); if (!jsonProperties.Any()) continue; group = JsonSerializer.Deserialize(jsonProperties.First().Value.ToString(), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); if (group is null) continue; foreach (WorkMaterial workMaterial in group) collection.Add(workMaterial); } if (collection is null) throw new NullReferenceException(nameof(collection)); results = WorkMaterial.Convert(collection); } result = new() { Results = results, TotalRows = results.Length, }; } return result; } }