477 lines
20 KiB
C#
477 lines
20 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Linq;
|
|
using System.Windows;
|
|
using DTS.Common.Base;
|
|
using DTS.Common.Storage;
|
|
using DTS.Common.ISO;
|
|
using DTS.Common.DataModel;
|
|
|
|
namespace DataPROWin7.DataModel
|
|
{
|
|
/// <summary>
|
|
/// a custom channel is a wrapper for MMEPossibleChannels that are defined by the user rather than ISO13499
|
|
/// they have mirror tables to the actual db and let us define new channels without disrupting the existing 1so13499 db
|
|
/// </summary>
|
|
public class CustomChannel : BasePropertyChanged, IComparable<CustomChannel>
|
|
{
|
|
private const string defaultDefaultFilterClass = "P";
|
|
|
|
#region Properties
|
|
public MMEPossibleChannels Channel { get; private set; }
|
|
|
|
public string TypeString
|
|
{
|
|
get => Channel.Type;
|
|
set { Channel.SetType(value); OnPropertyChanged("TypeString"); }
|
|
}
|
|
|
|
private MMETestObjects _testObject;
|
|
public MMETestObjects TestObject
|
|
{
|
|
get => _testObject;
|
|
set { SetProperty(ref _testObject, value, "TestObject"); if (null != Channel && null != value) { Channel.Set_Test_Object(value.Test_Object); } }
|
|
}
|
|
|
|
private MMEPositions _position;
|
|
public MMEPositions Position
|
|
{
|
|
get => _position;
|
|
set { SetProperty(ref _position, value, "Position"); if (null != Channel && null != value) { Channel.Set_Position(value.Position); } }
|
|
}
|
|
|
|
private MMETransducerMainLocation _mainLocation;
|
|
public MMETransducerMainLocation MainLocation
|
|
{
|
|
get => _mainLocation;
|
|
set { SetProperty(ref _mainLocation, value, "MainLocation"); if (null != Channel && null != value) { Channel.Set_Main_Loc(value.Trans_Main_Loc); } }
|
|
}
|
|
|
|
private MMEFineLocations1 _finLoc1;
|
|
|
|
public MMEFineLocations1 FinLoc1
|
|
{
|
|
get => _finLoc1;
|
|
set { SetProperty(ref _finLoc1, value, "FinLoc1"); if (null != Channel && null != value) { Channel.Set_Fine_Loc_1(value.Fine_Loc_1); } }
|
|
}
|
|
|
|
private MMEFineLocations2 _finLoc2;
|
|
public MMEFineLocations2 FinLoc2
|
|
{
|
|
get => _finLoc2;
|
|
set { SetProperty(ref _finLoc2, value, "FinLoc2"); if (null != Channel && null != value) { Channel.Set_Fine_Loc_2(value.FINE_LOC_2); } }
|
|
}
|
|
|
|
private MMEFineLocations3 _finLoc3;
|
|
public MMEFineLocations3 FinLoc3
|
|
{
|
|
get => _finLoc3;
|
|
set { SetProperty(ref _finLoc3, value, "FinLoc3"); if (null != Channel && null != value) { Channel.Set_Fine_Loc_3(value.FINE_LOC_3); } }
|
|
}
|
|
|
|
private MMEPhysicalDimensions _physicalDimension;
|
|
public MMEPhysicalDimensions PhysicalDimension
|
|
{
|
|
get => _physicalDimension;
|
|
set { SetProperty(ref _physicalDimension, value, "PhysicalDimension"); if (null != Channel && null != value) { Channel.Set_Physical_Dimension(value.Physical_Dimension); } }
|
|
}
|
|
|
|
private MMEDirections _direction;
|
|
public MMEDirections Direction
|
|
{
|
|
get => _direction;
|
|
set { SetProperty(ref _direction, value, "Direction"); if (null != Channel && null != value) { Channel.Set_Direction(value.Direction); } }
|
|
}
|
|
|
|
private MMEFilterClasses _filterClass;
|
|
public MMEFilterClasses FilterClass
|
|
{
|
|
get => _filterClass;
|
|
set { SetProperty(ref _filterClass, value, "FilterClass"); if (null != Channel && null != value) { Channel.Set_Default_Filter_Class(value.Filter_Class); } }
|
|
}
|
|
#endregion Properties
|
|
|
|
public string Text1
|
|
{
|
|
get => Channel.Text_L1;
|
|
set
|
|
{
|
|
var name = value;
|
|
System.Diagnostics.Trace.Assert(name?.Length < 250, "Channel text is too long");
|
|
Channel.SetText1(name);
|
|
OnPropertyChanged("Text1");
|
|
}
|
|
}
|
|
|
|
public string Remarks
|
|
{
|
|
get => Channel.Remarks;
|
|
set
|
|
{
|
|
Channel.SetRemarks(value);
|
|
OnPropertyChanged("Remarks");
|
|
}
|
|
}
|
|
|
|
public CustomChannel()
|
|
{
|
|
Channel = new MMEPossibleChannels(-1, "", "", "", "", "", "", "", "", "", "", "", "", 0, DateTime.Now, "", false, "", "", DateTime.MinValue, "", "", (int)MMEPossibleChannels.MMEChannelTypes.SQL);
|
|
_filterClass = ApplicationProperties.IsoDb.GetFilterClassByIso("A");
|
|
}
|
|
|
|
private readonly List<ISO13499FileDb.ExpiredISOFieldException> _expiredErrors = new List<ISO13499FileDb.ExpiredISOFieldException>();
|
|
/// <summary>
|
|
/// these are any errors detected during loading of the custom channel
|
|
/// as custom channels are reliant on the ISO13499 mdb, it is possible for it to have been updated and for things to have been removed or expired
|
|
/// </summary>
|
|
public ISO13499FileDb.ExpiredISOFieldException[] ExpiredErrors => _expiredErrors.ToArray();
|
|
|
|
|
|
public CustomChannel(MMEPossibleChannels channel, bool newChannel = true)
|
|
{
|
|
Channel = newChannel ? new MMEPossibleChannels(channel) : channel;
|
|
|
|
_direction = ApplicationProperties.IsoDb.GetDirectionByIso(channel.Direction);
|
|
_filterClass = ApplicationProperties.IsoDb.GetFilterClassByIso(channel.Default_Filter_Class) ??
|
|
ApplicationProperties.IsoDb.GetFilterClassByIso(defaultDefaultFilterClass);
|
|
_finLoc1 = ApplicationProperties.IsoDb.GetFineLocation1ByIso(channel.Fine_Loc_1);
|
|
_finLoc2 = ApplicationProperties.IsoDb.GetFineLocation2ByIso(channel.Fine_Loc_2);
|
|
_finLoc3 = ApplicationProperties.IsoDb.GetFineLocation3ByIso(channel.Fine_Loc_3);
|
|
|
|
try { _mainLocation = ApplicationProperties.IsoDb.GetMainLocationByIso(channel.Trans_Main_Loc); }
|
|
catch (ISO13499FileDb.ExpiredISOFieldException ex) { _expiredErrors.Add(ex); }
|
|
|
|
_physicalDimension = ApplicationProperties.IsoDb.GetPhysicalDimensionByIso(channel.Physical_Dimension);
|
|
_position = ApplicationProperties.IsoDb.GetPositionByISO(channel.Position);
|
|
_testObject = ApplicationProperties.IsoDb.GetTestObjectByIso(channel.Test_Object);
|
|
}
|
|
public void Commit(bool bNotify)
|
|
{
|
|
if (null == Channel)
|
|
{
|
|
Channel = new MMEPossibleChannels(-1, TypeString, TestObject.Test_Object, Position.Position, MainLocation?.Trans_Main_Loc, FinLoc1.Fine_Loc_1,
|
|
FinLoc2.FINE_LOC_2, FinLoc3.FINE_LOC_3, PhysicalDimension.Physical_Dimension, Direction?.Direction, FilterClass?.Filter_Class,
|
|
Text1, Text1, 1, DateTime.Now, Remarks, false, "", "", DateTime.Now, string.Format("created in DataPRO by {0}", ApplicationProperties.CurrentUser.UserName),
|
|
"", (int)MMEPossibleChannels.MMEChannelTypes.SQL);
|
|
}
|
|
else
|
|
{
|
|
Channel = new MMEPossibleChannels(Channel.Id, TypeString, TestObject.Test_Object, Position.Position, MainLocation?.Trans_Main_Loc, FinLoc1.Fine_Loc_1,
|
|
FinLoc2.FINE_LOC_2, FinLoc3.FINE_LOC_3, PhysicalDimension.Physical_Dimension, Direction?.Direction, FilterClass?.Filter_Class,
|
|
Text1, Text1, 1, DateTime.Now, Remarks, false, "", "", DateTime.Now, string.Format("updated in DataPRO by {0}", ApplicationProperties.CurrentUser.UserName),
|
|
"", (int)MMEPossibleChannels.MMEChannelTypes.SQL);
|
|
}
|
|
|
|
ApplicationProperties.IsoDb.Commit(Channel, bNotify);
|
|
|
|
}
|
|
public MMEPossibleChannels GetISOChannelForCommit()
|
|
{
|
|
if (null == Channel)
|
|
{
|
|
Channel = new MMEPossibleChannels(-1, TypeString, TestObject.Test_Object, Position.Position, MainLocation.Trans_Main_Loc, FinLoc1.Fine_Loc_1,
|
|
FinLoc2.FINE_LOC_2, FinLoc3.FINE_LOC_3, PhysicalDimension.Physical_Dimension, Direction.Direction, FilterClass.Filter_Class,
|
|
Text1, Text1, 1, DateTime.Now, Remarks, false, "", "", DateTime.Now, string.Format("created in DataPRO by {0}", ApplicationProperties.CurrentUser.UserName),
|
|
"", (int)MMEPossibleChannels.MMEChannelTypes.SQL);
|
|
}
|
|
else
|
|
{
|
|
Channel = new MMEPossibleChannels(Channel.Id, TypeString, TestObject.Test_Object, Position.Position, MainLocation.Trans_Main_Loc, FinLoc1.Fine_Loc_1,
|
|
FinLoc2.FINE_LOC_2, FinLoc3.FINE_LOC_3, PhysicalDimension.Physical_Dimension, Direction.Direction, FilterClass.Filter_Class,
|
|
Text1, Text1, 1, DateTime.Now, Remarks, false, "", "", DateTime.Now, string.Format("updated in DataPRO by {0}", ApplicationProperties.CurrentUser.UserName),
|
|
"", (int)MMEPossibleChannels.MMEChannelTypes.SQL);
|
|
}
|
|
return Channel;
|
|
}
|
|
public int CompareTo(CustomChannel other)
|
|
{
|
|
return Equals(this, other) ? 0 : string.Compare(Text1, other.Text1, StringComparison.Ordinal);
|
|
}
|
|
|
|
public string ISOCode => TestObject.Test_Object + Position.Position + MainLocation.Trans_Main_Loc + FinLoc1.Fine_Loc_1 + FinLoc2.FINE_LOC_2 +
|
|
FinLoc3.FINE_LOC_3 + PhysicalDimension.Physical_Dimension + Direction.Direction + FilterClass.Filter_Class;
|
|
|
|
}
|
|
public class CustomChannelList : BasePropertyChanged
|
|
{
|
|
public enum Tags
|
|
{
|
|
AllChannels
|
|
}
|
|
|
|
private static readonly object LockObject = new object();
|
|
private static CustomChannelList _list;
|
|
public static CustomChannelList List
|
|
{
|
|
get
|
|
{
|
|
lock (LockObject)
|
|
{
|
|
if (null == _list)
|
|
{
|
|
_list = new CustomChannelList();
|
|
}
|
|
}
|
|
return _list;
|
|
}
|
|
}
|
|
|
|
public void ReloadAll()
|
|
{
|
|
lock (LockObject)
|
|
{
|
|
List._listChannels = null;
|
|
//var app = Application.Current as App;
|
|
//if (app == null){ return; }
|
|
ApplicationProperties.IsoDb?.RefreshAllData();
|
|
List.PopulateChannelsIfNecessary(false);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// returns true if found, for a given isocode and/or channel id
|
|
/// returns false otherwise
|
|
/// </summary>
|
|
/// <param name="isocode"></param>
|
|
/// <returns></returns>
|
|
public bool IsChannelExists(string isocode)
|
|
{
|
|
lock (LockObject)
|
|
{
|
|
PopulateChannelsIfNecessary(false);
|
|
return ApplicationProperties.IsoDb.ContainsPossibleChannelWithISOCode(isocode);
|
|
}
|
|
}
|
|
public bool IsChannelExists(string isocode, long id)
|
|
{
|
|
if (id == -1) { return IsChannelExists(isocode); }
|
|
lock (LockObject)
|
|
{
|
|
PopulateChannelsIfNecessary(false);
|
|
if (_dictChannels.ContainsKey(isocode)) { return _dictChannels[isocode].Channel.Id != id; }
|
|
//still need to check isocode isn't in regular iso channels.
|
|
return ApplicationProperties.IsoDb.ContainsPossibleChannelWithISOCode(isocode);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// returns a custom channel if found, for a given isocode
|
|
/// returns null otherwise
|
|
/// </summary>
|
|
/// <param name="isocode"></param>
|
|
/// <returns></returns>
|
|
public CustomChannel GetChannelByISOCode(string isocode, bool careAboutTestTimeFields)
|
|
{
|
|
lock (LockObject)
|
|
{
|
|
PopulateChannelsIfNecessary(careAboutTestTimeFields);
|
|
return _dictChannels.ContainsKey(isocode) ? _dictChannels[isocode] : null;
|
|
}
|
|
}
|
|
public CustomChannel GetChannelByFullISOCode(string isocode)
|
|
{
|
|
lock (LockObject)
|
|
{
|
|
PopulateChannelsIfNecessary(false);
|
|
if (_dictChannels.ContainsKey(isocode))
|
|
{
|
|
return _dictChannels[isocode];
|
|
}
|
|
var isocodeWithQuestionMarks = isocode.Substring(0, 15) + "?";
|
|
return DictChannelsContainsChannel(isocode, isocodeWithQuestionMarks) ? _dictChannels[isocodeWithQuestionMarks] : null;
|
|
}
|
|
}
|
|
private bool DictChannelsContainsChannel(string isocode, string isocodeWithQuestionMarks)
|
|
{
|
|
if (!_dictChannels.ContainsKey(isocodeWithQuestionMarks)) return false;
|
|
var temp = _dictChannels[isocodeWithQuestionMarks];
|
|
return temp.FilterClass.Filter_Class == isocode.Substring(15, 1);
|
|
}
|
|
/// <summary>
|
|
/// returns a channel given a name, this should _ONLY_ be used in
|
|
/// NON-ISO mode, as in other modes the name may not unique
|
|
/// </summary>
|
|
/// <param name="name"></param>
|
|
/// <returns></returns>
|
|
public CustomChannel GetChannelByName(string name)
|
|
{
|
|
lock (LockObject)
|
|
{
|
|
var ch = from c in AllChannels.AsParallel() where c.Channel.Text_L1 == name select c;
|
|
return ch.Any() ? ch.First() : null;
|
|
}
|
|
}
|
|
public CustomChannel GetChannel(long id)
|
|
{
|
|
lock (LockObject)
|
|
{
|
|
PopulateChannelsIfNecessary(false);
|
|
var ch = from c in AllChannels where c.Channel.Id == id select c;
|
|
|
|
var customChannels = ch as CustomChannel[] ?? ch.ToArray();
|
|
return customChannels.Any() ? customChannels[0] : null;
|
|
}
|
|
}
|
|
private CustomChannelList()
|
|
{
|
|
}
|
|
|
|
private Dictionary<string, CustomChannel> _dictChannels;
|
|
private List<CustomChannel> _listChannels;
|
|
public CustomChannel[] AllChannels
|
|
{
|
|
get
|
|
{
|
|
PopulateChannelsIfNecessary(false);
|
|
return _listChannels.ToArray();
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// loads all calculated channels, if necessary
|
|
/// </summary>
|
|
private void PopulateChannelsIfNecessary(bool careAboutTestTimeFields)
|
|
{
|
|
lock (LockObject)
|
|
{
|
|
if (null != _listChannels) return;
|
|
_listChannels = new List<CustomChannel>();
|
|
_dictChannels = new Dictionary<string, CustomChannel>();
|
|
foreach (var channel in ApplicationProperties.IsoDb.GetSQLPossibleChannels())
|
|
{
|
|
var ch = new CustomChannel(channel);
|
|
var iso = IsoCodeStatics.GetString(ch.Channel, careAboutTestTimeFields);
|
|
if (_dictChannels.ContainsKey(iso)) continue;
|
|
_listChannels.Add(ch);
|
|
_dictChannels[iso] = ch;
|
|
}
|
|
_listChannels.Sort();
|
|
}
|
|
}
|
|
|
|
public void Delete(CustomChannel[] channels)
|
|
{
|
|
lock (LockObject)
|
|
{
|
|
var idx = 0;
|
|
IDbCommand iCmd = null;
|
|
try
|
|
{
|
|
foreach (var channel in channels)
|
|
{
|
|
for (var i = _listChannels.Count - 1; i >= 0; i--)
|
|
{
|
|
if (_listChannels[i].Channel.Id == channel.Channel.Id)
|
|
{
|
|
_listChannels.RemoveAt(i);
|
|
if (null == iCmd)
|
|
{
|
|
iCmd = DbOperations.GetSQLCommand(true);
|
|
iCmd.CommandText = DbOperations.BEGIN_STATEMENT;
|
|
}
|
|
|
|
iCmd.CommandText += $"DELETE FROM [{DbOperations.MMETables.MMEPossibleChannelsTable}] WHERE [{DbOperations.MMETables.MMEPossibleChannelsFields.ID}]=@{idx}_1;";
|
|
DbOperations.CreateParam(iCmd,
|
|
$"@{idx}_1",
|
|
SqlDbType.NVarChar,
|
|
channel.Channel.Id);
|
|
idx++;
|
|
if (0 == idx % 2000)
|
|
{
|
|
iCmd.CommandText += DbOperations.COMMIT_STATEMENT;
|
|
DbOperations.Connection.ExecuteCommand(iCmd);
|
|
iCmd.Connection.Dispose();
|
|
iCmd.Dispose();
|
|
iCmd = null;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (_dictChannels.ContainsKey(channel.Text1))
|
|
{
|
|
_dictChannels.Remove(channel.ISOCode);
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
if (null != iCmd)
|
|
{
|
|
iCmd.CommandText += DbOperations.COMMIT_STATEMENT;
|
|
DbOperations.Connection.ExecuteCommand(iCmd);
|
|
iCmd.Connection.Dispose();
|
|
iCmd.Dispose();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void UpdateAll()
|
|
{
|
|
lock (LockObject)
|
|
{
|
|
_listChannels = null;
|
|
_dictChannels = null;
|
|
ApplicationProperties.IsoDb.RefreshAllData();
|
|
}
|
|
OnPropertyChanged("AllChannels");
|
|
}
|
|
/// <summary>
|
|
/// this is a custom bulk insert of channels
|
|
/// it doesn't do the validation (make sure channels don't already exist)
|
|
/// and the clean the ordinary commit does (get the new id #)
|
|
/// so ... it's good for bulk, but make sure to call updateall so the ids are updated
|
|
/// </summary>
|
|
/// <param name="channels"></param>
|
|
public void Commit(CustomChannel[] channels)
|
|
{
|
|
MMEPossibleChannels.Commit(channels.Select(ch => ch.GetISOChannelForCommit()).ToArray());
|
|
}
|
|
public void Commit(CustomChannel channel) { Commit(channel, true, true); }
|
|
public void Commit(CustomChannel channel, bool bDoLookForExistingNameCheck, bool bNotify)
|
|
{
|
|
PopulateChannelsIfNecessary(false);
|
|
var bFound = false;
|
|
//don't consider the test fields when getting isocode (filter, position, test object)
|
|
var key = IsoCodeStatics.GetString(channel.Channel, false);
|
|
if (bDoLookForExistingNameCheck)
|
|
{
|
|
if (_dictChannels.ContainsKey(key))
|
|
{
|
|
bFound = true;
|
|
channel.Channel.SetId(_dictChannels[key].Channel.Id);
|
|
}
|
|
}
|
|
if (bFound && !bNotify)
|
|
{
|
|
//bypass the ordinary commit as it will attempt to do an insert
|
|
//and we just want to do an update.
|
|
//I'm abusing the bNotify flag above to limit the scope of my changes as I know it's
|
|
//false in batch updates where we aren't updating the list with every commit which is where the problem exists.
|
|
//see http://fogbugz/fogbugz/default.asp?6713 2016-03-14
|
|
channel.Channel.Commit();
|
|
}
|
|
else { channel.Commit(bNotify); }
|
|
|
|
if (bNotify)
|
|
{
|
|
lock (LockObject)
|
|
{
|
|
_listChannels = null;
|
|
_dictChannels = null;
|
|
}
|
|
OnPropertyChanged("AllChannels");
|
|
}
|
|
else
|
|
{
|
|
if (!bFound)
|
|
{
|
|
lock (LockObject)
|
|
{
|
|
_listChannels.Add(channel);
|
|
_dictChannels[key] = channel;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|