185 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using Datamodels.DatabaseModels;
 | |
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Threading.Tasks;
 | |
| using Microsoft.Extensions.Logging;
 | |
| using Repositories.Interfaces;
 | |
| using Datamodels.BusinessModels;
 | |
| using Datamodels.SearchModels;
 | |
| using Newtonsoft.Json;
 | |
| using System.Linq;
 | |
| using System.Linq.Expressions;
 | |
| using SearchApi.Exceptions;
 | |
| using Datamodels.Enums;
 | |
| 
 | |
| namespace SearchApi.SearchLogic
 | |
| {
 | |
|     public class SearchLogic : ISearchLogic
 | |
|     {
 | |
|         private readonly ILogger<SearchLogic> _logger;
 | |
|         private readonly IFwMariaSearchRepo _searchRepo;
 | |
| 
 | |
|         private List<string> _tableNames = new List<string>();
 | |
|         private List<string> _joinConditions = new List<string>();
 | |
|         private List<string> _fieldNames = new List<string>();
 | |
|         private List<string> _whereConditions = new List<string>();
 | |
|         private List<string> _sortFields = new List<string>();
 | |
|         
 | |
|         public SearchLogic(ILogger<SearchLogic> logger, IFwMariaSearchRepo searchRepo)
 | |
|         {
 | |
|             _logger = logger;
 | |
|             _searchRepo = searchRepo;
 | |
|         }
 | |
| 
 | |
|         public async Task<DataResult<List<Address>>> GetAllAddresses()
 | |
|         {
 | |
|             var result = await _searchRepo.GetAllAddresses();
 | |
|             return result;
 | |
|         }
 | |
| 
 | |
|         public async Task<DataResult<ResultModel>> GetFilteredData(FilterModel filter, long skip = 0, long take = -1)
 | |
|         {
 | |
|             var result = new DataResult<ResultModel>();
 | |
|             result.Data = new ResultModel();
 | |
|             result.Data.SearchModel = filter;
 | |
|             var sql = await Task.Run(() => { return AssembleSqlQuery(filter); } );
 | |
|             return result;
 | |
|         }
 | |
| 
 | |
|         // Extract Table
 | |
|         private void GetTables(FilterModel filter)
 | |
|         {
 | |
|             bool hasTableList = filter.TableDescriptions.Count > 0;
 | |
|             _tableNames = new List<string>();
 | |
|             foreach(var table in filter.TableDescriptions)
 | |
|             {
 | |
|                 if (hasTableList && string.IsNullOrEmpty(table.TableAlias))
 | |
|                 {
 | |
|                     throw new TableAliasMissingException($"No Alias defined for Table {table.TableName}");
 | |
|                 }
 | |
|                 _tableNames.Add($"{table.TableName} {(string.IsNullOrEmpty(table.TableAlias) ? string.Empty : table.TableAlias)}");
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // Extract Fieldlist
 | |
|         private void GetFields(FilterModel filter)
 | |
|         {
 | |
|             var tables = filter.TableDescriptions;
 | |
|             foreach (var table in tables)
 | |
|             {
 | |
|                 bool hasMultipleFields = table.Fields.Count > 0;
 | |
|                 foreach (var field in table.Fields) {
 | |
|                     if (hasMultipleFields && string.IsNullOrEmpty(field.FieldAlias))
 | |
|                     {
 | |
|                         throw new FieldAliasMissingException($"No Alias defined for Field {field.FieldName} in Table {table.TableName}");
 | |
|                     }
 | |
|                     _fieldNames.Add($"{table.TableAlias}.{field.FieldName} {field.FieldAlias}");
 | |
| 
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // Extract Join Path if more than one table
 | |
|         private void GetTableJoinConditions(FilterModel filter)
 | |
|         {
 | |
| 
 | |
|         }
 | |
| 
 | |
|         // Extract Where Conditions
 | |
|         // ToDo: wenn es mehrere Values gibt, werden die generell mit OR verknüpft? Oder nehmen wir lieber AND?
 | |
|         private void GetWhereConditions(string tableName, FieldModel field)
 | |
|         {
 | |
|             if (field.SearchDescriptions.Count > 0)
 | |
|             {
 | |
|                 foreach (var condition in field.SearchDescriptions)
 | |
|                 {
 | |
|                     var op = Operator(condition.SearchData.PhraseOperator);
 | |
|                     if (op != "NOTHING")
 | |
|                     {
 | |
|                         var usedField = $"{tableName}.{field.FieldName}{op}{condition.SearchData.Values[0]}";
 | |
|                         _whereConditions.Add(usedField);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (condition.SearchData.PhraseOperator == PhraseOperators.Contains)
 | |
|                         {
 | |
|                             var usedField = $"{tableName}.{field.FieldName} like '%{condition.SearchData.Values[0]}%'";
 | |
|                             _whereConditions.Add(usedField);
 | |
|                         }
 | |
|                         if (condition.SearchData.PhraseOperator == PhraseOperators.StartsWith)
 | |
|                         {
 | |
|                             var usedField = $"{tableName}.{field.FieldName} like '%{condition.SearchData.Values[0]}'";
 | |
|                             _whereConditions.Add(usedField);
 | |
|                         }
 | |
|                         if (condition.SearchData.PhraseOperator == PhraseOperators.EndsWith)
 | |
|                         {
 | |
|                             var usedField = $"{tableName}.{field.FieldName} like '{condition.SearchData.Values[0]} + %'";
 | |
|                             _whereConditions.Add(usedField);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|         }
 | |
| 
 | |
|         public string Operator(PhraseOperators ops)
 | |
|         {
 | |
|             switch (ops)
 | |
|             {
 | |
|                 case PhraseOperators.Equal:
 | |
|                     return "=";
 | |
|                 case PhraseOperators.NotEqual:
 | |
|                     return "!=";
 | |
|                 case PhraseOperators.GreaterThan:
 | |
|                     return ">";
 | |
|                 case PhraseOperators.GreaterThanOrEqual:
 | |
|                     return ">=";
 | |
|                 case PhraseOperators.LowerThan:
 | |
|                     return "<";
 | |
|                 case PhraseOperators.LowerThanOrEqual:
 | |
|                     return "<=";
 | |
|                 default:
 | |
|                     return "NOTHING";
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // Extract Sort Items
 | |
|         private void GetSortFields(FilterModel filter)
 | |
|         {
 | |
| 
 | |
|         }
 | |
| 
 | |
|         // Assemble SQL Query
 | |
|         private string AssembleSqlQuery(FilterModel filter)
 | |
|         {
 | |
|             GetTables(filter);
 | |
|             GetFields(filter);
 | |
|             var result = BuildSql();
 | |
|             return result;
 | |
|         }
 | |
| 
 | |
|         //Build SQL String itself
 | |
|         private string BuildSql()
 | |
|         {
 | |
|             var sql = "SELECT ";
 | |
|             foreach (var field in _fieldNames)
 | |
|             {
 | |
|                 sql += field.ToUpper();
 | |
|                 if (_fieldNames.IndexOf(field) < _fieldNames.Count - 1) sql += ",";
 | |
|             }
 | |
| 
 | |
|             sql += " FROM ";
 | |
|             foreach (var table in _tableNames)
 | |
|             {
 | |
|                 sql += table.ToUpper();
 | |
|                 if (_tableNames.IndexOf(table) < _tableNames.Count - 1)
 | |
|                 {
 | |
|                     sql += ",";
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return sql;
 | |
|         }
 | |
|     }
 | |
| }
 |