using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; namespace DatabaseImport.ISO { /// /// this class is a wrapper for the group template per the db, it's supposed to be a lighter weight version of concept of a test object template, with no /// connection to UI, just serialization and structure /// public class TestObjectTemplate { /// /// name of the test object template, this could be a GUID in the case of embedded test object templates /// public string TemplateName { get; set; } /// /// a human readable name for the template, for an embedded template this is the original template name, for /// a non embedded template, this is the template name (embedded templates have guids for names) /// public string TemplateNameOrOriginalTemplateName => Embedded ? OriginalTemplateName : TemplateName; /// /// the icon for the template /// public string Icon { get; set; } /// /// description for the template /// public string Description { get; set; } /// /// whether this template is intended to only be used locally or not /// public bool LocalOnly { get; set; } /// /// the version number of this template [not currently used?] /// public int Version { get; set; } /// /// last person to modify this template /// public string LastModifiedBy { get; set; } /// /// when this template was last modified /// public DateTime LastModified { get; set; } /// /// a CRC32 for the template, but not currently used /// original idea was to allow us to not have to check changes in the template, just quickly calculate whether anything has changed /// public int CRC32 { get; set; } /// /// test object (iso meta field) for this template /// public string TestObject { get; set; } /// /// test object type (iso meta field) for this template, all channels are of this type ... /// public string TestObjectType { get; set; } /// /// unsure if this is still used, was originally used to build up templates from sub templates, /// so an ATD could be composed of leg, arm, head, etc /// public string TemplateParent { get; set; } /// /// unsure, I think this is whether the group is dynamically added or an existing /// public bool SysBuilt { get; set; } /// /// zones where regions on a test object, this is currently hidden, but the idea /// was to associate a picture with a zone, and to allow constructing regions or areas in that zone /// public TemplateZone[] Zones { get; set; } /// /// all channels for the template /// public TestObjectTemplateChannel[] Channels { get; set; } /// /// the original template name [if we are embedded we got a new name that was a guid, but we store the old name here for readability purposes] /// public string OriginalTemplateName { get; set; } /// /// whether this group is embedded in a test setup, or is a user created and living on it's own template /// public bool Embedded { get; set; } public TestObjectTemplate(DataRow row, ref ISO13499FileDb db, ref List errors) { TemplateName = (string)row["TemplateName"]; Icon = (string)row["Icon"]; Description = (string)row["Description"]; LocalOnly = Convert.ToBoolean(row["LocalOnly"]); Version = Convert.ToInt32(row["Version"]); LastModifiedBy = (string)row["LastModifiedBy"]; LastModified = Convert.ToDateTime(row["LastModified"]); CRC32 = Convert.ToInt32(row["CRC32"]); TestObject = (string)row["TestObjectName"]; TestObjectType = (string)row["TestObjectType"]; var oTemplate = row["OrigTemplateName"]; OriginalTemplateName = DBNull.Value.Equals(oTemplate) ? string.Empty : Convert.ToString(oTemplate); var oEmbedded = row["Embedded"]; if (!DBNull.Value.Equals(oEmbedded)) { Embedded = Convert.ToBoolean(oEmbedded); } try { TemplateParent = DBNull.Value.Equals(row["ParentTemplate"]) ? "" : (string)row["ParentTemplate"]; } catch (Exception) { TemplateParent = null; } SysBuilt = Convert.ToBoolean(row["SysBuilt"]); var channels = new List(); var possibleChannels = db.GetPossibleChannelsForType(TestObjectType); var channelLookup = new Dictionary>(); foreach (var pc in possibleChannels) { try { var newCh = new TestObjectTemplateChannel(pc); newCh.SetTemplate(this); channels.Add(newCh); if (!channelLookup.ContainsKey(newCh.Channel.MMEChannelType)) { channelLookup.Add(newCh.Channel.MMEChannelType, new Dictionary()); } channelLookup[newCh.Channel.MMEChannelType][newCh.Channel.Id] = newCh; } catch (Exception) { /*APILogger.Log(ex);*/ } } var failedToLoadChannels = 0; try { var channelList = LoadExistingChannels(ref db); foreach (var ch in channelList) { try { if (!ch.Required) continue; if (null == ch.Channel) { failedToLoadChannels++; continue; } var old = channelLookup[ch.Channel.MMEChannelType][ch.Channel.Id]; channelLookup[ch.Channel.MMEChannelType][ch.Channel.Id] = ch; var index = channels.IndexOf(old); channels.RemoveAt(index); channels.Insert(index, ch); } catch (Exception) { //APILogger.Log("Failed to retrieve Template channel", ex); if (null != ch) { errors.Add("Failed to load " + ch.Name + " from template " + TemplateName); } else { errors.Add("Failed to load a channel in " + TemplateName); } } } } catch (Exception) { errors.Add("Failed to load channels for - " + TemplateName); //APILogger.Log("failed to retrieve template channels, ", TemplateName, ex); } Channels = channels.ToArray(); if (failedToLoadChannels > 0) { errors.Add($"Failed to load {failedToLoadChannels:N0} channel(s) from template {TemplateNameOrOriginalTemplateName}"); } var zones = new List(); try { using (var cmd = DbOperations.GetSQLCommand(true)) { try { cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = DbOperationsEnum.StoredProcedure.sp_TemplateZonesGet.ToString(); cmd.Parameters.Add( new SqlParameter("@TemplateName", SqlDbType.NVarChar) { Value = TemplateName }); using (var ds = DbOperations.Connection.QueryDataSet(cmd)) { if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) { zones.Add(new TemplateZone(ds.Tables[0].Rows[0])); //zones.AddRange(from DataRow dr in ds.Tables[0].Rows select new TemplateZone(dr)); } } } finally { cmd.Connection.Dispose(); } } } catch (Exception) { /*APILogger.Log("failed to retrieve template regions, ", TemplateName, ex); */} Zones = zones.ToArray(); } public TestObjectTemplate(string templateName, bool bLocalOnly) { Version = 1; TemplateName = templateName; LocalOnly = bLocalOnly; Zones = new TemplateZone[0]; Channels = new TestObjectTemplateChannel[0]; } public TestObjectTemplate(TestObjectTemplate copy, ref ISO13499FileDb db) { if (copy?.TemplateName != null) { TemplateName = copy.TemplateName; } if (copy == null) return; LocalOnly = copy.LocalOnly; Zones = copy.Zones; CRC32 = copy.CRC32; Description = copy.Description; Embedded = copy.Embedded; OriginalTemplateName = copy.OriginalTemplateName; Icon = copy.Icon; LastModified = copy.LastModified; LastModifiedBy = copy.LastModifiedBy; LocalOnly = copy.LocalOnly; SysBuilt = copy.SysBuilt; TemplateParent = copy.TemplateParent; TestObject = copy.TestObject; TestObjectType = copy.TestObjectType; Version = copy.Version; var lookup = new Dictionary(); var channels = new List(); foreach (var c in copy.Channels) { var ch = new TestObjectTemplateChannel(c, this); ch.SetTemplate(this); channels.Add(ch); lookup[$"{c.Channel.Id}x{c.Channel.MMEChannelType}"] = true; } var possibleChannels = db.GetPossibleChannelsForType(TestObjectType); foreach (var pc in possibleChannels) { var key = $"{pc.Id}x{pc.MMEChannelType}"; if (lookup.ContainsKey(key)) continue; lookup[key] = true; var ch = new TestObjectTemplateChannel(pc); ch.SetTemplate(this); channels.Insert(0, ch); } Channels = channels.ToArray(); } private List LoadExistingChannels(ref ISO13499FileDb db) { var existingChannels = new List(); using (var cmd = DbOperations.GetSQLCommand(true)) { try { cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = DbOperationsEnum.StoredProcedure.sp_TemplateChannelsGet.ToString(); #region params cmd.Parameters.Add( new SqlParameter("@TemplateName", SqlDbType.NVarChar, 50) { Value = TemplateName }); #endregion params using (var ds = DbOperations.Connection.QueryDataSet(cmd)) { if (ds.Tables.Count <= 0 || ds.Tables[0].Rows.Count <= 0) return existingChannels; foreach (DataRow dr in ds.Tables[0].Rows) { existingChannels.Add(new TestObjectTemplateChannel(dr, this, ref db)); } } } finally { cmd.Connection.Dispose(); } } return existingChannels; } public static TestObjectTemplate GetTemplate(ref ISO13499FileDb db, string name) { if (string.IsNullOrEmpty(name)) return null; var errors = new List(); var templates = new List(); try { using (var cmd = DbOperations.GetSQLCommand(true)) { try { cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = DbOperationsEnum.StoredProcedure.sp_TestObjectTemplatesGet.ToString(); cmd.Parameters.Add(new SqlParameter("@TemplateName", SqlDbType.NVarChar) { Value = name }); cmd.Parameters.Add(new SqlParameter("@SysBuilt", SqlDbType.NVarChar) { Value = null }); //cmd.ExecuteNonQuery(); using (var ds = DbOperations.Connection.QueryDataSet(cmd)) { if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) { //foreach (DataRow row in ds.Tables[0].Rows) if (ds.Tables[0].Rows.Count > 0) { try { templates.Add(new TestObjectTemplate(ds.Tables[0].Rows[0], ref db, ref errors)); } catch (Exception) { //APILogger.Log("Failed to retrieve template", ex2); } } } } } finally { cmd.Connection.Dispose(); } } } catch (Exception) { /*APILogger.Log("failed to get all templates", ex);*/ } return templates.Count > 0 ? templates[0] : null; } public static void DeleteAllTemplates(string templateName = null) { try { using (var cmd = DbOperations.GetSQLCommand(true)) { try { cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = DbOperationsEnum.StoredProcedure.sp_TestObjectTemplatesDelete.ToString(); cmd.Parameters.Add(new SqlParameter("@TemplateName", SqlDbType.NVarChar) { Value = String.IsNullOrEmpty(templateName) ? null : templateName }); var errorNumberParam = new SqlParameter("@errorNumber", SqlDbType.Int) { Direction = ParameterDirection.Output }; cmd.Parameters.Add(errorNumberParam); var errorMessageParam = new SqlParameter("@errorMessage", SqlDbType.NVarChar, 250) { Direction = ParameterDirection.Output }; cmd.Parameters.Add(errorMessageParam); cmd.ExecuteNonQuery(); } finally { cmd.Connection.Dispose(); } } } catch (Exception) { /*APILogger.Log("Failed to delete template:", templateName, ex);*/ throw; } } } }