//******************************************************************************************************
// OutputStreamDeviceDigital.cs - Gbtc
//
// Copyright © 2010, Grid Protection Alliance. All Rights Reserved.
//
// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
// the NOTICE file distributed with this work for additional information regarding copyright ownership.
// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
// not use this file except in compliance with the License. You may obtain a copy of the License at:
//
// http://www.opensource.org/licenses/MIT
//
// Unless agreed to in writing, the subject software distributed under the License is distributed on an
// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
// License for the specific language governing permissions and limitations.
//
// Code Modification History:
// ----------------------------------------------------------------------------------------------------
// 08/10/2011 - Aniket Salver
// Generated original version of source code.
// 09/19/2011 - Mehulbhai P Thakkar
// Added OnPropertyChanged() on all properties to reflect changes on UI.
// Fixed Load() and GetLookupList() static methods.
// 06/27/2012- Vijay Sukhavasi
// Modified Delete() to delete measurements associated with digital
// 08/15/2012 - Aniket Salver
// Added paging and sorting technique.
//
//******************************************************************************************************
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows;
using GSF.Data;
using GSF.TimeSeries.UI;
namespace GSF.PhasorProtocols.UI.DataModels
{
///
/// Represents a record of information as defined in the database.
///
public class OutputStreamDeviceDigital : DataModelBase
{
#region [ Members ]
private Guid m_nodeID;
private int m_outputStreamDeviceID;
private int m_id;
private string m_label;
private int m_maskValue;
private int m_loadOrder;
private DateTime m_createdOn;
private string m_createdBy;
private DateTime m_updatedOn;
private string m_updatedBy;
#endregion
#region [ Properties ]
///
/// Gets or sets NodeID.
///
[Required(ErrorMessage = "OutputStreamDeviceDigital NodeID is a required field, please provide value.")]
public Guid NodeID
{
get
{
return m_nodeID;
}
set
{
m_nodeID = value;
OnPropertyChanged("NodeID");
}
}
///
/// Gets or sets OutputStreamDeviceID.
///
[Required(ErrorMessage = "OutputStreamDeviceDigital OutputStreamDeviceID is a required field, please provide value.")]
public int OutputStreamDeviceID
{
get
{
return m_outputStreamDeviceID;
}
set
{
m_outputStreamDeviceID = value;
OnPropertyChanged("OutputStreamDeviceID");
}
}
///
/// Gets or sets ID.
///
// Field is populated by database via auto-increment and has no screen interaction, so no validation attributes are applied
[Required(ErrorMessage = "OutputStreamDeviceDigital ID is a required field, please provide value.")]
public int ID
{
get
{
return m_id;
}
set
{
m_id = value;
OnPropertyChanged("ID");
}
}
///
/// Gets or sets Label.
///
[Required(ErrorMessage = "OutputStreamDeviceDigital Label is a required field, please provide value.")]
public string Label
{
get
{
return m_label;
}
set
{
m_label = value.TruncateRight(256).PadRight(256);
OnPropertyChanged("Label");
}
}
///
/// Gets or sets Display Label.
///
public string DisplayLabel
{
get
{
return string.Concat(Label.GetSegments(16).Select(label => label.Trim() + "\r\n").Take(16));
}
set
{
Label = string.Concat(value.Split(new[] { "\r\n" }, StringSplitOptions.None).Select(label => label.TruncateRight(16).PadRight(16)).Take(16));
OnPropertyChanged("DisplayLabel");
}
}
///
/// Gets or sets MaskValue.
///
[Required(ErrorMessage = "OutputStreamDeviceDigital MaskValue is a required field, please provide value.")]
public int MaskValue
{
get
{
return m_maskValue;
}
set
{
m_maskValue = value;
OnPropertyChanged("MaskValue");
}
}
///
/// Gets or sets LoadOrder.
///
[Required(ErrorMessage = "OutputStreamDeviceDigital LoadOrder is a required field, please provide value.")]
[DefaultValue(0)]
public int LoadOrder
{
get
{
return m_loadOrder;
}
set
{
m_loadOrder = value;
OnPropertyChanged("LoadOrder");
}
}
///
/// Gets or sets when the current was created.
///
// Field is populated by trigger and has no screen interaction, so no validation attributes are applied
public DateTime CreatedOn
{
get
{
return m_createdOn;
}
set
{
m_createdOn = value;
}
}
///
/// Gets or sets who the current was created by.
///
// Field is populated by trigger and has no screen interaction, so no validation attributes are applied
public string CreatedBy
{
get
{
return m_createdBy;
}
set
{
m_createdBy = value;
}
}
///
/// Gets or sets when the current was updated.
///
// Field is populated by trigger and has no screen interaction, so no validation attributes are applied
public DateTime UpdatedOn
{
get
{
return m_updatedOn;
}
set
{
m_updatedOn = value;
}
}
///
/// Gets or sets who the current was updated by.
///
// Field is populated by trigger and has no screen interaction, so no validation attributes are applied
public string UpdatedBy
{
get
{
return m_updatedBy;
}
set
{
m_updatedBy = value;
}
}
#endregion
#region [ Static ]
// Static Methods
///
/// LoadKeys information as an style list.
///
/// to connection to database.
/// ID of the output stream device to filter data.
/// The field to sort by.
/// ASC or DESC for ascending or descending respectively.
/// Collection of .
public static IList LoadKeys(AdoDataConnection database, int outputStreamDeviceID, string sortMember, string sortDirection)
{
bool createdConnection = false;
try
{
createdConnection = CreateConnection(ref database);
IList outputStreamDeviceDigitalList = new List();
DataTable outputStreamDeviceDigitalTable;
string sortClause = string.Empty;
if (!string.IsNullOrEmpty(sortMember))
sortClause = string.Format("ORDER BY {0} {1}", sortMember, sortDirection);
outputStreamDeviceDigitalTable = database.Connection.RetrieveData(database.AdapterType, string.Format("SELECT ID From OutputStreamDeviceDigital WHERE OutputStreamDeviceID = {0} {1}", outputStreamDeviceID, sortClause));
foreach (DataRow row in outputStreamDeviceDigitalTable.Rows)
{
outputStreamDeviceDigitalList.Add(row.ConvertField("ID"));
}
return outputStreamDeviceDigitalList;
}
finally
{
if (createdConnection && database != null)
database.Dispose();
}
}
///
/// Loads information as an style list.
///
/// to connection to database.
/// Keys of the measurement to be loaded from the database
/// Collection of .
public static ObservableCollection Load(AdoDataConnection database, IList keys)
{
bool createdConnection = false;
try
{
createdConnection = CreateConnection(ref database);
string query;
string commaSeparatedKeys;
OutputStreamDeviceDigital[] outputStreamDeviceDigitalList = null;
DataTable outputStreamDeviceDigitalTable;
int id;
if ((object)keys != null && keys.Count > 0)
{
commaSeparatedKeys = keys.Select(key => "" + key.ToString() + "").Aggregate((str1, str2) => str1 + "," + str2);
query = database.ParameterizedQueryString(string.Format("SELECT NodeID, OutputStreamDeviceID, ID, Label, MaskValue, LoadOrder " +
"FROM OutputStreamDeviceDigital WHERE ID IN ({0})", commaSeparatedKeys));
outputStreamDeviceDigitalTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout);
outputStreamDeviceDigitalList = new OutputStreamDeviceDigital[outputStreamDeviceDigitalTable.Rows.Count];
foreach (DataRow row in outputStreamDeviceDigitalTable.Rows)
{
id = row.ConvertField("ID");
outputStreamDeviceDigitalList[keys.IndexOf(id)] = new OutputStreamDeviceDigital()
{
NodeID = database.Guid(row, "NodeID"),
OutputStreamDeviceID = row.ConvertField("OutputStreamDeviceID"),
ID = id,
Label = row.Field("Label"),
MaskValue = row.ConvertField("MaskValue"),
LoadOrder = row.ConvertField("LoadOrder")
};
}
}
return new ObservableCollection(outputStreamDeviceDigitalList ?? new OutputStreamDeviceDigital[0]);
}
finally
{
if (createdConnection && database != null)
database.Dispose();
}
}
///
/// Gets a style list of information.
///
/// to connection to database.
/// ID of the output stream device to filter data.
/// Indicates if selection on UI is optional for this collection.
/// containing ID and Label of OutputStreamDeviceDigitals defined in the database.
public static Dictionary GetLookupList(AdoDataConnection database, int outputStreamDeviceID, bool isOptional = false)
{
bool createdConnection = false;
try
{
createdConnection = CreateConnection(ref database);
Dictionary OutputStreamDeviceDigitalList = new();
if (isOptional)
OutputStreamDeviceDigitalList.Add(0, "Select OutputStreamDeviceDigital");
string query = database.ParameterizedQueryString("SELECT ID, Label FROM OutputStreamDeviceDigital " +
"WHERE OutputStreamDeviceID = {0} ORDER BY LoadOrder", "outputStreamDeviceID");
DataTable OutputStreamDeviceDigitalTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, outputStreamDeviceID);
foreach (DataRow row in OutputStreamDeviceDigitalTable.Rows)
OutputStreamDeviceDigitalList[row.ConvertField("ID")] = row.Field("Label");
return OutputStreamDeviceDigitalList;
}
finally
{
if (createdConnection && database != null)
database.Dispose();
}
}
///
/// Saves information to database.
///
/// to connection to database.
/// Information about .
/// String, for display use, indicating success.
public static string Save(AdoDataConnection database, OutputStreamDeviceDigital outputStreamDeviceDigital)
{
bool createdConnection = false;
string query;
try
{
createdConnection = CreateConnection(ref database);
if (outputStreamDeviceDigital.ID == 0)
{
query = database.ParameterizedQueryString("INSERT INTO OutputStreamDeviceDigital (NodeID, OutputStreamDeviceID, Label, MaskValue, LoadOrder, " +
"UpdatedBy, UpdatedOn, CreatedBy, CreatedOn) VALUES ({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8})", "nodeID", "outputStreamDeviceID", "label",
"maskValue", "loadOrder", "updatedBy", "updatedOn", "createdBy", "createdOn");
database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.CurrentNodeID(), outputStreamDeviceDigital.OutputStreamDeviceID,
outputStreamDeviceDigital.Label, outputStreamDeviceDigital.MaskValue, outputStreamDeviceDigital.LoadOrder, CommonFunctions.CurrentUser,
database.UtcNow, CommonFunctions.CurrentUser, database.UtcNow);
}
else
{
query = database.ParameterizedQueryString("UPDATE OutputStreamDeviceDigital SET NodeID = {0}, OutputStreamDeviceID = {1}, Label = {2}, MaskValue = {3}, " +
"LoadOrder = {4}, UpdatedBy = {5}, UpdatedOn = {6} WHERE ID = {7}", "nodeID", "outputStreamDeviceID", "label", "maskValue", "loadOrder", "updatedBy",
"updatedOn", "id");
database.Connection.ExecuteNonQuery(query, DefaultTimeout, outputStreamDeviceDigital.NodeID, outputStreamDeviceDigital.OutputStreamDeviceID,
outputStreamDeviceDigital.Label, outputStreamDeviceDigital.MaskValue, outputStreamDeviceDigital.LoadOrder, CommonFunctions.CurrentUser,
database.UtcNow, outputStreamDeviceDigital.ID);
}
return "OutputStreamDeviceDigital information saved successfully";
}
finally
{
if (createdConnection && database != null)
database.Dispose();
}
}
///
/// Deletes specified record from database.
///
/// to connection to database.
/// ID of the record to be deleted.
/// String, for display use, indicating success.
public static string Delete(AdoDataConnection database, int outputStreamDeviceDigitalID)
{
bool createdConnection = false;
int adapterID;
int outputStreamDeviceID;
int deletedSignalReferenceIndex;
int presentDeviceDigitalCount;
string digitalSignalReference;
string signalReferenceBase;
string previousDigitalSignalReference;
string nextDigitalSignalReference = string.Empty;
string lastAffectedMeasurementMessage = string.Empty;
try
{
createdConnection = CreateConnection(ref database);
// Setup current user context for any delete triggers
CommonFunctions.SetCurrentUserContext(database);
GetDeleteMeasurementDetails(database, outputStreamDeviceDigitalID, out digitalSignalReference, out adapterID, out outputStreamDeviceID);
database.Connection.ExecuteNonQuery(database.ParameterizedQueryString("DELETE FROM OutputStreamMeasurement WHERE SignalReference = {0} AND AdapterID = {1}", "signalReference", "adapterID"), DefaultTimeout, digitalSignalReference, adapterID);
presentDeviceDigitalCount = Convert.ToInt32(database.Connection.ExecuteScalar(database.ParameterizedQueryString("SELECT COUNT(*) FROM OutputStreamDeviceDigital WHERE OutputStreamDeviceID = {0}", "outputStreamDeviceID"), DefaultTimeout, outputStreamDeviceID));
// Using signal reference of measurement deleted build the next signal reference (increment by 1)\
int.TryParse(Regex.Match(digitalSignalReference, @"\d+$").Value, out deletedSignalReferenceIndex);
signalReferenceBase = Regex.Replace(digitalSignalReference, @"\d+$", "");
for (int i = deletedSignalReferenceIndex; i < presentDeviceDigitalCount; i++)
{
// We will be modifying the measurement with signal reference index i+1 to have signal reference index i.
previousDigitalSignalReference = string.Format("{0}{1}", signalReferenceBase, i);
nextDigitalSignalReference = string.Format("{0}{1}", signalReferenceBase, i + 1);
// Obtain details of measurements of the deleted measurements, then modify the signal reference (decrement by 1) and put it back
OutputStreamMeasurement outputStreamMeasurement = GetOutputMeasurementDetails(database, nextDigitalSignalReference, adapterID);
outputStreamMeasurement.SignalReference = previousDigitalSignalReference;
OutputStreamMeasurement.Save(database, outputStreamMeasurement);
}
database.Connection.ExecuteNonQuery(database.ParameterizedQueryString("DELETE FROM OutputStreamDeviceDigital WHERE ID = {0}", "outputStreamDeviceDigitalID"), DefaultTimeout, outputStreamDeviceDigitalID);
return "OutputStreamDeviceDigital and its Measurements deleted successfully";
}
catch (Exception ex)
{
if (!string.IsNullOrEmpty(nextDigitalSignalReference))
lastAffectedMeasurementMessage = string.Format("{0}(Last affected measurement: {1})", Environment.NewLine, nextDigitalSignalReference);
CommonFunctions.LogException(database, "OutputStreamDeviceDigital.Delete", ex);
MessageBoxResult dialogResult = MessageBox.Show(string.Format("Could not delete or modify measurements.{0}Do you still wish to delete this Digital?{1}", Environment.NewLine, lastAffectedMeasurementMessage), "", MessageBoxButton.YesNo);
if (dialogResult == MessageBoxResult.Yes)
{
database.Connection.ExecuteNonQuery(database.ParameterizedQueryString("DELETE FROM OutputStreamDeviceDigital WHERE ID = {0}", "outputStreamDeviceDigitalID"), DefaultTimeout, outputStreamDeviceDigitalID);
return "OutputStreamDeviceDigital deleted successfully but failed to modify all measurements ";
}
else
{
Exception exception = ex.InnerException ?? ex;
return string.Format("Delete OutputStreamDeviceDigital was unsuccessful: {0}", exception.Message);
}
}
finally
{
if (createdConnection && database != null)
database.Dispose();
}
}
private static OutputStreamMeasurement GetOutputMeasurementDetails(AdoDataConnection database, string signalReference, int adapterID)
{
bool createdConnection = false;
try
{
createdConnection = CreateConnection(ref database);
string query = database.ParameterizedQueryString("SELECT * FROM OutputStreamMeasurement WHERE SignalReference = {0} AND AdapterID = {1}", "signalReference", "adapterID");
DataRow row = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, signalReference, adapterID).Rows[0];
OutputStreamMeasurement outputStreamMeasurement = new()
{
NodeID = row.ConvertField("NodeID"),
AdapterID = row.Field("AdapterID"),
ID = row.Field("ID"),
HistorianID = row.Field("HistorianID"),
PointID = row.Field("PointID"),
SignalReference = row.ConvertField("SignalReference"),
CreatedOn = row.ConvertField("CreatedOn"),
CreatedBy = row.Field("CreatedBy"),
UpdatedOn = row.ConvertField("UpdatedOn"),
UpdatedBy = row.Field("UpdatedBy")
};
return outputStreamMeasurement;
}
catch (Exception ex)
{
CommonFunctions.LogException(database, "OutputStreamDeviceDigital.GetOutputMeasurementDetails", ex);
throw;
}
finally
{
if (createdConnection && database != null)
database.Dispose();
}
}
private static void GetDeleteMeasurementDetails(AdoDataConnection database, int outputStreamDeviceDigitalID, out string digitalSignalReference, out int adapterID, out int outputStreamDeviceID)
{
const string outputDigitalFormat = "SELECT Label, OutputStreamDeviceID FROM OutputStreamDeviceDigital ID = {0}";
const string outputDeviceFormat = "SELECT Acronym, AdapterID FROM OutputStreamDevice WHERE ID = {0}";
const string measurementDetailFormat = "SELECT PointTag FROM MeasurementDetail WHERE DeviceAcronym = '{0}' AND AlternateTag = '{1}' AND SignalTypeSuffix = 'DV'";
const string outputMeasurementDetailFormat = "SELECT SignalReference FROM OutputStreamMeasurementDetail WHERE SourcePointTag = '{0}'";
bool createdConnection = false;
try
{
DataRow outputDigitalRecord;
DataRow outputDeviceRecord;
string labelName;
string deviceName;
string digitalPointTag;
createdConnection = CreateConnection(ref database);
outputDigitalRecord = database.Connection.RetrieveData(database.AdapterType, string.Format(outputDigitalFormat, outputStreamDeviceDigitalID)).Rows[0];
labelName = outputDigitalRecord.Field("Label");
outputStreamDeviceID = outputDigitalRecord.Field("OutputStreamDeviceID");
outputDeviceRecord = database.Connection.RetrieveData(database.AdapterType, string.Format(outputDeviceFormat, outputStreamDeviceID)).Rows[0];
deviceName = outputDeviceRecord.Field("Acronym");
adapterID = outputDeviceRecord.ConvertField("AdapterID");
digitalPointTag = database.Connection.ExecuteScalar(string.Format(measurementDetailFormat, deviceName, labelName)).ToNonNullString();
digitalSignalReference = database.Connection.ExecuteScalar(string.Format(outputMeasurementDetailFormat, digitalPointTag)).ToNonNullString();
}
catch (Exception ex)
{
CommonFunctions.LogException(database, "OutputStreamDeviceDigital.GetDeleteMeasurementDetails", ex);
throw;
}
finally
{
if (createdConnection && database != null)
database.Dispose();
}
}
#endregion
}
}