git_bsmd/bsmd.database/ValueMapping.cs

212 lines
6.9 KiB
C#

// Copyright (c) 2023-present schick Informatik
// Description: Container class for self-learning, volatile information that
// is added by parsing Excel sheets. Here common wrong/misspelled data fields
// are mapped to valid ones.
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bsmd.database
{
public class ValueMapping : DatabaseEntityAsync
{
#region Construction
public ValueMapping()
{
this.tablename = "[dbo].[ValueMapping]";
}
#endregion
#region enums
public enum MappingType
{
COUNTRY,
GENDER,
DOCUMENT_TYPE,
LOCODE
}
#endregion
#region Fields
private static Dictionary<MappingType, Dictionary<string, ValueMapping>> _dicts;
private static Dictionary<MappingType, List<string>> _invalidKeys;
#endregion
#region Properties
public static Dictionary<MappingType, Dictionary<string, ValueMapping>> Dicts
{
get
{
if (_dicts == null)
{
_dicts = new Dictionary<MappingType, Dictionary<string, ValueMapping>>();
foreach (MappingType type in Enum.GetValues(typeof(MappingType)))
_dicts[type] = new Dictionary<string, ValueMapping>();
}
return _dicts;
}
}
public static Dictionary<MappingType, List<string>> InvalidKeys
{
get
{
if (_invalidKeys == null)
{
_invalidKeys = new Dictionary<MappingType, List<string>>();
// get the keys initialized that cannot be assigned
foreach (MappingType type in Enum.GetValues(typeof(MappingType)))
_invalidKeys[type] = new List<string>();
_invalidKeys[MappingType.COUNTRY].Add("UK"); // can be mapped to GB and to UA .. we don't know what they want
}
return _invalidKeys;
}
}
public MappingType EntryType { get; private set; }
public string Key { get; set; }
public string Value { get; set; }
public DateTime? Created { get; private set; }
public DateTime? Changed { get; private set; }
#endregion
#region public funcs
/// <summary>
/// creates and saves a new entry and adds it to the internal dictionaries
/// </summary>
/// <returns>true if entry was actually created, false if already present</returns>
public static async Task<bool> Create(MappingType type, string key, string value)
{
if (!Dicts[type].ContainsKey(key))
{
ValueMapping vm = new ValueMapping()
{
EntryType = type,
Key = key,
Value = value
};
Dicts[type][key] = vm;
return await DBManagerAsync.SaveAsync(vm) == 1;
}
return false;
}
/// <summary>
/// deletes an entry and removes it from the database
/// </summary>
/// <returns>true if successful, false if value was not found</returns>
public static async Task<bool> Delete(MappingType type, string key)
{
if (!Dicts.ContainsKey(type)) return false;
if (!Dicts[type].ContainsKey(key)) return false;
ValueMapping vm = Dicts[type][key];
Dicts[type].Remove(key);
return await DBManagerAsync.DeleteAsync(vm) == 1;
}
/// <summary>
/// updates an existing value and saves it
/// </summary>
/// <returns>true if successful</returns>
public async Task<bool> Update(string newValue)
{
this.Value = newValue;
return await DBManagerAsync.SaveAsync(this) == 1;
}
/// <summary>
/// (re-)loads all value mapping dictionaries
/// </summary>
public static async void LoadDicts()
{
foreach(MappingType type in Enum.GetValues(typeof(MappingType)))
{
Dicts[type].Clear();
List<ValueMapping> mappings = await DBManagerAsync.LoadValuesForType(type);
foreach (ValueMapping mapping in mappings)
Dicts[type][mapping.Key] = mapping;
}
}
#endregion
#region DatabaseEntity implementation
public override void PrepareSave(System.Data.IDbCommand cmd)
{
SqlCommand scmd = cmd as SqlCommand;
scmd.Parameters.AddWithValue("@TYPE", this.EntryType);
scmd.Parameters.AddWithNullableValue("@KEY", this.Key);
scmd.Parameters.AddWithNullableValue("@VALUE", this.Value);
if(this.IsNew)
{
this.CreateId();
scmd.Parameters.AddWithValue("@ID", this.Id);
scmd.CommandText = $"INSERT INTO {Tablename} (Id, EntryType, MappingKey, MappingValue) VALUES (@ID, @TYPE, @KEY, @VALUE)";
}
else
{
scmd.Parameters.AddWithValue("@ID", this.Id);
scmd.CommandText = $"UPDATE {Tablename} SET EntryType = @TYPE, MappingKey = @KEY, MappingValue = @VALUE WHERE Id = @ID";
}
}
public override void PrepareLoadCommand(System.Data.IDbCommand cmd, Message.LoadFilter filter, params object[] criteria)
{
string query = $"SELECT Id, EntryType, MappingKey, MappingValue, Created, Changed FROM {Tablename}";
switch (filter)
{
case Message.LoadFilter.BY_TYPE:
query += " WHERE EntryType = @TYPE";
((SqlCommand)cmd).Parameters.AddWithValue("@TYPE", criteria[0]);
break;
default:
break;
}
query += " ORDER BY MappingKey";
cmd.CommandText = query;
}
protected override DatabaseEntityAsync ReadRowFromReader(System.Data.IDataReader reader)
{
ValueMapping vm = null;
if (reader != null)
{
vm = new ValueMapping();
vm.id = reader.GetGuid(0);
if (!reader.IsDBNull(1)) vm.EntryType = (ValueMapping.MappingType)reader.GetByte(1);
if (!reader.IsDBNull(2)) vm.Key = reader.GetString(2);
if (!reader.IsDBNull(3)) vm.Value = reader.GetString(3);
if (!reader.IsDBNull(4)) vm.Created = reader.GetDateTime(4);
if (!reader.IsDBNull(5)) vm.Changed = reader.GetDateTime(5);
}
return vm;
}
#endregion
}
}