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