Files

370 lines
16 KiB
C#
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
namespace DatabaseImport.ISO
{
/// <summary>
/// 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
/// </summary>
public class TestObjectTemplate
{
/// <summary>
/// name of the test object template, this could be a GUID in the case of embedded test object templates
/// </summary>
public string TemplateName { get; set; }
/// <summary>
/// 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)
/// </summary>
public string TemplateNameOrOriginalTemplateName => Embedded ? OriginalTemplateName : TemplateName;
/// <summary>
/// the icon for the template
/// </summary>
public string Icon { get; set; }
/// <summary>
/// description for the template
/// </summary>
public string Description { get; set; }
/// <summary>
/// whether this template is intended to only be used locally or not
/// </summary>
public bool LocalOnly { get; set; }
/// <summary>
/// the version number of this template [not currently used?]
/// </summary>
public int Version { get; set; }
/// <summary>
/// last person to modify this template
/// </summary>
public string LastModifiedBy { get; set; }
/// <summary>
/// when this template was last modified
/// </summary>
public DateTime LastModified { get; set; }
/// <summary>
/// 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
/// </summary>
public int CRC32 { get; set; }
/// <summary>
/// test object (iso meta field) for this template
/// </summary>
public string TestObject { get; set; }
/// <summary>
/// test object type (iso meta field) for this template, all channels are of this type ...
/// </summary>
public string TestObjectType { get; set; }
/// <summary>
/// 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
/// </summary>
public string TemplateParent { get; set; }
/// <summary>
/// unsure, I think this is whether the group is dynamically added or an existing
/// </summary>
public bool SysBuilt { get; set; }
/// <summary>
/// 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
/// </summary>
public TemplateZone[] Zones { get; set; }
/// <summary>
/// all channels for the template
/// </summary>
public TestObjectTemplateChannel[] Channels { get; set; }
/// <summary>
/// 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]
/// </summary>
public string OriginalTemplateName { get; set; }
/// <summary>
/// whether this group is embedded in a test setup, or is a user created and living on it's own template
/// </summary>
public bool Embedded { get; set; }
public TestObjectTemplate(DataRow row, ref ISO13499FileDb db, ref List<string> 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<TestObjectTemplateChannel>();
var possibleChannels = db.GetPossibleChannelsForType(TestObjectType);
var channelLookup = new Dictionary<int, Dictionary<long, TestObjectTemplateChannel>>();
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<long, TestObjectTemplateChannel>());
}
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<TemplateZone>();
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<string, bool>();
var channels = new List<TestObjectTemplateChannel>();
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<TestObjectTemplateChannel> LoadExistingChannels(ref ISO13499FileDb db)
{
var existingChannels = new List<TestObjectTemplateChannel>();
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<string>();
var templates = new List<TestObjectTemplate>();
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; }
}
}
}