| | | 1 | | using System.Data; |
| | | 2 | | using System.Reflection; |
| | | 3 | | using System.Text.Json.Serialization; |
| | | 4 | | using Newtonsoft.Json; |
| | | 5 | | using Snacks.DAL.Common; |
| | | 6 | | public class QueryStore |
| | | 7 | | { |
| | 4 | 8 | | private static readonly Lazy<QueryStore> instance = new Lazy<QueryStore>(() => new QueryStore()); |
| | 2 | 9 | | private bool isInitialized = false; |
| | | 10 | | public static QueryStore Instance |
| | | 11 | | { |
| | | 12 | | get |
| | 344 | 13 | | { |
| | 344 | 14 | | if (!instance.Value.isInitialized) |
| | 2 | 15 | | { |
| | 2 | 16 | | instance.Value.InitMapper(); |
| | 2 | 17 | | } |
| | 344 | 18 | | return instance.Value; |
| | 344 | 19 | | } |
| | | 20 | | } |
| | | 21 | | |
| | 1224 | 22 | | public JRoot? Root { get; set; } |
| | | 23 | | |
| | | 24 | | public class JRoot |
| | | 25 | | { |
| | | 26 | | [JsonPropertyName("Entities")] |
| | 766 | 27 | | public Dictionary<string, JEntity>? Entities { get; set; } |
| | | 28 | | } |
| | | 29 | | |
| | | 30 | | public class JEntity |
| | | 31 | | { |
| | | 32 | | [JsonPropertyName("Queries")] |
| | 304 | 33 | | public List<JQuery>? Queries { get; set; } |
| | | 34 | | |
| | | 35 | | [JsonPropertyName("Mappings")] |
| | 72 | 36 | | public JMapping[]? Mappings { get; set; } |
| | | 37 | | |
| | 242 | 38 | | public Delegate? Mapper { get; set; } |
| | | 39 | | } |
| | | 40 | | public class JQuery |
| | | 41 | | { |
| | | 42 | | [JsonPropertyName("Name")] |
| | 790 | 43 | | public string? Name { get; set; } |
| | | 44 | | |
| | | 45 | | [JsonPropertyName("Parameters")] |
| | 574 | 46 | | public JParameter[]? Parameters { get; set; } |
| | | 47 | | |
| | | 48 | | [JsonPropertyName("Statement")] |
| | 822 | 49 | | public string? Statement { get; set; } |
| | | 50 | | |
| | | 51 | | [JsonPropertyName("Type")] |
| | 96 | 52 | | public string? Type { get; set; } |
| | | 53 | | } |
| | | 54 | | public class JParameter |
| | | 55 | | { |
| | | 56 | | [JsonPropertyName("Name")] |
| | 4296 | 57 | | public string? Name { get; set; } |
| | | 58 | | |
| | | 59 | | [JsonPropertyName("Type")] |
| | 334 | 60 | | public string? Type { get; set; } |
| | | 61 | | } |
| | | 62 | | public class JMapping |
| | | 63 | | { |
| | | 64 | | [JsonPropertyName("PropertyName")] |
| | 2018 | 65 | | public string? PropertyName { get; set; } |
| | | 66 | | |
| | | 67 | | [JsonPropertyName("FieldName")] |
| | 2970 | 68 | | public string? FieldName { get; set; } |
| | | 69 | | |
| | | 70 | | [JsonPropertyName("DataType")] |
| | 104 | 71 | | public string? DataType { get; set; } |
| | | 72 | | |
| | | 73 | | } |
| | | 74 | | |
| | 2 | 75 | | private QueryStore() |
| | 2 | 76 | | { |
| | 2 | 77 | | LoadQueries(); |
| | 2 | 78 | | } |
| | | 79 | | |
| | | 80 | | |
| | | 81 | | private void LoadQueries() |
| | 2 | 82 | | { |
| | 2 | 83 | | var assembly = Assembly.GetExecutingAssembly(); |
| | 2 | 84 | | var resourceName = "Snacks.DAL.Common.Queries.json"; |
| | | 85 | | |
| | 2 | 86 | | using (var stream = assembly.GetManifestResourceStream(resourceName)) |
| | 2 | 87 | | if (stream == null) |
| | 0 | 88 | | { |
| | 0 | 89 | | throw new InvalidOperationException($"Die Datei {resourceName} konnte nicht gefunden werden."); |
| | | 90 | | } |
| | | 91 | | else |
| | 2 | 92 | | { |
| | | 93 | | |
| | 2 | 94 | | using (var reader = new StreamReader(stream)) |
| | 2 | 95 | | { |
| | 2 | 96 | | string jsonContent = reader.ReadToEnd(); |
| | | 97 | | |
| | 2 | 98 | | Root = JsonConvert.DeserializeObject<JRoot>(jsonContent); |
| | 2 | 99 | | } |
| | 2 | 100 | | } |
| | 2 | 101 | | } |
| | | 102 | | |
| | | 103 | | private void InitMapper() |
| | 2 | 104 | | { |
| | 2 | 105 | | isInitialized = true; |
| | 2 | 106 | | if (Root?.Entities == null) |
| | 0 | 107 | | { |
| | 0 | 108 | | throw new InvalidOperationException("Die Entitäten konnten nicht geladen werden."); |
| | | 109 | | } |
| | | 110 | | else |
| | 2 | 111 | | { |
| | 54 | 112 | | foreach (var entity in Root.Entities) |
| | 24 | 113 | | { |
| | 24 | 114 | | var className = entity.Key.ToString(); |
| | 24 | 115 | | Assembly assembly = Assembly.Load("Snacks.Domain"); |
| | 24 | 116 | | var type = Type.GetType($"Snacks.Domain.Models.{className},{assembly}"); |
| | | 117 | | |
| | 24 | 118 | | if (type == null) |
| | 0 | 119 | | { |
| | 0 | 120 | | throw new InvalidOperationException($"Der Typ {className} konnte nicht gefunden werden."); |
| | | 121 | | } |
| | | 122 | | |
| | 24 | 123 | | object? instance = Activator.CreateInstance(type); |
| | 24 | 124 | | MethodInfo? mapperMethodGeneric = typeof(QueryStore).GetMethod("mapper"); |
| | 24 | 125 | | MethodInfo? mapperMethod = mapperMethodGeneric is null ? throw new InvalidOperationException($"Die Metho |
| | | 126 | | |
| | 24 | 127 | | var mappings = Root.Entities[className].Mappings; |
| | 24 | 128 | | var func = mappings is null ? throw new InvalidOperationException() : mapperMethod.Invoke(QueryStore.Ins |
| | 24 | 129 | | Root.Entities[className].Mapper = func is null ? throw new InvalidOperationException() : (Delegate)func; |
| | 24 | 130 | | } |
| | 2 | 131 | | } |
| | 2 | 132 | | } |
| | | 133 | | public RowMapper<T> mapper<T>(JMapping[] mappings) |
| | 24 | 134 | | { |
| | 24 | 135 | | return (IDataRecord row) => |
| | 204 | 136 | | { |
| | 204 | 137 | | T instance = Activator.CreateInstance<T>(); |
| | 2520 | 138 | | foreach (var map in mappings) |
| | 954 | 139 | | { |
| | 954 | 140 | | if (map.PropertyName is null || map.FieldName is null) |
| | 0 | 141 | | { |
| | 0 | 142 | | throw new InvalidOperationException("Die Mappings konnten nicht geladen werden."); |
| | 24 | 143 | | } |
| | 954 | 144 | | var propertyInfo = typeof(T).GetProperty(map.PropertyName); |
| | 954 | 145 | | if (propertyInfo != null && row[map.FieldName] != DBNull.Value) |
| | 952 | 146 | | { |
| | 952 | 147 | | propertyInfo.SetValue(instance, Convert.ChangeType(row[map.FieldName], propertyInfo.PropertyType)); |
| | 952 | 148 | | } |
| | 954 | 149 | | } |
| | 24 | 150 | | |
| | 204 | 151 | | return instance; |
| | 228 | 152 | | }; |
| | 24 | 153 | | } |
| | | 154 | | } |