1689 lines
68 KiB
C#
1689 lines
68 KiB
C#
//
|
|
// Class: DBManager
|
|
// Current CLR: 4.0.30319.34209
|
|
// System: Microsoft Visual Studio 10.0
|
|
// Author: dani
|
|
// Created: 3/10/2015 7:25:55 AM
|
|
//
|
|
// Copyright (c) 2015 Informatikbüro Daniel Schick. All rights reserved.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Data.SqlClient;
|
|
using System.Diagnostics;
|
|
using Newtonsoft.Json;
|
|
using log4net;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading.Tasks;
|
|
using System.Threading;
|
|
|
|
namespace bsmd.database
|
|
{
|
|
public class DBManager
|
|
{
|
|
|
|
#region Fields
|
|
|
|
private SqlConnection _con;
|
|
private static DBManager _instance;
|
|
private static readonly ILog _log = LogManager.GetLogger(typeof(DBManager));
|
|
private static Dictionary<Guid, ReportingParty> allReportingParties;
|
|
private static Dictionary<string, PortArea> allPortAreas;
|
|
private readonly object _lock = new object();
|
|
private bool _closeConnectionAfterUse = false;
|
|
private readonly List<string> truncatedFieldCollection = new List<string>();
|
|
private Dictionary<Type, string> messageHistoryTypeDict;
|
|
|
|
#endregion
|
|
|
|
#region Enums
|
|
|
|
public enum MessageLoad
|
|
{
|
|
ALL,
|
|
EXCEL,
|
|
HE,
|
|
ENI
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Construction
|
|
|
|
public DBManager()
|
|
{
|
|
this.InitializeMessageHistoryTypes();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
public static DBManager Instance
|
|
{
|
|
get
|
|
{
|
|
return _instance ?? (_instance = new DBManager());
|
|
}
|
|
}
|
|
|
|
public static DBManager GetSingleCon(string dbConnectionString)
|
|
{
|
|
DBManager aDBManager = new DBManager();
|
|
if (aDBManager.Connect(dbConnectionString))
|
|
{
|
|
aDBManager._closeConnectionAfterUse = true;
|
|
return aDBManager;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public string ConnectionString { get; set; }
|
|
|
|
#endregion
|
|
|
|
#region public DB funcs
|
|
|
|
public bool Connect(string dbConnectionString)
|
|
{
|
|
try
|
|
{
|
|
_con = new SqlConnection(dbConnectionString);
|
|
_con.Open();
|
|
this.ConnectionString = dbConnectionString;
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_log.ErrorFormat("DBManager cannot connect:{0}", ex.Message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public async Task<bool> ConnectAsync(string dbConnectionString)
|
|
{
|
|
try
|
|
{
|
|
_con = new SqlConnection(dbConnectionString);
|
|
await _con.OpenAsync();
|
|
this.ConnectionString = dbConnectionString;
|
|
return true;
|
|
}
|
|
catch(Exception ex)
|
|
{
|
|
_log.ErrorFormat("DBManager cannot connect:{0}", ex.Message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public void Disconnect()
|
|
{
|
|
if (this._con?.State == ConnectionState.Open)
|
|
this._con.Close();
|
|
}
|
|
|
|
public bool IsConnected
|
|
{
|
|
get { return this._con?.State == ConnectionState.Open; }
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
#region public helper funcs
|
|
|
|
public List<MessageCore> GetMessageCoresForExcelCreate()
|
|
{
|
|
MessageCore aMessageCore = new MessageCore();
|
|
SqlCommand cmd = new SqlCommand();
|
|
aMessageCore.PrepareLoadCommand(cmd, Message.LoadFilter.CREATE_EXCEL);
|
|
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> cores = aMessageCore.LoadList(reader);
|
|
List<MessageCore> result = new List<MessageCore>();
|
|
foreach (MessageCore core in cores)
|
|
{
|
|
this.LoadCustomer(core);
|
|
result.Add(core);
|
|
}
|
|
|
|
if (this._closeConnectionAfterUse) this.Disconnect();
|
|
|
|
return result;
|
|
}
|
|
|
|
public List<MessageCore> GetMessageCoresByStatus(MessageCore.BSMDStatus status)
|
|
{
|
|
MessageCore aMessageCore = new MessageCore();
|
|
SqlCommand cmd = new SqlCommand();
|
|
aMessageCore.PrepareLoadCommand(cmd, Message.LoadFilter.BSMDSTATUS, status);
|
|
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> cores = aMessageCore.LoadList(reader);
|
|
List<MessageCore> result = new List<MessageCore>();
|
|
foreach (MessageCore core in cores)
|
|
{
|
|
this.LoadCustomer(core);
|
|
result.Add(core);
|
|
}
|
|
|
|
if (this._closeConnectionAfterUse) this.Disconnect();
|
|
|
|
return result;
|
|
}
|
|
|
|
public List<MessageCore> GetMessageCoresByReportStatus(MessageCore.ReportStatusEnum reportStatus)
|
|
{
|
|
MessageCore aMessageCore = new MessageCore();
|
|
SqlCommand cmd = new SqlCommand();
|
|
aMessageCore.PrepareLoadCommand(cmd, Message.LoadFilter.REPORTSTATUS, reportStatus);
|
|
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> cores = aMessageCore.LoadList(reader);
|
|
List<MessageCore> result = new List<MessageCore>();
|
|
foreach (MessageCore core in cores)
|
|
{
|
|
|
|
this.LoadCustomer(core);
|
|
this.LoadETA_ETD(core);
|
|
this.LoadSTATShipName(core);
|
|
|
|
result.Add(core);
|
|
}
|
|
|
|
if (this._closeConnectionAfterUse) this.Disconnect();
|
|
|
|
return result;
|
|
}
|
|
|
|
internal List<ImportHeader> GetImportHeader(Guid messageCoreId)
|
|
{
|
|
ImportHeader ih = new ImportHeader();
|
|
SqlCommand cmd = new SqlCommand();
|
|
ih.PrepareLoadCommand(cmd, Message.LoadFilter.BY_CORE, messageCoreId);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<ImportHeader> result = new List<ImportHeader>();
|
|
foreach (ImportHeader existingHeader in ih.LoadList(reader))
|
|
result.Add(existingHeader);
|
|
|
|
if (this._closeConnectionAfterUse) this.Disconnect();
|
|
|
|
return result;
|
|
}
|
|
|
|
internal List<ImportValue> GetValuesForImportHeader(ImportHeader importHeader)
|
|
{
|
|
ImportValue iv = new ImportValue();
|
|
SqlCommand cmd = new SqlCommand();
|
|
iv.PrepareLoadCommand(cmd, Message.LoadFilter.IMPORTHEADER_ID, importHeader.Id.Value);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<ImportValue> result = new List<ImportValue>();
|
|
foreach (ImportValue existingValue in iv.LoadList(reader))
|
|
result.Add(existingValue);
|
|
|
|
if (this._closeConnectionAfterUse) this.Disconnect();
|
|
|
|
return result;
|
|
}
|
|
|
|
public List<MessageCore> GetMessageCoresWithNSWStatusFlag()
|
|
{
|
|
List<MessageCore> result = new List<MessageCore>();
|
|
MessageCore aMessageCore = new MessageCore();
|
|
SqlCommand cmd = new SqlCommand();
|
|
aMessageCore.PrepareLoadCommand(cmd, Message.LoadFilter.QUERY_NSW_STATUS);
|
|
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
if (reader != null)
|
|
{
|
|
List<DatabaseEntity> cores = aMessageCore.LoadList(reader);
|
|
|
|
foreach (MessageCore core in cores)
|
|
{
|
|
this.LoadCustomer(core);
|
|
result.Add(core);
|
|
}
|
|
|
|
if (this._closeConnectionAfterUse) this.Disconnect();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public List<MessageCore> GetMessageCoresOlderThan(int months)
|
|
{
|
|
List<MessageCore> result = new List<MessageCore>();
|
|
MessageCore aMessageCore = new MessageCore();
|
|
SqlCommand cmd = new SqlCommand();
|
|
aMessageCore.PrepareLoadCommand(cmd, Message.LoadFilter.BY_AGE, months);
|
|
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
if (reader != null)
|
|
{
|
|
foreach (MessageCore core in aMessageCore.LoadList(reader))
|
|
result.Add(core);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public int? GetNumCoresWithFilters(Dictionary<MessageCore.SearchFilterType, string> filters)
|
|
{
|
|
MessageCore aMessageCore = new MessageCore();
|
|
SqlCommand cmd = new SqlCommand();
|
|
aMessageCore.PrepareCountCmd(cmd, Message.LoadFilter.SEARCH_CORE_FILTERS, filters);
|
|
|
|
int? result = this.PerformReadIntQuery(cmd);
|
|
|
|
if (this._closeConnectionAfterUse) this.Disconnect();
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
public List<MessageCore> GetMessageCoresWithFilters(Dictionary<MessageCore.SearchFilterType, string> filters, int? limit = null)
|
|
{
|
|
MessageCore aMessageCore = new MessageCore();
|
|
SqlCommand cmd = new SqlCommand();
|
|
if (limit > 0)
|
|
aMessageCore.ResultLimit = limit;
|
|
aMessageCore.PrepareLoadCommand(cmd, Message.LoadFilter.SEARCH_CORE_FILTERS, filters);
|
|
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> cores = aMessageCore.LoadList(reader);
|
|
List<MessageCore> result = new List<MessageCore>();
|
|
foreach (MessageCore core in cores)
|
|
{
|
|
this.LoadCustomer(core);
|
|
this.LoadSTATShipName(core);
|
|
this.LoadETA_ETD(core);
|
|
this.LoadATA(core);
|
|
this.LoadATD(core);
|
|
this.LoadNumberSent(core);
|
|
result.Add(core);
|
|
}
|
|
|
|
|
|
if (this._closeConnectionAfterUse) this.Disconnect();
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lädt MessageCore (=Schiffsanlauf) einer EU-NOAD Nachricht vom Fleettracker / Herberg
|
|
/// </summary>
|
|
/// <param name="herbergFormGuid"></param>
|
|
/// <returns></returns>
|
|
public MessageCore GetHerbergFormMessage(Guid herbergFormGuid)
|
|
{
|
|
MessageCore result = null;
|
|
MessageCore aMessageCore = new MessageCore();
|
|
SqlCommand cmd = new SqlCommand();
|
|
aMessageCore.PrepareLoadCommand(cmd, Message.LoadFilter.HERBERG_FORMGUID, herbergFormGuid);
|
|
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> cores = aMessageCore.LoadList(reader);
|
|
if (cores.Count > 1) _log.WarnFormat("Herberg form message: {0} cores found for guid {1}",
|
|
cores.Count, herbergFormGuid);
|
|
if (cores.Count > 0)
|
|
{
|
|
result = (MessageCore)cores[0];
|
|
this.LoadCustomer(result);
|
|
}
|
|
|
|
if (this._closeConnectionAfterUse) this.Disconnect();
|
|
|
|
return result;
|
|
}
|
|
|
|
public List<Message> GetMessagesForCore(MessageCore core, MessageLoad loadType)
|
|
{
|
|
Message aMessage = new Message();
|
|
SqlCommand cmd = new SqlCommand();
|
|
|
|
Message.LoadFilter loadFilter = Message.LoadFilter.BY_CORE;
|
|
switch(loadType)
|
|
{
|
|
case MessageLoad.ENI: loadFilter = Message.LoadFilter.BY_CORE_ENI; break;
|
|
case MessageLoad.EXCEL: loadFilter = Message.LoadFilter.BY_CORE_EXCEL; break;
|
|
case MessageLoad.HE: loadFilter = Message.LoadFilter.BY_CORE_HE; break;
|
|
|
|
}
|
|
|
|
aMessage.PrepareLoadCommand(cmd, loadFilter, core.Id);
|
|
IDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> messages = aMessage.LoadList(reader);
|
|
|
|
List<Message> messageList = new List<Message>();
|
|
foreach (Message message in messages)
|
|
{
|
|
message.MessageCore = core;
|
|
messageList.Add(message);
|
|
}
|
|
this.LoadMessageDependencies(messageList);
|
|
|
|
if (this._closeConnectionAfterUse) this.Disconnect();
|
|
|
|
return messageList;
|
|
}
|
|
|
|
public Message GetMessage(MessageCore core, Message.NotificationClass notificationClass)
|
|
{
|
|
Message aMessage = new Message();
|
|
SqlCommand cmd = new SqlCommand();
|
|
aMessage.PrepareLoadCommand(cmd, Message.LoadFilter.BY_CORE_AND_CLASS, core.Id, notificationClass);
|
|
IDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> messages = aMessage.LoadList(reader);
|
|
|
|
Message result = null;
|
|
if(!messages.IsNullOrEmpty())
|
|
{
|
|
result = (Message) messages[0]; // es kann nur eine sein
|
|
result.MessageCore = core;
|
|
List<Message> lm = new List<Message> { result };
|
|
this.LoadMessageDependencies(lm);
|
|
}
|
|
|
|
if (this._closeConnectionAfterUse) this.Disconnect();
|
|
return result;
|
|
}
|
|
|
|
|
|
public string GetShipNameFromCore(MessageCore core)
|
|
{
|
|
|
|
Message statMessage = this.GetMessage(core, Message.NotificationClass.STAT);
|
|
|
|
if (statMessage?.Elements.Count > 0)
|
|
{
|
|
if (statMessage.Elements[0] is STAT stat)
|
|
return stat.ShipName;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public Dictionary<Guid, ReportingParty> GetReportingPartyDict()
|
|
{
|
|
if (DBManager.allReportingParties == null)
|
|
{
|
|
ReportingParty aRep = new ReportingParty();
|
|
SqlCommand cmd = new SqlCommand();
|
|
aRep.PrepareLoadCommand(cmd, Message.LoadFilter.ALL);
|
|
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> reportingParties = aRep.LoadList(reader);
|
|
DBManager.allReportingParties = new Dictionary<Guid, ReportingParty>();
|
|
foreach (ReportingParty rp in reportingParties)
|
|
DBManager.allReportingParties.Add(rp.Id.Value, rp);
|
|
}
|
|
return DBManager.allReportingParties;
|
|
}
|
|
|
|
public List<ValidationRule> GetValidationRules()
|
|
{
|
|
ValidationRule vr = new ValidationRule();
|
|
SqlCommand cmd = new SqlCommand();
|
|
vr.PrepareLoadCommand(cmd, Message.LoadFilter.ALL);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> allRules = vr.LoadList(reader);
|
|
List<ValidationRule> result = new List<ValidationRule>();
|
|
foreach (ValidationRule aVR in allRules)
|
|
result.Add(aVR);
|
|
return result;
|
|
}
|
|
|
|
public Dictionary<string, PortArea> GetPortAreaDict()
|
|
{
|
|
if(DBManager.allPortAreas == null)
|
|
{
|
|
PortArea pa = new PortArea();
|
|
SqlCommand cmd = new SqlCommand();
|
|
pa.PrepareLoadCommand(cmd, Message.LoadFilter.ALL);
|
|
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> portAreas = pa.LoadList(reader);
|
|
DBManager.allPortAreas = new Dictionary<string, PortArea>();
|
|
foreach (PortArea aPa in portAreas)
|
|
DBManager.allPortAreas[aPa.Code] = aPa; // TODO da gibt es doppelte Einträge
|
|
}
|
|
return DBManager.allPortAreas;
|
|
}
|
|
|
|
public DatabaseEntity GetMessageById(Guid id)
|
|
{
|
|
Message aMessage = new Message();
|
|
SqlCommand cmd = new SqlCommand();
|
|
const Message.LoadFilter filter = Message.LoadFilter.BY_ID;
|
|
aMessage.PrepareLoadCommand(cmd, filter, id);
|
|
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> messages = aMessage.LoadList(reader);
|
|
|
|
List<Message> messageList = new List<Message>();
|
|
foreach (Message message in messages)
|
|
messageList.Add(message);
|
|
|
|
if (messageList.Count == 0) return null;
|
|
|
|
this.LoadMessageDependencies(messageList);
|
|
if(messageList[0].MessageCoreId.HasValue)
|
|
messageList[0].MessageCore = this.GetMessageCoreById(messageList[0].MessageCoreId.Value);
|
|
|
|
return messageList[0];
|
|
}
|
|
|
|
public Message GetMessageByFileSeqNum(int fileSeqNum)
|
|
{
|
|
Message aMessage = new Message();
|
|
SqlCommand cmd = new SqlCommand();
|
|
const Message.LoadFilter filter = Message.LoadFilter.BY_FILE_SEQ_NUM;
|
|
aMessage.PrepareLoadCommand(cmd, filter, fileSeqNum);
|
|
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> messages = aMessage.LoadList(reader);
|
|
|
|
List<Message> messageList = new List<Message>();
|
|
foreach (Message message in messages)
|
|
messageList.Add(message);
|
|
|
|
if (messageList.Count == 0) return null;
|
|
|
|
this.LoadMessageDependencies(messageList);
|
|
if (messageList[0].MessageCoreId.HasValue)
|
|
messageList[0].MessageCore = this.GetMessageCoreById(messageList[0].MessageCoreId.Value);
|
|
|
|
return messageList[0];
|
|
}
|
|
|
|
public MessageCore GetMessageCoreById(Guid id)
|
|
{
|
|
MessageCore aCore = new MessageCore();
|
|
SqlCommand cmd = new SqlCommand();
|
|
const Message.LoadFilter filter = Message.LoadFilter.BY_ID;
|
|
aCore.PrepareLoadCommand(cmd, filter, id);
|
|
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> cores = aCore.LoadList(reader);
|
|
|
|
MessageCore result = null;
|
|
if (cores.Count > 0)
|
|
{
|
|
result = cores[0] as MessageCore;
|
|
if (result.CustomerId.HasValue)
|
|
{
|
|
Customer c = new Customer();
|
|
SqlCommand cCmd = new SqlCommand();
|
|
c.PrepareLoadCommand(cCmd, Message.LoadFilter.BY_ID, result.CustomerId.Value);
|
|
reader = this.PerformCommand(cCmd);
|
|
List<DatabaseEntity> customers = c.LoadList(reader);
|
|
if (customers.Count > 0)
|
|
result.Customer = customers[0] as Customer;
|
|
}
|
|
this.LoadSTATShipName(result);
|
|
}
|
|
|
|
if (this._closeConnectionAfterUse) this.Disconnect();
|
|
|
|
return result;
|
|
}
|
|
|
|
public MessageCore GetMessageCoreByVisitId(string visitId)
|
|
{
|
|
MessageCore aCore = new MessageCore();
|
|
SqlCommand cmd = new SqlCommand();
|
|
const Message.LoadFilter filter = Message.LoadFilter.BY_VISITID;
|
|
aCore.PrepareLoadCommand(cmd, filter, visitId);
|
|
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> cores = aCore.LoadList(reader);
|
|
|
|
MessageCore result = null;
|
|
if (cores.Count > 0)
|
|
{
|
|
if (cores.Count > 1) _log.WarnFormat("more than one core in DB for VISIT ID {0}", visitId);
|
|
result = cores[0] as MessageCore;
|
|
if (result.CustomerId.HasValue)
|
|
{
|
|
Customer c = new Customer();
|
|
SqlCommand cCmd = new SqlCommand();
|
|
c.PrepareLoadCommand(cCmd, Message.LoadFilter.BY_ID, result.CustomerId.Value);
|
|
reader = this.PerformCommand(cCmd);
|
|
List<DatabaseEntity> customers = c.LoadList(reader);
|
|
if (customers.Count > 0)
|
|
result.Customer = customers[0] as Customer;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public MessageCore GetMessageCoreByTransitId(string transitId)
|
|
{
|
|
MessageCore aCore = new MessageCore();
|
|
SqlCommand cmd = new SqlCommand();
|
|
const Message.LoadFilter filter = Message.LoadFilter.BY_TRANSITID;
|
|
aCore.PrepareLoadCommand(cmd, filter, transitId);
|
|
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> cores = aCore.LoadList(reader);
|
|
|
|
MessageCore result = null;
|
|
if (cores.Count > 0)
|
|
{
|
|
if (cores.Count > 1) _log.WarnFormat("more than one core in DB for TRANSIT ID {0}", transitId);
|
|
result = cores[0] as MessageCore;
|
|
if (result.CustomerId.HasValue)
|
|
{
|
|
Customer c = new Customer();
|
|
SqlCommand cCmd = new SqlCommand();
|
|
c.PrepareLoadCommand(cCmd, Message.LoadFilter.BY_ID, result.CustomerId.Value);
|
|
reader = this.PerformCommand(cCmd);
|
|
List<DatabaseEntity> customers = c.LoadList(reader);
|
|
if (customers.Count > 0)
|
|
result.Customer = customers[0] as Customer;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public MessageCore GetMessageCoreByShipInfos(string imo, DateTime eta, string poc)
|
|
{
|
|
MessageCore aCore = new MessageCore();
|
|
SqlCommand cmd = new SqlCommand();
|
|
const Message.LoadFilter filter = Message.LoadFilter.IMO_ETA_POC;
|
|
aCore.PrepareLoadCommand(cmd, filter, imo, eta, poc);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> cores = aCore.LoadList(reader);
|
|
|
|
MessageCore result = null;
|
|
if (cores.Count > 0)
|
|
{
|
|
if (cores.Count > 1)
|
|
_log.WarnFormat("Multiple ({3}) cores found for IMO {0}, ETA {1}, PoC {2}",
|
|
imo, eta, poc, cores.Count);
|
|
result = cores[0] as MessageCore;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public void DeleteCore(MessageCore messageCore)
|
|
{
|
|
if(messageCore == null) return;
|
|
|
|
List<Message> coreMessages = this.GetMessagesForCore(messageCore, MessageLoad.ALL);
|
|
|
|
foreach (Message message in coreMessages)
|
|
{
|
|
if (message is ISublistContainer sublistContainer)
|
|
{
|
|
(sublistContainer).DeleteElements();
|
|
}
|
|
this.Delete(message);
|
|
}
|
|
|
|
this.Delete(messageCore);
|
|
}
|
|
|
|
public void Save(DatabaseEntity entity)
|
|
{
|
|
List<string> truncatedFields = new List<string>();
|
|
List<string> fieldNames = new List<string>();
|
|
entity.TruncateFields(truncatedFields, fieldNames);
|
|
|
|
foreach(string truncatedField in truncatedFields)
|
|
{
|
|
_log.WarnFormat("Entity {0} save: Field truncated: {1}", entity.GetType(), truncatedField);
|
|
}
|
|
|
|
this.truncatedFieldCollection.AddRange(fieldNames);
|
|
|
|
SqlCommand cmd = new SqlCommand();
|
|
entity.PrepareSave(cmd);
|
|
int queryResult = this.PerformNonQuery(cmd);
|
|
this.LogNonQueryResult(cmd.CommandText, queryResult);
|
|
this.CreateEntityHistoryEntry(entity);
|
|
|
|
if (this._closeConnectionAfterUse) this.Disconnect();
|
|
}
|
|
|
|
public void Delete(DatabaseEntity entity)
|
|
{
|
|
if (!entity.IsNew)
|
|
{
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
entity.PrepareDelete(cmd);
|
|
int queryResult = this.PerformNonQuery(cmd);
|
|
this.LogNonQueryResult(cmd.CommandText, queryResult);
|
|
}
|
|
}
|
|
if (this._closeConnectionAfterUse) this.Disconnect();
|
|
}
|
|
|
|
public void DeleteMessageErrors(Message message)
|
|
{
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
cmd.CommandText = string.Format("UPDATE Error SET Deleted = 1 WHERE MessageHeaderId='{0}'", message.Id);
|
|
int queryResult = this.PerformNonQuery(cmd);
|
|
this.LogNonQueryResult(cmd.CommandText, queryResult);
|
|
}
|
|
}
|
|
|
|
public void DeleteMessageViolations(Message message)
|
|
{
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
cmd.CommandText = string.Format("UPDATE Violation SET Deleted = 1 WHERE MessageHeaderId='{0}'", message.Id);
|
|
int queryResult = this.PerformNonQuery(cmd);
|
|
this.LogNonQueryResult(cmd.CommandText, queryResult);
|
|
}
|
|
}
|
|
|
|
public void DeleteSystemErrors(Message message)
|
|
{
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
cmd.CommandText = string.Format("UPDATE SystemError SET Deleted = 1 WHERE MessageHeaderId='{0}'", message.Id);
|
|
int queryResult = this.PerformNonQuery(cmd);
|
|
this.LogNonQueryResult(cmd.CommandText, queryResult);
|
|
}
|
|
}
|
|
|
|
public void Save(MessageCore core)
|
|
{
|
|
if (core.Customer != null)
|
|
{
|
|
using (SqlCommand cCmd = new SqlCommand())
|
|
{
|
|
core.Customer.PrepareSave(cCmd);
|
|
_log.DebugFormat("Saved Customer to Core: {0}", this.PerformNonQuery(cCmd));
|
|
core.CustomerId = core.Customer.Id;
|
|
}
|
|
}
|
|
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
core.PrepareSave(cmd);
|
|
int queryResult = this.PerformNonQuery(cmd);
|
|
this.LogNonQueryResult(cmd.CommandText, queryResult);
|
|
}
|
|
|
|
if (this._closeConnectionAfterUse) this.Disconnect();
|
|
}
|
|
|
|
public bool? GetMessageCoreQueryStatusFlag(Guid messageCoreId)
|
|
{
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
cmd.CommandText = string.Format("SELECT QueryNSWStatus FROM MessageCore WHERE Id = '{0}'", messageCoreId);
|
|
bool? result = this.PerformReadFlagQuery(cmd);
|
|
|
|
if (this._closeConnectionAfterUse) this.Disconnect();
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
public List<MessageHistory> GetMessageHistories(Guid messageId)
|
|
{
|
|
try
|
|
{
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
cmd.CommandText = MessageHistory.GetLoadCommand();
|
|
cmd.Parameters.AddWithValue("@ENTITYID", messageId);
|
|
IDataReader reader = this.PerformCommand(cmd);
|
|
List<MessageHistory> result = MessageHistory.LoadList(reader);
|
|
reader.Close();
|
|
return result;
|
|
}
|
|
}
|
|
catch(Exception ex)
|
|
{
|
|
_log.ErrorFormat("Error loadin message history: {0}", ex.Message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public List<AGNT_Template> GetAGNTTemplates()
|
|
{
|
|
List<AGNT_Template> result = new List<AGNT_Template>();
|
|
try
|
|
{
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
AGNT_Template agnt_template = new AGNT_Template();
|
|
agnt_template.PrepareLoadCommand(cmd, Message.LoadFilter.ALL);
|
|
IDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> a_list = agnt_template.LoadList(reader);
|
|
foreach (AGNT_Template aTemplate in a_list)
|
|
result.Add(aTemplate);
|
|
reader.Close();
|
|
}
|
|
}
|
|
catch(Exception ex)
|
|
{
|
|
_log.ErrorFormat("Error loading AGNT templates: {0}", ex.Message);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public void DeleteAllPASForMessage(Guid? id)
|
|
{
|
|
if (!id.HasValue) return;
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
cmd.CommandText = "DELETE FROM PAS WHERE MessageHeaderId = @MESSAGEHEADERID";
|
|
cmd.Parameters.AddWithValue("@MESSAGEHEADERID", id);
|
|
int numDel = this.PerformNonQuery(cmd);
|
|
_log.InfoFormat("Deleted all elements ({0}) from PAS message", numDel);
|
|
}
|
|
}
|
|
|
|
public int? GetMessageFileMaxNum()
|
|
{
|
|
int? result = 0;
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
cmd.CommandText = "SELECT MAX(FileNumSequence) FROM MessageHeader";
|
|
result = this.PerformReadIntQuery(cmd);
|
|
if (result == null) result = 0;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region internal/private funcs
|
|
|
|
private void CheckConnection()
|
|
{
|
|
if ((this._con == null) ||
|
|
(this._con.State == ConnectionState.Closed))
|
|
this.Connect(this.ConnectionString);
|
|
}
|
|
|
|
private void LogNonQueryResult(string query, int queryResult)
|
|
{
|
|
switch (queryResult)
|
|
{
|
|
case 0:
|
|
_log.DebugFormat("Query {0} affected no rows", query); break;
|
|
case -1:
|
|
_log.DebugFormat("Query {0} error occurred", query); break;
|
|
default:
|
|
_log.DebugFormat("Query {0} affected {1} rows", query, queryResult); break;
|
|
}
|
|
}
|
|
|
|
internal void LoadMessageDependencies(List<Message> messageList)
|
|
{
|
|
// Dictionary<Guid, MessageCore> messageCoreDict = this.GetToSendMessageCoreList();
|
|
Dictionary<Guid, ReportingParty> reportingPartyDict = this.GetReportingPartyDict();
|
|
|
|
// Zuordnung MessageCore,Zuordnung Reporting party
|
|
Message.AssignReportingParties(messageList, reportingPartyDict);
|
|
// Message.AssignMessageCores(messageList, messageCoreDict);
|
|
|
|
foreach (Message message in messageList)
|
|
{
|
|
this.LoadErrorList(message);
|
|
this.LoadViolationList(message);
|
|
this.LoadSystemErrorList(message);
|
|
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
DatabaseEntity msgClass = DBManager.CreateMessage(message.MessageNotificationClass);
|
|
|
|
if (msgClass != null)
|
|
{
|
|
msgClass.PrepareLoadCommand(cmd, Message.LoadFilter.MESSAGEHEADER, message.Id);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
if (reader != null)
|
|
{
|
|
List<DatabaseEntity> statList = msgClass.LoadList(reader);
|
|
foreach (DatabaseEntity derivedMessage in statList)
|
|
{
|
|
if (message.MessageNotificationClass == Message.NotificationClass.HAZD)
|
|
{
|
|
if (derivedMessage is HAZ hAZ)
|
|
(hAZ).IsDeparture = true;
|
|
}
|
|
message.Elements.Add(derivedMessage);
|
|
derivedMessage.MessageHeader = message;
|
|
this.LoadDependingLists(derivedMessage);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Stupid workaround to find HAZA's that are attached to a HAZD message header
|
|
if(message.MessageNotificationClass == Message.NotificationClass.HAZD)
|
|
{
|
|
using (SqlCommand cmd2 = new SqlCommand())
|
|
{
|
|
DatabaseEntity dummyHAZA = DBManager.CreateMessage(Message.NotificationClass.HAZA);
|
|
|
|
if (dummyHAZA != null)
|
|
{
|
|
dummyHAZA.PrepareLoadCommand(cmd2, Message.LoadFilter.MESSAGEHEADER, message.Id);
|
|
SqlDataReader reader = this.PerformCommand(cmd2);
|
|
if (reader != null)
|
|
{
|
|
List<DatabaseEntity> statList = dummyHAZA.LoadList(reader);
|
|
foreach (DatabaseEntity derivedMessage in statList)
|
|
{
|
|
message.Elements.Add(derivedMessage);
|
|
derivedMessage.MessageHeader = message;
|
|
this.LoadDependingLists(derivedMessage);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#region MessageHistory
|
|
|
|
/// <summary>
|
|
/// Diskussion: Es wäre besser, wenn man hier nur Message serialisieren würde. Allerdings wird der "Inhalt" bei
|
|
/// einer Neuanlage erst nach der Message gespeichert und wäre dann hier nicht vorhanden. Es muss daher ein Switch über alle Element
|
|
/// Typen durchgeführt werden.
|
|
/// </summary>
|
|
/// <param name="entity"></param>
|
|
private void CreateEntityHistoryEntry(DatabaseEntity entity)
|
|
{
|
|
// sehr schöner Ansatz, den ich doch nicht verwendet habe;
|
|
//var @switch = new Dictionary<Type, Action> {
|
|
// { typeof(Type1), () => ... },
|
|
// { typeof(Type2), () => ... },
|
|
// { typeof(Type3), () => ... },
|
|
//};
|
|
|
|
//@switch[typeof(MyType)]();
|
|
|
|
Type entityType = entity.GetType();
|
|
// 1. prüfen ob für das Objekt ein Historieneintrag angelegt werden soll
|
|
if (this.messageHistoryTypeDict.ContainsKey(entityType)) {
|
|
|
|
// 2. falls ja Objekt serialisieren
|
|
MessageHistory mh = new MessageHistory();
|
|
mh.EntityId = entity.MessageHeader.Id.Value;
|
|
mh.EntityName = entityType.Name;
|
|
mh.EntityType = entityType.ToString();
|
|
mh.EntityValues = JsonConvert.SerializeObject(entity);
|
|
if (ReportingParty.CurrentReportingParty != null)
|
|
mh.ReportingPartyId = ReportingParty.CurrentReportingParty.Id.Value;
|
|
if (entity is ISublistElement sublistElement)
|
|
{
|
|
string stringIdentifier = (sublistElement).Identifier;
|
|
if (stringIdentifier == null) return;
|
|
Regex re = new Regex(@"\d+");
|
|
Match m = re.Match(stringIdentifier);
|
|
if (m.Success)
|
|
mh.Identifier = Int32.Parse(m.Value);
|
|
}
|
|
|
|
// 3. MessageHistory Element speichern
|
|
/// TODO: das könnte auch in einem Background Thread passieren, da der Wert erst irgendwann gelesen wird und aktuell nicht relevant ist
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
mh.PrepareSave(cmd);
|
|
int queryResult = this.PerformNonQuery(cmd);
|
|
this.LogNonQueryResult(cmd.CommandText, queryResult);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void InitializeMessageHistoryTypes()
|
|
{
|
|
this.messageHistoryTypeDict = new Dictionary<Type, string>
|
|
{
|
|
{ typeof(AGNT), typeof(AGNT).Name },
|
|
{ typeof(ATA), typeof(ATA).Name },
|
|
{ typeof(ATD), typeof(ATD).Name },
|
|
{ typeof(BRKA), typeof(BRKA).Name },
|
|
{ typeof(BRKD), typeof(BRKD).Name },
|
|
{ typeof(CREW), typeof(CREW).Name },
|
|
{ typeof(CREWD), typeof(CREWD).Name },
|
|
{ typeof(HAZ), typeof(HAZ).Name },
|
|
{ typeof(INFO), typeof(INFO).Name },
|
|
{ typeof(LADG), typeof(LADG).Name },
|
|
{ typeof(MDH), typeof(MDH).Name },
|
|
{ typeof(NAME), typeof(NAME).Name },
|
|
{ typeof(NOA_NOD), typeof(NOA_NOD).Name },
|
|
{ typeof(PAS), typeof(PAS).Name },
|
|
{typeof(PASD), typeof(PASD).Name },
|
|
{ typeof(POBA), typeof(POBA).Name },
|
|
{ typeof(POBD), typeof(POBD).Name },
|
|
{ typeof(PRE72H), typeof(PRE72H).Name },
|
|
{ typeof(SEC), typeof(SEC).Name },
|
|
{ typeof(SERV), typeof(SERV).Name },
|
|
{ typeof(STAT), typeof(STAT).Name },
|
|
{ typeof(STO), typeof(STO).Name },
|
|
{ typeof(TIEFA), typeof(TIEFA).Name },
|
|
{ typeof(TIEFD), typeof(TIEFD).Name },
|
|
{ typeof(TOWA), typeof(TOWA).Name },
|
|
{ typeof(TOWD), typeof(TOWD).Name },
|
|
{ typeof(WAS), typeof(WAS).Name },
|
|
{ typeof(BPOL), typeof(BPOL).Name },
|
|
{ typeof(WAS_RCPT), typeof(WAS_RCPT).Name }
|
|
};
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region CreateMessage()
|
|
|
|
/// <summary>
|
|
/// factory method for messages by type
|
|
/// </summary>
|
|
internal static DatabaseEntity CreateMessage(Message.NotificationClass notificationClass)
|
|
{
|
|
DatabaseEntity result = null;
|
|
switch (notificationClass)
|
|
{
|
|
case Message.NotificationClass.NOA_NOD: result = new NOA_NOD(); break;
|
|
case Message.NotificationClass.ATA: result = new ATA(); break;
|
|
case Message.NotificationClass.ATD: result = new ATD(); break;
|
|
case Message.NotificationClass.SEC: result = new SEC(); break;
|
|
case Message.NotificationClass.POBA: result = new POBA(); break;
|
|
case Message.NotificationClass.POBD: result = new POBD(); break;
|
|
case Message.NotificationClass.NAME: result = new NAME(); break;
|
|
case Message.NotificationClass.TIEFA: result = new TIEFA(); break;
|
|
case Message.NotificationClass.TIEFD: result = new TIEFD(); break;
|
|
case Message.NotificationClass.BKRA: result = new BRKA(); break;
|
|
case Message.NotificationClass.BKRD: result = new BRKD(); break;
|
|
case Message.NotificationClass.STAT: result = new STAT(); break;
|
|
case Message.NotificationClass.LADG: result = new LADG(); break;
|
|
case Message.NotificationClass.INFO: result = new INFO(); break;
|
|
case Message.NotificationClass.SERV: result = new SERV(); break;
|
|
case Message.NotificationClass.PRE72H: result = new PRE72H(); break;
|
|
case Message.NotificationClass.MDH: result = new MDH(); break;
|
|
case Message.NotificationClass.WAS: result = new WAS(); break;
|
|
case Message.NotificationClass.CREWA: result = new CREW(); break;
|
|
case Message.NotificationClass.PASA: result = new PAS(); break;
|
|
case Message.NotificationClass.BPOL: result = new BPOL(); break;
|
|
case Message.NotificationClass.TOWA: result = new TOWA(); break;
|
|
case Message.NotificationClass.TOWD: result = new TOWD(); break;
|
|
case Message.NotificationClass.HAZA: result = new HAZ(); break;
|
|
case Message.NotificationClass.HAZD: result = new HAZ(); ((HAZ)result).IsDeparture = true; break;
|
|
case Message.NotificationClass.AGNT: result = new AGNT(); break;
|
|
case Message.NotificationClass.STO: result = new STO(); break;
|
|
case Message.NotificationClass.CREWD: result = new CREWD(); ((CREWD)result).IsDeparture = true; break;
|
|
case Message.NotificationClass.PASD: result = new PASD(); ((PASD)result).IsDeparture = true; break;
|
|
case Message.NotificationClass.WAS_RCPT: result = new WAS_RCPT(); break;
|
|
|
|
default:
|
|
break; // VISIT, TRANSIT
|
|
}
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region LoadDependingLists
|
|
|
|
/// <summary>
|
|
/// Loads inner lists / collections
|
|
/// </summary>
|
|
internal void LoadDependingLists(DatabaseEntity databaseEntity)
|
|
{
|
|
SqlCommand cmd = new SqlCommand();
|
|
|
|
#region BPOL
|
|
|
|
if (databaseEntity.GetType().IsAssignableFrom(typeof(BPOL)))
|
|
{
|
|
BPOL bpol = databaseEntity as BPOL;
|
|
PortOfItinerary poi = new PortOfItinerary();
|
|
poi.PrepareLoadCommand(cmd, Message.LoadFilter.BPOL_ID, bpol.Id);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> pois = poi.LoadList(reader);
|
|
foreach (PortOfItinerary aPoi in pois)
|
|
{
|
|
bpol.PortOfItineraries.Add(aPoi);
|
|
aPoi.BPOL = bpol;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region HAZ
|
|
|
|
if(databaseEntity.GetType().IsAssignableFrom(typeof(HAZ)))
|
|
{
|
|
HAZ haz = databaseEntity as HAZ;
|
|
|
|
// load all 5 position sublists
|
|
IMDGPosition imdg = new IMDGPosition();
|
|
imdg.PrepareLoadCommand(cmd, Message.LoadFilter.HAZ_ID, haz.Id);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> imdgs = imdg.LoadList(reader);
|
|
foreach (IMDGPosition imdgPosition in imdgs)
|
|
{
|
|
haz.IMDGPositions.Add(imdgPosition);
|
|
imdgPosition.HAZ = haz;
|
|
|
|
// load SubsidiaryRisk sub-table
|
|
SqlCommand srCmd = new SqlCommand();
|
|
SubsidiaryRisks subsidiaryRisks = new SubsidiaryRisks();
|
|
subsidiaryRisks.PrepareLoadCommand(srCmd, Message.LoadFilter.IMDG_ID, imdgPosition.Id);
|
|
SqlDataReader srReader = this.PerformCommand(srCmd);
|
|
List<DatabaseEntity> sRisks = subsidiaryRisks.LoadList(srReader);
|
|
foreach (SubsidiaryRisks subsidiaryRisk in sRisks)
|
|
{
|
|
imdgPosition.SubsidiaryRiskList.Add(subsidiaryRisk);
|
|
subsidiaryRisk.IMDGPosition = imdgPosition;
|
|
}
|
|
}
|
|
|
|
cmd = new SqlCommand();
|
|
|
|
IBCPosition ibc = new IBCPosition();
|
|
ibc.PrepareLoadCommand(cmd, Message.LoadFilter.HAZ_ID, haz.Id);
|
|
reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> ibcs = ibc.LoadList(reader);
|
|
foreach (IBCPosition ibcPosition in ibcs)
|
|
{
|
|
haz.IBCPositions.Add(ibcPosition);
|
|
ibcPosition.HAZ = haz;
|
|
}
|
|
|
|
cmd = new SqlCommand();
|
|
|
|
IGCPosition igc = new IGCPosition();
|
|
igc.PrepareLoadCommand(cmd, Message.LoadFilter.HAZ_ID, haz.Id);
|
|
reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> igcs = igc.LoadList(reader);
|
|
foreach (IGCPosition igcPosition in igcs)
|
|
{
|
|
haz.IGCPositions.Add(igcPosition);
|
|
igcPosition.HAZ = haz;
|
|
}
|
|
|
|
cmd = new SqlCommand();
|
|
|
|
IMSBCPosition imsbc = new IMSBCPosition();
|
|
imsbc.PrepareLoadCommand(cmd, Message.LoadFilter.HAZ_ID, haz.Id);
|
|
reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> imsbcs = imsbc.LoadList(reader);
|
|
foreach (IMSBCPosition imsbcPosition in imsbcs)
|
|
{
|
|
haz.IMSBCPositions.Add(imsbcPosition);
|
|
imsbcPosition.HAZ = haz;
|
|
}
|
|
|
|
cmd = new SqlCommand();
|
|
MARPOL_Annex_I_Position marpol = new MARPOL_Annex_I_Position();
|
|
marpol.PrepareLoadCommand(cmd, Message.LoadFilter.HAZ_ID, haz.Id);
|
|
reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> marpols = marpol.LoadList(reader);
|
|
foreach (MARPOL_Annex_I_Position marpolPosition in marpols)
|
|
{
|
|
haz.MARPOLPositions.Add(marpolPosition);
|
|
marpolPosition.HAZ = haz;
|
|
}
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region MDH
|
|
|
|
if (databaseEntity.GetType().IsAssignableFrom(typeof(MDH)))
|
|
{
|
|
MDH mdh = databaseEntity as MDH;
|
|
|
|
PortOfCallLast30Days poc30 = new PortOfCallLast30Days();
|
|
poc30.PrepareLoadCommand(cmd, Message.LoadFilter.MDH_ID, mdh.Id);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> poc30s = poc30.LoadList(reader);
|
|
foreach (PortOfCallLast30Days apoc30 in poc30s)
|
|
{
|
|
mdh.PortOfCallLast30Days.Add(apoc30);
|
|
apoc30.MDH = mdh;
|
|
this.LoadDependingLists(apoc30);
|
|
}
|
|
|
|
SanitaryMeasuresDetail smd = new SanitaryMeasuresDetail();
|
|
smd.PrepareLoadCommand(cmd, Message.LoadFilter.MDH_ID, mdh.Id);
|
|
reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> smds = smd.LoadList(reader);
|
|
foreach(SanitaryMeasuresDetail aSmd in smds)
|
|
{
|
|
mdh.SanitaryMeasuresDetails.Add(aSmd);
|
|
aSmd.MDH = mdh;
|
|
}
|
|
|
|
StowawaysJoiningLocation sjl = new StowawaysJoiningLocation();
|
|
sjl.PrepareLoadCommand(cmd, Message.LoadFilter.MDH_ID, mdh.Id);
|
|
reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> sjls = sjl.LoadList(reader);
|
|
foreach(StowawaysJoiningLocation aSjl in sjls)
|
|
{
|
|
mdh.StowawaysJoiningLocations.Add(aSjl);
|
|
aSjl.MDH = mdh;
|
|
}
|
|
|
|
InfectedArea ia = new InfectedArea();
|
|
ia.PrepareLoadCommand(cmd, Message.LoadFilter.MDH_ID, mdh.Id);
|
|
reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> ias = ia.LoadList(reader);
|
|
foreach(InfectedArea aIa in ias)
|
|
{
|
|
mdh.InfectedAreas.Add(aIa);
|
|
aIa.MDH = mdh;
|
|
}
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region PortOfCallLast30Days
|
|
|
|
if (databaseEntity.GetType().IsAssignableFrom(typeof(PortOfCallLast30Days)))
|
|
{
|
|
PortOfCallLast30Days poc30 = databaseEntity as PortOfCallLast30Days;
|
|
PortOfCallLast30DaysCrewJoinedShip poc30s = new PortOfCallLast30DaysCrewJoinedShip();
|
|
poc30s.PrepareLoadCommand(cmd, Message.LoadFilter.POC30_ID, poc30.Id);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> poc30Names = poc30s.LoadList(reader);
|
|
foreach (PortOfCallLast30DaysCrewJoinedShip poc30Name in poc30Names)
|
|
{
|
|
poc30.CrewJoinedShip.Add(poc30Name);
|
|
poc30Name.PortOfCallLast30Days = poc30;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region SEC
|
|
|
|
if (databaseEntity.GetType().IsAssignableFrom(typeof(SEC)))
|
|
{
|
|
SEC sec = databaseEntity as SEC;
|
|
LastTenPortFacilitiesCalled ltp = new LastTenPortFacilitiesCalled();
|
|
ltp.PrepareLoadCommand(cmd, Message.LoadFilter.SEC_ID, sec.Id);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> ltps = ltp.LoadList(reader);
|
|
foreach (LastTenPortFacilitiesCalled altp in ltps)
|
|
{
|
|
sec.LastTenPortFacilitesCalled.Add(altp);
|
|
altp.SEC = sec;
|
|
}
|
|
|
|
cmd = new SqlCommand();
|
|
ShipToShipActivitiesDuringLastTenPortFacilitiesCalled sts = new ShipToShipActivitiesDuringLastTenPortFacilitiesCalled();
|
|
sts.PrepareLoadCommand(cmd, Message.LoadFilter.SEC_ID, sec.Id);
|
|
reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> stss = sts.LoadList(reader);
|
|
foreach (ShipToShipActivitiesDuringLastTenPortFacilitiesCalled asts in stss)
|
|
{
|
|
sec.ShipToShipActivitiesDuringLastTenPortFacilitiesCalled.Add(asts);
|
|
asts.SEC = sec;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region WAS
|
|
|
|
if(databaseEntity.GetType().IsAssignableFrom(typeof(WAS)))
|
|
{
|
|
WAS was = databaseEntity as WAS;
|
|
|
|
WasteDisposalServiceProvider wdsp = new WasteDisposalServiceProvider();
|
|
wdsp.PrepareLoadCommand(cmd, Message.LoadFilter.WAS_ID, was.Id);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> wdsps = wdsp.LoadList(reader);
|
|
foreach (WasteDisposalServiceProvider awdsp in wdsps)
|
|
{
|
|
was.WasteDisposalServiceProvider.Add(awdsp);
|
|
awdsp.WAS = was;
|
|
this.LoadDependingLists(awdsp);
|
|
}
|
|
|
|
Waste waste = new Waste();
|
|
waste.PrepareLoadCommand(cmd, Message.LoadFilter.WAS_ID, was.Id);
|
|
SqlDataReader reader2 = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> wastes = waste.LoadList(reader2);
|
|
foreach (Waste aWaste in wastes)
|
|
{
|
|
was.Waste.Add(aWaste);
|
|
aWaste.WAS = was;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region WAS_RCPT
|
|
|
|
if (databaseEntity.GetType().IsAssignableFrom(typeof(WAS_RCPT)))
|
|
{
|
|
WAS_RCPT was_rcpt = databaseEntity as WAS_RCPT;
|
|
|
|
TreatmentFacilityProvider tfp = new TreatmentFacilityProvider();
|
|
tfp.PrepareLoadCommand(cmd, Message.LoadFilter.WASRCPT_ID, was_rcpt.Id);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> tfps = tfp.LoadList(reader);
|
|
foreach (TreatmentFacilityProvider aTfp in tfps)
|
|
{
|
|
was_rcpt.TreatmentFacilityProvider.Add(aTfp);
|
|
aTfp.WAS_RCPT = was_rcpt;
|
|
this.LoadDependingLists(aTfp);
|
|
}
|
|
|
|
WasteReceived wasteReceived = new WasteReceived();
|
|
wasteReceived.PrepareLoadCommand(cmd, Message.LoadFilter.WASRCPT_ID, was_rcpt.Id);
|
|
SqlDataReader reader2 = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> wrs = wasteReceived.LoadList(reader2);
|
|
foreach (WasteReceived awrs in wrs)
|
|
{
|
|
was_rcpt.WasteReceived.Add(awrs);
|
|
awrs.WAS_RCPT = was_rcpt;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region NOA_NOD
|
|
|
|
if (databaseEntity.GetType().IsAssignableFrom(typeof(NOA_NOD)))
|
|
{
|
|
NOA_NOD noa_nod = databaseEntity as NOA_NOD;
|
|
|
|
CallPurpose cp = new CallPurpose();
|
|
cp.PrepareLoadCommand(cmd, Message.LoadFilter.NOA_NODID, noa_nod.Id);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> cps = cp.LoadList(reader);
|
|
foreach (CallPurpose callPurpose in cps)
|
|
{
|
|
noa_nod.CallPurposes.Add(callPurpose);
|
|
callPurpose.NOA_NOD = noa_nod;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region WasteDisposalServiceProvider
|
|
|
|
/*
|
|
if (databaseEntity.GetType().IsAssignableFrom(typeof(WasteDisposalServiceProvider)))
|
|
{
|
|
WasteDisposalServiceProvider wdsp = databaseEntity as WasteDisposalServiceProvider;
|
|
|
|
}
|
|
*/
|
|
|
|
#endregion
|
|
|
|
cmd.Dispose();
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Error / Violation
|
|
|
|
internal void LoadErrorList(Message message)
|
|
{
|
|
MessageError aMessageError = new MessageError();
|
|
SqlCommand cmd = new SqlCommand();
|
|
aMessageError.PrepareLoadCommand(cmd, Message.LoadFilter.MESSAGEHEADER, message.Id);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> errorList = aMessageError.LoadList(reader);
|
|
foreach (MessageError error in errorList)
|
|
message.ErrorList.Add(error);
|
|
}
|
|
|
|
internal void LoadViolationList(Message message)
|
|
{
|
|
MessageViolation aMessageViolation = new MessageViolation();
|
|
SqlCommand cmd = new SqlCommand();
|
|
aMessageViolation.PrepareLoadCommand(cmd, Message.LoadFilter.MESSAGEHEADER, message.Id);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> violationList = aMessageViolation.LoadList(reader);
|
|
foreach (MessageViolation violation in violationList)
|
|
message.ViolationList.Add(violation);
|
|
}
|
|
|
|
internal void LoadSystemErrorList(Message message)
|
|
{
|
|
SystemError aSystemError = new SystemError();
|
|
SqlCommand cmd = new SqlCommand();
|
|
aSystemError.PrepareLoadCommand(cmd, Message.LoadFilter.MESSAGEHEADER, message.Id);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> systemErrorList = aSystemError.LoadList(reader);
|
|
foreach (SystemError sError in systemErrorList)
|
|
message.SystemErrorList.Add(sError);
|
|
}
|
|
|
|
internal Dictionary<int, string> LoadErrorTexts()
|
|
{
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
cmd.CommandText = "SELECT ErrorCode, ErrorText FROM ErrorText";
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
Dictionary<int, string> result = new Dictionary<int, string>();
|
|
while (reader.Read())
|
|
{
|
|
int errorCode = reader.GetInt32(0);
|
|
string errorText = reader.GetString(1);
|
|
result[errorCode] = errorText;
|
|
}
|
|
reader.Close();
|
|
return result;
|
|
}
|
|
}
|
|
|
|
internal Dictionary<int, string> LoadViolationTexts()
|
|
{
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
cmd.CommandText = "SELECT ViolationCode, ViolationText FROM ViolationText";
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
Dictionary<int, string> result = new Dictionary<int, string>();
|
|
while (reader.Read())
|
|
{
|
|
int violationCode = reader.GetInt32(0);
|
|
string violationText = reader.GetString(1);
|
|
result[violationCode] = violationText;
|
|
}
|
|
reader.Close();
|
|
return result;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Convenience loading functions
|
|
|
|
internal void LoadCustomer(MessageCore core)
|
|
{
|
|
if (core.CustomerId.HasValue)
|
|
{
|
|
Customer c = new Customer();
|
|
SqlCommand cCmd = new SqlCommand();
|
|
c.PrepareLoadCommand(cCmd, Message.LoadFilter.BY_ID, core.CustomerId.Value);
|
|
SqlDataReader reader = this.PerformCommand(cCmd);
|
|
List<DatabaseEntity> customers = c.LoadList(reader);
|
|
if (customers.Count > 0)
|
|
core.Customer = customers[0] as Customer;
|
|
}
|
|
}
|
|
|
|
internal void LoadSTATShipName(MessageCore core)
|
|
{
|
|
if (core == null) return;
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
cmd.CommandText = "SELECT STAT.ShipName, STAT.GrossTonnage FROM STAT JOIN MessageHeader ON STAT.MessageHeaderId = MessageHeader.Id WHERE MessageHeader.MessageCoreId = @ID";
|
|
cmd.Parameters.AddWithValue("@ID", core.Id);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
if (reader.Read())
|
|
{
|
|
if (reader.IsDBNull(0))
|
|
core.Shipname = "";
|
|
else
|
|
core.Shipname = reader.GetString(0);
|
|
if (!reader.IsDBNull(1))
|
|
{
|
|
int grossTonnage = reader.GetInt32(1);
|
|
core.IsSmallShip = grossTonnage < 500;
|
|
}
|
|
}
|
|
reader.Close();
|
|
}
|
|
}
|
|
|
|
internal void LoadETA_ETD(MessageCore core)
|
|
{
|
|
if (core == null) return;
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
cmd.CommandText = "SELECT NOA_NOD.ETAToPortOfCall, NOA_NOD.ETAToKielCanal, NOA_NOD.ETDFromPortOfCall, NOA_NOD.ETDFromKielCanal FROM NOA_NOD JOIN MessageHeader ON NOA_NOD.MessageHeaderId = MessageHeader.Id WHERE MessageHeader.MessageCoreId = @ID";
|
|
cmd.Parameters.AddWithValue("@ID", core.Id);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
if (reader.Read())
|
|
{
|
|
if (core.IsTransit)
|
|
{
|
|
if (!reader.IsDBNull(1)) core.ETA_NOA_NOD = reader.GetDateTime(1);
|
|
if (!reader.IsDBNull(3)) core.ETD_NOA_NOD = reader.GetDateTime(3);
|
|
}
|
|
else
|
|
{
|
|
if (!reader.IsDBNull(0)) core.ETA_NOA_NOD = reader.GetDateTime(0);
|
|
if (!reader.IsDBNull(2)) core.ETD_NOA_NOD = reader.GetDateTime(2);
|
|
}
|
|
}
|
|
reader.Close();
|
|
}
|
|
|
|
if (!core.ETA_NOA_NOD.HasValue && !core.IsTransit && core.ETA.HasValue)
|
|
{
|
|
// die Zeit aus MessageCore ist nur ein Datum. Daher verwendet er 00:00 als lokale Zeit, was z.B. nach 01:00 MET zur Anzeige konvertiert wird.
|
|
// Das darf in diesem Fall nicht sein, der Wert müsste also gefakt lokal gesetzt werden.. ouch hack
|
|
core.ETA_NOA_NOD = DateTime.SpecifyKind(core.ETA.Value, DateTimeKind.Local).ToUniversalTime();
|
|
}
|
|
|
|
if (!core.ETA_NOA_NOD.HasValue && core.IsTransit && core.ETAKielCanal.HasValue)
|
|
{
|
|
core.ETA_NOA_NOD = DateTime.SpecifyKind(core.ETAKielCanal.Value, DateTimeKind.Local).ToUniversalTime();
|
|
}
|
|
|
|
}
|
|
|
|
internal void LoadATA(MessageCore core)
|
|
{
|
|
if (core == null) return;
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
cmd.CommandText = "SELECT MessageHeader.BSMDStatus, ATA.ATAPortOfCall FROM ATA JOIN MessageHeader ON ATA.MessageHeaderId = MessageHeader.Id WHERE MessageHeader.MessageCoreId = @ID";
|
|
cmd.Parameters.AddWithValue("@ID", core.Id);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
if (reader.Read())
|
|
{
|
|
Message.BSMDStatus status = Message.BSMDStatus.UNDEFINED;
|
|
if (!reader.IsDBNull(0)) status = (Message.BSMDStatus)Enum.ToObject(typeof(Message.BSMDStatus), reader.GetByte(0));
|
|
if (!reader.IsDBNull(1))
|
|
{
|
|
core.ATA = reader.GetDateTime(1);
|
|
core.UnsentATAATD |= (status == Message.BSMDStatus.SAVED) || (status == Message.BSMDStatus.EXCEL) || (status == Message.BSMDStatus.UPDATED);
|
|
}
|
|
}
|
|
reader.Close();
|
|
}
|
|
}
|
|
|
|
internal void LoadATD(MessageCore core)
|
|
{
|
|
if (core == null) return;
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
cmd.CommandText = "SELECT MessageHeader.BSMDStatus, ATD.ATDPortOfCall FROM ATD JOIN MessageHeader ON ATD.MessageHeaderId = MessageHeader.Id WHERE MessageHeader.MessageCoreId = @ID";
|
|
cmd.Parameters.AddWithValue("@ID", core.Id);
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
if (reader.Read())
|
|
{
|
|
Message.BSMDStatus status = Message.BSMDStatus.UNDEFINED;
|
|
if (!reader.IsDBNull(0)) status = (Message.BSMDStatus)Enum.ToObject(typeof(Message.BSMDStatus), reader.GetByte(0));
|
|
if (!reader.IsDBNull(1))
|
|
{
|
|
core.ATD = reader.GetDateTime(1);
|
|
core.UnsentATAATD |= (status == Message.BSMDStatus.SAVED) || (status == Message.BSMDStatus.EXCEL) || (status == Message.BSMDStatus.UPDATED);
|
|
}
|
|
}
|
|
reader.Close();
|
|
}
|
|
}
|
|
|
|
internal void LoadNumberSent(MessageCore core)
|
|
{
|
|
if (core == null) return;
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
cmd.CommandText = "SELECT COUNT(*) FROM MessageHeader WHERE MessageHeader.MessageCoreId = @ID AND ((MessageHeader.NotificationClass > 1 AND MessageHeader.NotificationClass < 28) OR MessageHeader.NotificationClass > 30)";
|
|
cmd.Parameters.AddWithValue("@ID", core.Id);
|
|
int total = this.PerformReadIntQuery(cmd) ?? 0;
|
|
|
|
cmd.CommandText = "SELECT COUNT(*) FROM MessageHeader WHERE MessageHeader.MessageCoreId = @ID AND MessageHeader.BSMDStatus = 5 AND ((MessageHeader.NotificationClass > 1 AND MessageHeader.NotificationClass < 28) OR MessageHeader.NotificationClass > 30)"; // compare "CONFIRMED"
|
|
int sent = this.PerformReadIntQuery(cmd) ?? 0;
|
|
|
|
core.NumberSentDisplay = string.Format("{0}/{1}", sent, total);
|
|
core.NumberSent = sent;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region DB access methods
|
|
|
|
internal SqlDataReader PerformCommand(SqlCommand cmd)
|
|
{
|
|
SqlDataReader reader = null;
|
|
|
|
lock (this._lock)
|
|
{
|
|
try
|
|
{
|
|
|
|
this.CheckConnection();
|
|
|
|
cmd.Connection = this._con;
|
|
// Stopwatch sw = new Stopwatch();
|
|
// sw.Start();
|
|
reader = cmd.ExecuteReader();
|
|
// sw.Stop();
|
|
// _log.DebugFormat("{1}ms: {0}", cmd.CommandText, sw.ElapsedMilliseconds);
|
|
|
|
}
|
|
catch (SqlException ex)
|
|
{
|
|
Trace.WriteLine("SQL Exception:" + ex.Message);
|
|
_log.Error("Error performing command", ex);
|
|
_log.DebugFormat("Query: {0}", cmd.CommandText);
|
|
_log.Debug("Parameters:");
|
|
for (int i = 0; i < cmd.Parameters.Count; i++)
|
|
{
|
|
_log.DebugFormat("{0}:{1}", cmd.Parameters[i].ParameterName, cmd.Parameters[i].Value);
|
|
}
|
|
}
|
|
}
|
|
return reader;
|
|
}
|
|
|
|
internal int PerformNonQuery(SqlCommand cmd)
|
|
{
|
|
int result = -1;
|
|
lock (this._lock)
|
|
{
|
|
try
|
|
{
|
|
this.CheckConnection();
|
|
|
|
cmd.Connection = this._con;
|
|
result = cmd.ExecuteNonQuery();
|
|
}
|
|
catch (SqlException ex)
|
|
{
|
|
System.Diagnostics.Trace.WriteLine("SQL Exception:" + ex.Message);
|
|
_log.Error("Error performing command", ex);
|
|
_log.DebugFormat("Query: {0}", cmd.CommandText);
|
|
_log.Debug("Parameters:");
|
|
for (int i = 0; i < cmd.Parameters.Count; i++)
|
|
{
|
|
_log.DebugFormat("{0}:{1}", cmd.Parameters[i].ParameterName, cmd.Parameters[i].Value);
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
internal bool? PerformReadFlagQuery(SqlCommand cmd)
|
|
{
|
|
bool? result = null;
|
|
|
|
lock (this._lock)
|
|
{
|
|
try
|
|
{
|
|
this.CheckConnection();
|
|
cmd.Connection = this._con;
|
|
result = (bool?)cmd.ExecuteScalar();
|
|
}
|
|
catch (SqlException ex)
|
|
{
|
|
_log.Error("Error performing command", ex);
|
|
_log.DebugFormat("Query: {0}", cmd.CommandText);
|
|
_log.Debug("Parameters:");
|
|
for (int i = 0; i < cmd.Parameters.Count; i++)
|
|
{
|
|
_log.DebugFormat("{0}:{1}", cmd.Parameters[i].ParameterName, cmd.Parameters[i].Value);
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
internal int? PerformReadIntQuery(SqlCommand cmd)
|
|
{
|
|
int? result = null;
|
|
|
|
lock (this._lock)
|
|
{
|
|
try
|
|
{
|
|
this.CheckConnection();
|
|
cmd.Connection = this._con;
|
|
object r = cmd.ExecuteScalar();
|
|
if (r == null) { result = null; }
|
|
else if (r == DBNull.Value) { result = null; }
|
|
else { result = (int)r; }
|
|
|
|
}
|
|
catch (SqlException ex)
|
|
{
|
|
_log.Error("Error performing command", ex);
|
|
_log.DebugFormat("Query: {0}", cmd.CommandText);
|
|
_log.Debug("Parameters:");
|
|
for (int i = 0; i < cmd.Parameters.Count; i++)
|
|
{
|
|
_log.DebugFormat("{0}:{1}", cmd.Parameters[i].ParameterName, cmd.Parameters[i].Value);
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public void PerformBulkInsert(DataTable table)
|
|
{
|
|
lock (this._lock)
|
|
{
|
|
this.CheckConnection();
|
|
|
|
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(this._con, SqlBulkCopyOptions.UseInternalTransaction | SqlBulkCopyOptions.TableLock, null))
|
|
{
|
|
bulkCopy.BulkCopyTimeout = 180;
|
|
foreach (DataColumn dataColumn in table.Columns)
|
|
{
|
|
bulkCopy.ColumnMappings.Add(dataColumn.ColumnName, dataColumn.ColumnName);
|
|
}
|
|
|
|
bulkCopy.BatchSize = table.Rows.Count;
|
|
bulkCopy.DestinationTableName = table.TableName;
|
|
bulkCopy.WriteToServer(table);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
}
|
|
}
|