434 lines
16 KiB
C#
434 lines
16 KiB
C#
// Copyright (c) 2023-present schick Informatik
|
|
// Description: Variant of DBManager that uses async calls
|
|
|
|
using log4net;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data.SqlClient;
|
|
using System.Diagnostics;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace bsmd.database
|
|
{
|
|
public static class DBManagerAsync
|
|
{
|
|
#region Fields
|
|
|
|
private static readonly ILog _log = LogManager.GetLogger(typeof(DBManagerAsync));
|
|
private static readonly SemaphoreSlim _portAreaLoadLock = new SemaphoreSlim(1, 1);
|
|
private static readonly SemaphoreSlim _ladgNst2007LoadLock = new SemaphoreSlim(1, 1);
|
|
private static readonly SemaphoreSlim _servTemplateLoadLock = new SemaphoreSlim(1, 1);
|
|
private static List<PortArea> _allPortAreaRows;
|
|
private static Dictionary<string, PortArea> _allPortAreasByCode;
|
|
private static List<LADG_NST2007> _allLADGNST2007Rows;
|
|
private static Dictionary<string, LADG_NST2007> _allLADGNST2007ByDescription;
|
|
private static List<SERV_Template> _allSERVTemplates;
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
public static string ConnectionString { get; set; }
|
|
|
|
#endregion
|
|
|
|
#region public methods
|
|
|
|
public static async Task<int> SaveAsync(DatabaseEntity entity)
|
|
{
|
|
SqlCommand cmd = new SqlCommand();
|
|
entity.PrepareSave(cmd);
|
|
int result = await PerformNonQueryAsync(cmd);
|
|
if (result == 1) entity.IsDirty = false;
|
|
if ((result == 1) && (entity is PortArea))
|
|
InvalidatePortAreaCache();
|
|
if ((result == 1) && (entity is LADG_NST2007))
|
|
InvalidateLADGNST2007Cache();
|
|
if ((result == 1) && (entity is SERV_Template))
|
|
InvalidateSERVTemplatesCache();
|
|
return result;
|
|
}
|
|
|
|
public static async Task<int> DeleteAsync(DatabaseEntity entity)
|
|
{
|
|
if (!entity.IsNew)
|
|
{
|
|
using (SqlCommand cmd = new SqlCommand())
|
|
{
|
|
entity.PrepareDelete(cmd);
|
|
int result = await PerformNonQueryAsync(cmd);
|
|
if ((result == 1) && (entity is PortArea))
|
|
InvalidatePortAreaCache();
|
|
if ((result == 1) && (entity is LADG_NST2007))
|
|
InvalidateLADGNST2007Cache();
|
|
if ((result == 1) && (entity is SERV_Template))
|
|
InvalidateSERVTemplatesCache();
|
|
return result;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#region convenience loading functions
|
|
|
|
public static async Task<List<MessageCore>> LoadMaerskCoresByIntervalAsync(Dictionary<MessageCore.SearchFilterType, string> filterDict, bool loadXtraData = false)
|
|
{
|
|
SqlCommand cmd = new SqlCommand();
|
|
MessageCore aMessageCore = new MessageCore();
|
|
aMessageCore.PrepareLoadCommand(cmd, Message.LoadFilter.SEARCH_CORE_FILTERS, filterDict);
|
|
SqlDataReader reader = await PerformCommandAsync(cmd);
|
|
return await aMessageCore.LoadListAsync(reader);
|
|
}
|
|
|
|
public static async Task<MessageCore> LoadCoreByVisitIdAsync(string visitId)
|
|
{
|
|
SqlCommand cmd = new SqlCommand();
|
|
MessageCore aMessageCore = new MessageCore();
|
|
aMessageCore.PrepareLoadCommand(cmd, Message.LoadFilter.BY_VISITID, visitId);
|
|
SqlDataReader reader = await PerformCommandAsync(cmd);
|
|
List<MessageCore> resultList = await aMessageCore.LoadListAsync(reader);
|
|
MessageCore result = null;
|
|
if(resultList.Count > 0)
|
|
{
|
|
if(resultList.Count > 1)
|
|
_log.WarnFormat("more than one core found for VISIT-ID {0}", visitId);
|
|
result = resultList[0];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static async Task<MaerskData> LoadMaerskDataForCoreAsync(Guid messageCoreId)
|
|
{
|
|
SqlCommand cmd = new SqlCommand();
|
|
MaerskData md = new MaerskData();
|
|
md.PrepareLoadCommand(cmd, Message.LoadFilter.BY_CORE, messageCoreId);
|
|
SqlDataReader reader = await PerformCommandAsync(cmd);
|
|
List<MaerskData> resultList = (await md.LoadListAsync(reader)).ConvertAll(x => (MaerskData) x);
|
|
MaerskData result = null;
|
|
if(resultList.Count > 0)
|
|
{
|
|
if(resultList.Count > 1)
|
|
_log.WarnFormat("more than one xtra data found for core id {0}", messageCoreId);
|
|
result = resultList[0];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static async Task<List<ValueMapping>> LoadValuesForType(ValueMapping.MappingType mappingType)
|
|
{
|
|
SqlCommand cmd = new SqlCommand();
|
|
ValueMapping vm = new ValueMapping();
|
|
vm.PrepareLoadCommand(cmd, Message.LoadFilter.BY_TYPE, mappingType);
|
|
SqlDataReader reader = await PerformCommandAsync(cmd);
|
|
return (await vm.LoadListAsync(reader)).ConvertAll(x => (ValueMapping)x);
|
|
}
|
|
|
|
public static async Task<List<WASExemption>> LoadWASExemptionsAsync()
|
|
{
|
|
SqlCommand cmd = new SqlCommand();
|
|
WASExemption was = new WASExemption();
|
|
was.PrepareLoadCommand(cmd, Message.LoadFilter.ALL);
|
|
SqlDataReader reader = await PerformCommandAsync(cmd);
|
|
return (await was.LoadListAsync(reader)).ConvertAll(x => (WASExemption)x);
|
|
}
|
|
|
|
public static async Task<List<HAZPosTemplate>> LoadHAZTemplatesAsync()
|
|
{
|
|
SqlCommand cmd = new SqlCommand();
|
|
HAZPosTemplate hpt = new HAZPosTemplate();
|
|
hpt.PrepareLoadCommand(cmd, Message.LoadFilter.ALL);
|
|
SqlDataReader reader = await PerformCommandAsync(cmd);
|
|
return (await hpt.LoadListAsync(reader)).ConvertAll(x => (HAZPosTemplate)x);
|
|
}
|
|
|
|
public static async Task<List<PortArea>> LoadPortAreasAsync(bool forceReload = false)
|
|
{
|
|
await EnsurePortAreasLoadedAsync(forceReload);
|
|
return new List<PortArea>(_allPortAreaRows);
|
|
}
|
|
|
|
public static async Task<Dictionary<string, PortArea>> GetPortAreaDictAsync(bool forceReload = false)
|
|
{
|
|
await EnsurePortAreasLoadedAsync(forceReload);
|
|
return _allPortAreasByCode;
|
|
}
|
|
|
|
public static Dictionary<string, PortArea> GetPortAreaDict(bool forceReload = false)
|
|
{
|
|
return Task.Run(() => GetPortAreaDictAsync(forceReload)).GetAwaiter().GetResult();
|
|
}
|
|
|
|
public static void InvalidatePortAreaCache()
|
|
{
|
|
_allPortAreaRows = null;
|
|
_allPortAreasByCode = null;
|
|
}
|
|
|
|
public static async Task<List<LADG_NST2007>> LoadLADGNST2007Async(bool forceReload = false)
|
|
{
|
|
await EnsureLADGNST2007LoadedAsync(forceReload);
|
|
return new List<LADG_NST2007>(_allLADGNST2007Rows);
|
|
}
|
|
|
|
public static async Task<Dictionary<string, LADG_NST2007>> GetLADGNST2007DictAsync(bool forceReload = false)
|
|
{
|
|
await EnsureLADGNST2007LoadedAsync(forceReload);
|
|
return _allLADGNST2007ByDescription;
|
|
}
|
|
|
|
public static Dictionary<string, LADG_NST2007> GetLADGNST2007Dict(bool forceReload = false)
|
|
{
|
|
return Task.Run(() => GetLADGNST2007DictAsync(forceReload)).GetAwaiter().GetResult();
|
|
}
|
|
|
|
public static void InvalidateLADGNST2007Cache()
|
|
{
|
|
_allLADGNST2007Rows = null;
|
|
_allLADGNST2007ByDescription = null;
|
|
}
|
|
|
|
public static async Task<List<AGNT_Template>> GetAGNTTemplatesAsync()
|
|
{
|
|
SqlCommand cmd = new SqlCommand();
|
|
AGNT_Template at = new AGNT_Template();
|
|
at.PrepareLoadCommand(cmd, Message.LoadFilter.ALL);
|
|
SqlDataReader reader = await PerformCommandAsync(cmd);
|
|
return (await at.LoadListAsync(reader)).ConvertAll(x => (AGNT_Template)x);
|
|
}
|
|
|
|
public static async Task<List<SERV_Template>> GetSERVTemplatesAsync(bool forceReload = false)
|
|
{
|
|
await EnsureSERVTemplatesLoadedAsync(forceReload);
|
|
return new List<SERV_Template>(_allSERVTemplates);
|
|
}
|
|
|
|
public static void InvalidateSERVTemplatesCache()
|
|
{
|
|
_allSERVTemplates = null;
|
|
}
|
|
|
|
|
|
public static async Task<List<WasteDisposalServiceProvider_Template>> GetWasteDisposalServiceProviderTemplatesAsync()
|
|
{
|
|
SqlCommand cmd = new SqlCommand();
|
|
WasteDisposalServiceProvider_Template wdsp_t = new WasteDisposalServiceProvider_Template();
|
|
wdsp_t.PrepareLoadCommand(cmd, Message.LoadFilter.ALL);
|
|
SqlDataReader reader = await PerformCommandAsync(cmd);
|
|
return (await wdsp_t.LoadListAsync(reader)).ConvertAll(x => (WasteDisposalServiceProvider_Template)x);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region private helpers
|
|
|
|
private static async Task EnsurePortAreasLoadedAsync(bool forceReload)
|
|
{
|
|
if (forceReload)
|
|
InvalidatePortAreaCache();
|
|
|
|
if ((_allPortAreaRows != null) && (_allPortAreasByCode != null))
|
|
return;
|
|
|
|
await _portAreaLoadLock.WaitAsync();
|
|
try
|
|
{
|
|
if ((_allPortAreaRows != null) && (_allPortAreasByCode != null))
|
|
return;
|
|
|
|
SqlCommand cmd = new SqlCommand();
|
|
PortArea portArea = new PortArea();
|
|
portArea.PrepareLoadCommand(cmd, Message.LoadFilter.ALL);
|
|
SqlDataReader reader = await PerformCommandAsync(cmd);
|
|
|
|
List<PortArea> rows = new List<PortArea>();
|
|
if (reader != null)
|
|
{
|
|
foreach (DatabaseEntity entity in portArea.LoadList(reader))
|
|
{
|
|
if (entity is PortArea pa)
|
|
rows.Add(pa);
|
|
}
|
|
}
|
|
|
|
Dictionary<string, PortArea> byCode = new Dictionary<string, PortArea>(StringComparer.OrdinalIgnoreCase);
|
|
foreach (PortArea pa in rows)
|
|
{
|
|
if (!pa.Code.IsNullOrEmpty())
|
|
byCode[pa.Code] = pa;
|
|
}
|
|
|
|
_allPortAreaRows = rows;
|
|
_allPortAreasByCode = byCode;
|
|
}
|
|
finally
|
|
{
|
|
_portAreaLoadLock.Release();
|
|
}
|
|
}
|
|
|
|
private static async Task EnsureLADGNST2007LoadedAsync(bool forceReload)
|
|
{
|
|
if (forceReload)
|
|
InvalidateLADGNST2007Cache();
|
|
|
|
if ((_allLADGNST2007Rows != null) && (_allLADGNST2007ByDescription != null))
|
|
return;
|
|
|
|
await _ladgNst2007LoadLock.WaitAsync();
|
|
try
|
|
{
|
|
if ((_allLADGNST2007Rows != null) && (_allLADGNST2007ByDescription != null))
|
|
return;
|
|
|
|
SqlCommand cmd = new SqlCommand();
|
|
LADG_NST2007 item = new LADG_NST2007();
|
|
item.PrepareLoadCommand(cmd, Message.LoadFilter.ALL);
|
|
SqlDataReader reader = await PerformCommandAsync(cmd);
|
|
|
|
List<LADG_NST2007> rows = new List<LADG_NST2007>();
|
|
if (reader != null)
|
|
{
|
|
foreach (DatabaseEntity entity in item.LoadList(reader))
|
|
{
|
|
if (entity is LADG_NST2007 nst)
|
|
rows.Add(nst);
|
|
}
|
|
}
|
|
|
|
Dictionary<string, LADG_NST2007> byDescription = new Dictionary<string, LADG_NST2007>(StringComparer.OrdinalIgnoreCase);
|
|
foreach (LADG_NST2007 nst in rows)
|
|
{
|
|
if (!nst.Description.IsNullOrEmpty())
|
|
byDescription[nst.Description] = nst;
|
|
}
|
|
|
|
_allLADGNST2007Rows = rows;
|
|
_allLADGNST2007ByDescription = byDescription;
|
|
}
|
|
finally
|
|
{
|
|
_ladgNst2007LoadLock.Release();
|
|
}
|
|
}
|
|
|
|
private static async Task EnsureSERVTemplatesLoadedAsync(bool forceReload)
|
|
{
|
|
if (forceReload)
|
|
InvalidateSERVTemplatesCache();
|
|
|
|
if (_allSERVTemplates != null)
|
|
return;
|
|
|
|
await _servTemplateLoadLock.WaitAsync();
|
|
try
|
|
{
|
|
if (_allSERVTemplates != null)
|
|
return;
|
|
|
|
SqlCommand cmd = new SqlCommand();
|
|
SERV_Template st = new SERV_Template();
|
|
st.PrepareLoadCommand(cmd, Message.LoadFilter.ALL);
|
|
SqlDataReader reader = await PerformCommandAsync(cmd);
|
|
_allSERVTemplates = (await st.LoadListAsync(reader)).ConvertAll(x => (SERV_Template)x);
|
|
}
|
|
finally
|
|
{
|
|
_servTemplateLoadLock.Release();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region async DB access methods
|
|
|
|
internal static async Task<SqlDataReader> PerformCommandAsync(SqlCommand cmd)
|
|
{
|
|
SqlDataReader reader = null;
|
|
|
|
try
|
|
{
|
|
SqlConnection connection = new SqlConnection(ConnectionString);
|
|
await connection.OpenAsync();
|
|
cmd.Connection = connection;
|
|
reader = await cmd.ExecuteReaderAsync();
|
|
}
|
|
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 static async Task<int> PerformNonQueryAsync(SqlCommand cmd)
|
|
{
|
|
int result = -1;
|
|
// await _asyncSemaphore.WaitAsync();
|
|
try
|
|
{
|
|
using (SqlConnection connection = new SqlConnection(ConnectionString))
|
|
{
|
|
await connection.OpenAsync();
|
|
cmd.Connection = connection;
|
|
result = await cmd.ExecuteNonQueryAsync();
|
|
}
|
|
}
|
|
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 result;
|
|
}
|
|
|
|
internal static async Task<int?> PerformReadIntQueryAsync(SqlCommand cmd)
|
|
{
|
|
int? result = null;
|
|
|
|
try
|
|
{
|
|
using (SqlConnection connection = new SqlConnection(ConnectionString))
|
|
{
|
|
cmd.Connection = connection;
|
|
object r = await cmd.ExecuteScalarAsync();
|
|
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;
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
}
|