504 lines
20 KiB
C#
504 lines
20 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 log4net;
|
|
|
|
namespace bsmd.database
|
|
{
|
|
public class DBManager
|
|
{
|
|
private SqlConnection _con;
|
|
private static DBManager _instance;
|
|
private static ILog _log = LogManager.GetLogger(typeof(DBManager));
|
|
|
|
#region Properties
|
|
|
|
public static DBManager Instance
|
|
{
|
|
get
|
|
{
|
|
if (_instance == null)
|
|
_instance = new DBManager();
|
|
return _instance;
|
|
}
|
|
}
|
|
|
|
public string ConnectionString { get; set; }
|
|
|
|
#endregion
|
|
|
|
#region public DB funcs
|
|
|
|
public bool Connect(string dbConnectionString)
|
|
{
|
|
try
|
|
{
|
|
_con = new SqlConnection(dbConnectionString);
|
|
_con.Open();
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_log.Error("DBManager cannot connect", ex);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public void Disconnect()
|
|
{
|
|
if ((this._con != null) && (this._con.State == ConnectionState.Open))
|
|
this._con.Close();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public helper funcs
|
|
|
|
public Dictionary<Guid, MessageCore> GetToSendMessageCoreList()
|
|
{
|
|
MessageCore aMessageCore = new MessageCore();
|
|
SqlCommand cmd = new SqlCommand();
|
|
Message.LoadFilter filter = Message.LoadFilter.BSMDSTATUS;
|
|
aMessageCore.PrepareLoadCommand(cmd, filter, Message.BSMDStatus.TOSEND);
|
|
|
|
SqlDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> cores = aMessageCore.LoadList(reader);
|
|
Dictionary<Guid, MessageCore> result = new Dictionary<Guid, MessageCore>();
|
|
foreach (MessageCore core in cores)
|
|
result.Add(core.Id.Value, core);
|
|
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 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)
|
|
return (MessageCore) cores[0];
|
|
return null;
|
|
}
|
|
|
|
public List<Message> GetMessagesForCore(MessageCore core)
|
|
{
|
|
Message aMessage = new Message();
|
|
SqlCommand cmd = new SqlCommand();
|
|
aMessage.PrepareLoadCommand(cmd, Message.LoadFilter.BY_CORE, core.Id);
|
|
IDataReader reader = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> messages = aMessage.LoadList(reader);
|
|
List<Message> messageList = new List<Message>();
|
|
foreach (Message message in messages)
|
|
messageList.Add(message);
|
|
|
|
this.LoadMessageDependencies(messageList);
|
|
return messageList;
|
|
}
|
|
|
|
public List<Message> GetToSendMessageList()
|
|
{
|
|
Message aMessage = new Message();
|
|
SqlCommand cmd = new SqlCommand();
|
|
Message.LoadFilter filter = Message.LoadFilter.BSMDSTATUS;
|
|
aMessage.PrepareLoadCommand(cmd, filter, Message.BSMDStatus.TOSEND);
|
|
|
|
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);
|
|
|
|
this.LoadMessageDependencies(messageList);
|
|
|
|
return messageList;
|
|
}
|
|
|
|
public Dictionary<Guid, ReportingParty> GetReportingPartyDict()
|
|
{
|
|
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);
|
|
Dictionary<Guid, ReportingParty> result = new Dictionary<Guid, ReportingParty>();
|
|
foreach (ReportingParty rp in reportingParties)
|
|
result.Add(rp.Id.Value, rp);
|
|
|
|
return result;
|
|
}
|
|
|
|
public DatabaseEntity GetMessageById(Guid id)
|
|
{
|
|
Message aMessage = new Message();
|
|
SqlCommand cmd = new SqlCommand();
|
|
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 MessageCore GetMessageCoreById(Guid id)
|
|
{
|
|
MessageCore aCore = new MessageCore();
|
|
SqlCommand cmd = new SqlCommand();
|
|
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;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
public void Save(DatabaseEntity entity)
|
|
{
|
|
SqlCommand cmd = new SqlCommand();
|
|
entity.PrepareSave(cmd);
|
|
int queryResult = this.PerformNonQuery(cmd);
|
|
switch(queryResult)
|
|
{
|
|
case 1:
|
|
_log.InfoFormat("Message {0} saved", entity.Id); break;
|
|
case 0:
|
|
_log.WarnFormat("Message {0} save affected no rows", entity.Id); break;
|
|
case -1:
|
|
_log.WarnFormat("Message {0} save: error occurred", entity.Id); break;
|
|
default:
|
|
_log.WarnFormat("Message {0} save affected {1} rows", entity.Id, queryResult); break;
|
|
}
|
|
}
|
|
|
|
public void Save(MessageCore core)
|
|
{
|
|
if (core.Customer != null)
|
|
{
|
|
SqlCommand cCmd = new SqlCommand();
|
|
core.Customer.PrepareSave(cCmd);
|
|
_log.InfoFormat("Saved Customer to Core: {0}", this.PerformNonQuery(cCmd));
|
|
core.CustomerId = core.Customer.Id;
|
|
}
|
|
|
|
SqlCommand cmd = new SqlCommand();
|
|
core.PrepareSave(cmd);
|
|
int queryResult = this.PerformNonQuery(cmd);
|
|
if (queryResult == 1)
|
|
_log.InfoFormat("MessageCore {0} saved", core.Id);
|
|
else
|
|
_log.WarnFormat("MessageCore {0} save affected {1} rows", core.Id, queryResult);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region internal/private funcs
|
|
|
|
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);
|
|
|
|
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);
|
|
List<DatabaseEntity> statList = msgClass.LoadList(reader);
|
|
foreach (DatabaseEntity derivedMessage in statList)
|
|
{
|
|
message.Elements.Add(derivedMessage);
|
|
derivedMessage.MessageHeader = message;
|
|
this.LoadDependingLists(derivedMessage);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_log.ErrorFormat("cannot create a message class for notification type {0}", message.MessageNotificationClass);
|
|
}
|
|
}
|
|
}
|
|
|
|
#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.CREW: result = new CREW(); break;
|
|
case Message.NotificationClass.PAS: 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:
|
|
case Message.NotificationClass.HAZD:
|
|
_log.WarnFormat("CreateMessage: message type {0} is not supported", notificationClass.ToString());
|
|
break;
|
|
default:
|
|
break; // VISIT, TRANSIT
|
|
}
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Loads inner lists / collections
|
|
/// </summary>
|
|
internal void LoadDependingLists(DatabaseEntity databaseEntity)
|
|
{
|
|
SqlCommand cmd = new SqlCommand();
|
|
|
|
#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);
|
|
}
|
|
}
|
|
|
|
#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.WDSP_ID, was.Id);
|
|
SqlDataReader reader2 = this.PerformCommand(cmd);
|
|
List<DatabaseEntity> wastes = wdsp.LoadList(reader2);
|
|
foreach (Waste aWaste in wastes)
|
|
{
|
|
was.Waste.Add(aWaste);
|
|
aWaste.WAS = was;
|
|
}
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region WasteDisposalServiceProvider
|
|
|
|
if(databaseEntity.GetType().IsAssignableFrom(typeof(WasteDisposalServiceProvider)))
|
|
{
|
|
WasteDisposalServiceProvider wdsp = databaseEntity as WasteDisposalServiceProvider;
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
#region DB access methods
|
|
|
|
internal SqlDataReader PerformCommand(SqlCommand cmd)
|
|
{
|
|
try
|
|
{
|
|
cmd.Connection = this._con;
|
|
SqlDataReader reader = cmd.ExecuteReader();
|
|
return reader;
|
|
}
|
|
catch (SqlException ex)
|
|
{
|
|
System.Diagnostics.Trace.WriteLine("SQL Exception:" + ex.Message);
|
|
_log.Error("Error performing command", ex);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
internal int PerformNonQuery(SqlCommand cmd)
|
|
{
|
|
try
|
|
{
|
|
cmd.Connection = this._con;
|
|
return cmd.ExecuteNonQuery();
|
|
}
|
|
catch (SqlException ex)
|
|
{
|
|
System.Diagnostics.Trace.WriteLine("SQL Exception:" + ex.Message);
|
|
_log.Error("Error performing command", ex);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
}
|
|
}
|