Files
TxSearchApi/BusinessLogic/SearchLogic/SearchLogic.cs
2021-11-26 10:00:58 +01:00

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;
}
}
}