first things

This commit is contained in:
Roland Fieger
2021-09-22 12:37:40 +02:00
parent 074df0adec
commit 5e15db793b
53 changed files with 2065 additions and 229 deletions

26
.dockerignore Normal file
View File

@@ -0,0 +1,26 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
**/helmvalues

251
.gitignore vendored
View File

@@ -1,45 +1,7 @@
# ---> C++
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
# ---> VisualStudio
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
@@ -48,9 +10,6 @@
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
@@ -58,62 +17,41 @@ mono_crash.*
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
# NUNIT
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*_i.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
@@ -123,15 +61,15 @@ StyleCopReport.xml
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
*.log
*.log*
# Chutzpah Test files
_Chutzpah*
@@ -153,9 +91,6 @@ ipch/
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
@@ -167,25 +102,15 @@ _ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
@@ -217,7 +142,7 @@ publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
@@ -229,21 +154,16 @@ PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
**/packages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Nuget personal access tokens and Credentials
nuget.config
# Microsoft Azure Build Output
csx/
*.build.csdef
@@ -257,15 +177,12 @@ AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
!*.[Cc]ache/
# Others
ClientBin/
@@ -273,15 +190,11 @@ ClientBin/
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
@@ -296,22 +209,15 @@ _UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
@@ -321,7 +227,6 @@ FakesAssemblies/
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
@@ -329,9 +234,6 @@ node_modules/
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
@@ -347,120 +249,15 @@ paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
.idea/
*.sln.iml
/LiPoUploadService/Resources/Uploads
/package-lock.json
LiPoValidationService/mono_crash.21acb2abea.0.json
# ---> VisualStudioCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# ---> MonoDevelop
#User Specific
*.userprefs
*.usertasks
#Mono Project Files
*.pidb
*.resources
test-results/
# ---> MicrosoftOffice
*.tmp
# Word temporary
~$*.doc*
# Word Auto Backup File
Backup of *.doc*
# Excel temporary
~$*.xls*
# Excel Backup File
*.xlk
# PowerPoint temporary
~$*.ppt*
# Visio autosave temporary files
*.~vsd*
UploadRepository/mono_crash.21acb2abea.0.json
UploadRepository/mono_crash.21acb2abea.1.json
LiPoUploadStagingService/appsettings.Development.json
LiPoTaskService/appsettings.Development.json
LiPoTaskService/mono_crash.21acb2ae56.0.json

View File

@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using BusinessLogic.LookupLogic.Interfaces;
using Datamodels.Lookups;
using Datamodels.BusinessModels;
using Repositories.Interfaces;
namespace BusinessLogic.LookupLogic
{
public class FwLookupLogic: ILookupLogic
{
private readonly IConfiguration _configuration;
private readonly ILogger<FwLookupLogic> _logger;
private readonly IFwMariaLookupRepo _lookupRepo;
public FwLookupLogic(ILogger<FwLookupLogic> logger, IConfiguration configuration, IFwMariaLookupRepo lookupRepo)
{
_logger = logger;
_configuration = configuration;
_lookupRepo = lookupRepo;
}
public async Task<DataResult<List<LookupCategory>>> GetAllLookups()
{
var result = await _lookupRepo.GetAllLookups();
return result;
}
public async Task<DataResult<LookupCategory>> GetLookupCategoryById(long id)
{
var result = await _lookupRepo.GetLookupCategoryById(id);
return result;
}
public async Task<DataResult<List<LookupCategory>>> GetLookupCategoryByName(string categoryName)
{
var result = await _lookupRepo.GetLookupCategoryByName(categoryName);
return result;
}
public async Task<DataResult<List<LookupCategory>>> GetActiveLookupCategories()
{
var result = await _lookupRepo.GetActiveLookupCategories();
return result;
}
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Datamodels.Lookups;
using Datamodels.BusinessModels;
namespace BusinessLogic.LookupLogic.Interfaces
{
public interface ILookupLogic
{
Task<DataResult<List<LookupCategory>>> GetAllLookups();
Task<DataResult<LookupCategory>> GetLookupCategoryById(long id);
Task<DataResult<List<LookupCategory>>> GetLookupCategoryByName(string categoryName);
Task<DataResult<List<LookupCategory>>> GetActiveLookupCategories();
}
}

View File

@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.16" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.16" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Datamodels\Datamodels.csproj" />
<ProjectReference Include="..\..\Repositories\Repositories.csproj" />
</ItemGroup>
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Datamodels.BusinessModels;
using Datamodels.DatabaseModels;
using Datamodels.SearchModels;
namespace SearchLogic
{
public interface ISearchLogic
{
Task<DataResult<List<Address>>> GetAllAddresses();
Task<DataResult<ResultModel>> GetFilteredData(FilterModel filter, long skip = 0, long take = -1);
}
}

View File

@@ -0,0 +1,41 @@
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;
namespace SearchLogic
{
public class SearchLogic : ISearchLogic
{
private readonly ILogger<SearchLogic> _logger;
private readonly IFwMariaSearchRepo _searchRepo;
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;
return result;
}
}
}

View File

@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Datamodels\Datamodels.csproj" />
<ProjectReference Include="..\..\Repositories\Repositories.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Datamodels.BusinessModels
{
public enum GeneralResults
{
Success = 0,
DatabaseError = 1,
GeneralError = 2,
LogicWarning = 3,
Created = 4,
Updated = 5,
Deleted = 6
}
public class ResultObject
{
public GeneralResults GeneralResult { get; set; } = GeneralResults.Success;
public string UserMessage { get; set; }
public string ServerMessage { get; set; }
public string StackTrace { get; set; }
}
public class DataResult<T> : ResultObject
{
public T Data { get; set; }
public long TotalCount { get; set; }
public long Skip { get; set; }
public long Take { get; set; }
public TimeSpan Duration { get; set; }
}
}

View File

@@ -0,0 +1,17 @@
namespace Datamodels.BusinessModels
{
public enum SortDirections
{
Ascending,
Descending
}
public sealed class SortModel
{
public int SortFieldOrder { get; set; }
public string SortFieldName { get; set; }
public SortDirections SortDirection { get; set; } = SortDirections.Ascending;
}
}

View File

@@ -0,0 +1,18 @@
using System;
using Datamodels.Lookups;
namespace Datamodels.DatabaseModels
{
public class Address: IEntityClass
{
public long Id { get; set; }
public string StreetName { get; set; }
public int StreetNumber { get; set; }
public string Zip { get; set; }
public string City { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime ChangedAt { get; set; }
public LookupValue AddressType { get; set; } //something like "Job" or "Private"
public Person Person { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using System;
using Datamodels.Lookups;
namespace Datamodels.DatabaseModels
{
public class Communication
{
public long Id { get; set; }
public string CommunicationValue { get; set; } //mobile phone, home phone, job mail, etc.
public LookupValue CommunicationType { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime ChangedAt { get; set; }
public Person Person { get; set; }
}
}

View File

@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Datamodels.DatabaseModels
{
public interface IEntityClass
{
}
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using Datamodels.Lookups;
namespace Datamodels.DatabaseModels
{
public class Person
{
public long Id { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public DateTime? Birthday { get; set; }
public bool IsActive { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime ChangedAt { get; set; }
public LookupValue Gender { get; set; }
public List<Address> Addresses { get; set; }
public List<Communication> Communications { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Datamodels.Enums
{
public enum FieldTypes
{
String,
Integer,
Double,
Boolean,
DateTime,
Currency,
Blob
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Datamodels.Enums
{
public enum JoinTypes
{
And,
Or
}
}

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Datamodels.Enums
{
public enum PhraseOperators
{
Equal,
NotEqual,
LowerThan,
LowerThanOrEqual,
GreaterThan,
GreaterThanOrEqual,
StartsWith,
Contains,
EndsWith
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Datamodels.Enums
{
public enum SearchTypes
{
Phrase,
Range,
Terms
}
}

View File

@@ -0,0 +1,12 @@
using System.Collections.Generic;
namespace Datamodels.Lookups
{
public sealed class LookupCategory
{
public long Id { get; set; }
public string CategoryName { get; set; }
public bool IsActive { get; set; } = true;
public List<LookupValue> LookupValues { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
using Newtonsoft.Json;
namespace Datamodels.Lookups
{
public sealed class LookupValue {
public long Id { get; set; }
public string Value { get; set; }
public bool IsActive { get; set; } = true;
[JsonIgnore]
public LookupCategory LookupCategory { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using Datamodels.Enums;
using System;
using System.Collections.Generic;
namespace Datamodels.SearchModels
{
public sealed class FieldModel
{
public string FieldName { get; set; }
public string FieldAlias { get; set; }
public FieldTypes FieldType { get; set; }
public List<SearchDescription> SearchDescriptions { get; set; }
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Datamodels.SearchModels
{
public class FilterModel
{
public List<TableModel> TableDescriptions { get; set; }
public long Skip { get; set; }
public long Take { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Datamodels.SearchModels
{
public class ResultDataModel
{
public List<ResultRowModel> ResultRows { get; set; }
}
}

View File

@@ -0,0 +1,21 @@
using Datamodels.Enums;
using System;
using System.Collections.Generic;
using System.Text;
namespace Datamodels.SearchModels
{
/// <summary>
/// Field base query Result
/// </summary>
public class ResultFieldModel
{
public FieldTypes FieldType { get; set; }
public string FieldContent { get; set; }
public int FieldContentInt { get; set; }
public DateTime FieldContentDate { get; set; }
public Decimal FieldContentDecimal { get; set; }
public float FieldContentFloat { get; set; }
public string FieldContentString { get; set; }
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Datamodels.SearchModels
{
public class ResultModel
{
public FilterModel SearchModel { get; set; }
public ResultDataModel ResultData { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Datamodels.SearchModels
{
public class ResultRowModel
{
public List<ResultFieldModel> RowFields { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using Datamodels.Enums;
using System;
using System.Collections.Generic;
using System.Text;
namespace Datamodels.SearchModels
{
public class SearchDescription
{
public SearchObject SearchData { get; set; }
public JoinTypes JoinType { get; set; }
}
}

View File

@@ -0,0 +1,17 @@
using Datamodels.Enums;
using System;
using System.Collections.Generic;
using System.Text;
namespace Datamodels.SearchModels
{
public class SearchObject
{
public List<string> Values { get; set; }
public SearchTypes SearchType { get; set; }
public PhraseOperators PhraseOperator { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
namespace Datamodels.SearchModels
{
public sealed class TableModel
{
public string TableName { get; set; }
public string TableAlias { get; set; }
public List<FieldModel> Fields { get; set; } = new List<FieldModel>();
}
}

View File

@@ -1,2 +0,0 @@
# TxSearchApi

View File

@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using Datamodels.Lookups;
using Datamodels.DatabaseModels;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
namespace Repositories
{
public class FwDbContext: DbContext
{
public string _connectionString { get; set; } = "SERVER=127.0.0.1;DATABASE=testdb;PORT=3306;USER=root;PASSWORD=example";
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseMySql(_connectionString);
}
public DbSet<LookupCategory> LookupCategories { get; set; }
public DbSet<LookupValue> LookupValues { get; set; }
public DbSet<Address> Address { get; set; }
public DbSet<Person> Person { get; set; }
public DbSet<Communication> Communication { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<LookupValue>()
.HasKey(x => x.Id);
modelBuilder.Entity<LookupValue>()
.Property(x => x.Id).ValueGeneratedOnAdd();
modelBuilder.Entity<LookupCategory>()
.HasKey(x => x.Id);
modelBuilder.Entity<LookupCategory>()
.Property(x => x.Id).ValueGeneratedOnAdd();
modelBuilder.Entity<LookupCategory>()
.HasMany(x => x.LookupValues)
.WithOne(y => y.LookupCategory);
modelBuilder.Entity<Person>()
.Property(x => x.Id).ValueGeneratedOnAdd();
modelBuilder.Entity<Person>()
.HasKey(x => x.Id);
modelBuilder.Entity<Person>()
.HasMany(x => x.Communications)
.WithOne(y => y.Person);
modelBuilder.Entity<Person>()
.HasMany(x => x.Addresses)
.WithOne(y => y.Person);
modelBuilder.Entity<Address>()
.Property(x => x.Id).ValueGeneratedOnAdd();
modelBuilder.Entity<Address>()
.HasKey(x => x.Id);
modelBuilder.Entity<Communication>()
.Property(x => x.Id).ValueGeneratedOnAdd();
modelBuilder.Entity<Communication>()
.HasKey(x => x.Id);
}
}
}

View File

@@ -0,0 +1,147 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using Datamodels.BusinessModels;
using Datamodels.Lookups;
using Repositories.Interfaces;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;
namespace Repositories
{
public class FwMariaLookupRepo: IFwMariaLookupRepo
{
private readonly FwDbContext _dbContext = new FwDbContext();
private readonly ILogger<FwMariaLookupRepo> _logger;
private readonly IConfiguration _configuration;
public FwMariaLookupRepo(ILogger<FwMariaLookupRepo> logger, IConfiguration configuration)
{
_logger = logger;
_configuration = configuration;
try
{
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development")
{
_dbContext._connectionString = "SERVER=127.0.0.1;DATABASE=testdb;PORT=3306;USER=root;PASSWORD=example";
}
else
{
string usedDb = configuration.GetSection("GeneralSettings").GetSection("DbToUse").Get<string>();
string connectionString = configuration.GetConnectionString(usedDb);
_dbContext._connectionString = connectionString;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Database Connection Configuration not valid");
}
}
public async Task<DataResult<List<LookupCategory>>> GetAllLookups()
{
var result = await Task.Run(() =>
{
try
{
var newList = _dbContext.LookupCategories.Include(vals => vals.LookupValues).OrderBy(o => o.CategoryName).ToList();
return new DataResult<List<LookupCategory>> { Data = newList };
}
catch (Exception ex)
{
_logger.LogError(ex, "Error reading Lookup Data");
return new DataResult<List<LookupCategory>>
{
UserMessage = "Daten f<>r Lookups konnten nicht gelesen werden.",
ServerMessage = ex.Message,
GeneralResult = GeneralResults.DatabaseError,
StackTrace = ex.StackTrace
};
}
});
return result;
}
public async Task<DataResult<LookupCategory>> GetLookupCategoryById(long id)
{
var result = await Task.Run(() =>
{
try
{
var cat = _dbContext.LookupCategories.Where(x => x.Id == id).Include(vals => vals.LookupValues).FirstOrDefault();
return new DataResult<LookupCategory> { Data = cat };
}
catch (Exception ex)
{
_logger.LogError(ex, $"Error reading Lookup Category with Id: {id}");
return new DataResult<LookupCategory>
{
UserMessage = $"Daten f<>r Lookup Kategorie mit Id {id} konnten nicht gelesen werden.",
ServerMessage = ex.Message,
GeneralResult = GeneralResults.DatabaseError,
StackTrace = ex.StackTrace
};
}
});
return result;
}
public async Task<DataResult<List<LookupCategory>>> GetLookupCategoryByName(string categoryName)
{
var result = await Task.Run(() =>
{
try
{
var cat = _dbContext.LookupCategories.Where(x => x.CategoryName.ToUpper().Contains(categoryName.ToUpper())).Include(vals => vals.LookupValues).ToList();
return new DataResult<List<LookupCategory>> { Data = cat };
}
catch (Exception ex)
{
_logger.LogError(ex, $"Error reading Lookup Category with Name: {categoryName}");
return new DataResult<List<LookupCategory>>
{
UserMessage = $"Daten f<>r Lookup Kategorie mit Namen {categoryName} konnten nicht gelesen werden.",
ServerMessage = ex.Message,
GeneralResult = GeneralResults.DatabaseError,
StackTrace = ex.StackTrace
};
}
});
return result;
}
public async Task<DataResult<List<LookupCategory>>> GetActiveLookupCategories()
{
var result = await Task.Run(() =>
{
try
{
var catList = _dbContext.LookupCategories.Where(x => x.IsActive).Include(vals => vals.LookupValues).OrderBy(o => o.CategoryName).ToList();
return new DataResult<List<LookupCategory>> { Data = catList };
}
catch (Exception ex)
{
_logger.LogError(ex, "Error reading active Lookup Data");
return new DataResult<List<LookupCategory>>
{
UserMessage = "Daten f<>r aktive Lookups konnten nicht gelesen werden.",
ServerMessage = ex.Message,
GeneralResult = GeneralResults.DatabaseError,
StackTrace = ex.StackTrace
};
}
});
return result;
}
public void DeleteAllCategories()
{
_dbContext.Database.ExecuteSqlRaw("delete from LookupValues");
_dbContext.Database.ExecuteSqlRaw("delete from LookupCategories");
}
}
}

View File

@@ -0,0 +1,94 @@
using Datamodels.BusinessModels;
using Datamodels.DatabaseModels;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Repositories.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Datamodels.SearchModels;
using System.Linq.Expressions;
using System.Diagnostics;
namespace Repositories
{
public class FwMariaSearchRepo : IFwMariaSearchRepo
{
private readonly FwDbContext _dbContext = new FwDbContext();
private readonly ILogger<FwMariaSearchRepo> _logger;
private readonly IConfiguration _configuration;
public FwMariaSearchRepo(ILogger<FwMariaSearchRepo> logger, IConfiguration configuration)
{
_logger = logger;
_configuration = configuration;
try
{
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development")
{
_dbContext._connectionString = "SERVER=127.0.0.1;DATABASE=testdb;PORT=3306;USER=root;PASSWORD=example";
}
else
{
string usedDb = configuration.GetSection("GeneralSettings").GetSection("DbToUse").Get<string>();
string connectionString = configuration.GetConnectionString(usedDb);
_dbContext._connectionString = connectionString;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Database Connection Configuration not valid");
}
}
public async Task<DataResult<List<Address>>> GetAllAddresses()
{
try
{
var result = await _dbContext.Address.Where(x => x.City == "Augsburg" || x.City == "München").Where(y => y.StreetName.Contains("bruck")).ToListAsync().ConfigureAwait(false);
return new DataResult<List<Address>> { Data = result };
}
catch (Exception ex)
{
return new DataResult<List<Address>>
{
GeneralResult = GeneralResults.DatabaseError,
UserMessage = "Fehler beim Laden der Adressen",
ServerMessage = ex.Message
};
}
}
public Task<object> GetAllSortedData(TableModel queryFieldDef, List<SortModel> sortModel)
{
throw new NotImplementedException();
}
public Task<string> GetBlobData(string tableName, string fieldName, long id)
{
throw new NotImplementedException();
}
public Task<object> GetDataFilteredAndSorted(List<FilterModel> filter, List<SortModel> sortModel, long skip = 0, long take = -1)
{
throw new NotImplementedException();
}
public async Task<DataResult<List<IEntityClass>>> GetFilteredData<T>(List<Expression> expressions, long skip = 0, long take = -1) where T : IEntityClass
{
throw new NotImplementedException();
}
}
public class FilterLinq<T>
{
public static Expression<Func<T, Boolean>> GetWherePredicate(string whereFieldList, string whereFieldValues)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Datamodels.BusinessModels;
using Datamodels.Lookups;
namespace Repositories.Interfaces
{
public interface IFwMariaLookupRepo
{
Task<DataResult<List<LookupCategory>>> GetAllLookups();
Task<DataResult<LookupCategory>> GetLookupCategoryById(long id);
Task<DataResult<List<LookupCategory>>> GetLookupCategoryByName(string categoryName);
Task<DataResult<List<LookupCategory>>> GetActiveLookupCategories();
}
}

View File

@@ -0,0 +1,53 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using System;
using Datamodels.BusinessModels;
using Datamodels.DatabaseModels;
using Datamodels.SearchModels;
using System.Linq.Expressions;
namespace Repositories.Interfaces
{
public interface IFwMariaSearchRepo
{
Task<DataResult<List<Address>>> GetAllAddresses();
/// <summary>
/// Get Filtered Data from DB Provider without sorting
/// </summary>
/// <param name="filter">Object describing filters</param>
/// <param name="skip">From row</param>
/// <param name="take">To Row (-1 for all rows)</param>
/// <param name="queryFieldDef">Table- and FieldDefinitions to load from</param>
/// <returns>Result Object with Result information and list of DataObjects</returns>
Task<DataResult<List<IEntityClass>>> GetFilteredData<T> (List<Expression> expressions, long skip = 0, long take = -1) where T: IEntityClass;
/// <summary>
/// Get all Data from query field definition sorted by sortModel
/// </summary>
/// <param name="queryFieldDef">Table and Field Descriptions to Query from</param>
/// <param name="sortModel">Sorting Definitions</param>
/// <returns>Result Object with Result information and list of DataObjects</returns>
Task<object> GetAllSortedData (TableModel queryFieldDef, List<SortModel> sortModel);
/// <summary>
/// Get filtered and sorted DB Provider with given range of records
/// </summary>
/// <param name="queryFieldDef">Table- and Field Description to Query from</param>
/// <param name="filter">Object describing filter</param>
/// <param name="sortModel">Sorting Definitions</param>
/// <param name="skip">From Row</param>
/// <param name="take">To Row (-1) for all rows</param>
/// <returns>Result Object with Result information and list of DataObjects</returns>
Task<object> GetDataFilteredAndSorted(List<FilterModel> filter, List<SortModel> sortModel, long skip=0, long take=-1);
/// <summary>
/// Get Blob String from specific Field in specific Table - works only with id long fields
/// </summary>
/// <param name="tableName">Name of Table</param>
/// <param name="fieldName">Name of Field</param>
/// <param name="id">id value of Record</param>
/// <returns>String with Blob data</returns>
Task<string> GetBlobData(string tableName, string fieldName, long id);
}
}

View File

@@ -0,0 +1,202 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Repositories;
namespace Repositories.Migrations
{
[DbContext(typeof(FwDbContext))]
[Migration("20210706081036_v1")]
partial class v1
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.16")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Datamodels.DatabaseModels.Address", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<long?>("AddressTypeId")
.HasColumnType("bigint");
b.Property<DateTime>("ChangedAt")
.HasColumnType("datetime(6)");
b.Property<string>("City")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<long?>("PersonId")
.HasColumnType("bigint");
b.Property<string>("StreetName")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<int>("StreetNumber")
.HasColumnType("int");
b.Property<string>("Zip")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.HasKey("Id");
b.HasIndex("AddressTypeId");
b.HasIndex("PersonId");
b.ToTable("Address");
});
modelBuilder.Entity("Datamodels.DatabaseModels.Communication", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("ChangedAt")
.HasColumnType("datetime(6)");
b.Property<long?>("CommunicationTypeId")
.HasColumnType("bigint");
b.Property<string>("CommunicationValue")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<long?>("PersonId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("CommunicationTypeId");
b.HasIndex("PersonId");
b.ToTable("Communication");
});
modelBuilder.Entity("Datamodels.DatabaseModels.Person", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime?>("Birthday")
.HasColumnType("datetime(6)");
b.Property<DateTime>("ChangedAt")
.HasColumnType("datetime(6)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<string>("FirstName")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<long?>("GenderId")
.HasColumnType("bigint");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<string>("LastName")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.HasKey("Id");
b.HasIndex("GenderId");
b.ToTable("Person");
});
modelBuilder.Entity("Datamodels.Lookups.LookupCategory", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("CategoryName")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.HasKey("Id");
b.ToTable("LookupCategories");
});
modelBuilder.Entity("Datamodels.Lookups.LookupValue", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<long?>("LookupCategoryId")
.HasColumnType("bigint");
b.Property<string>("Value")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.HasKey("Id");
b.HasIndex("LookupCategoryId");
b.ToTable("LookupValues");
});
modelBuilder.Entity("Datamodels.DatabaseModels.Address", b =>
{
b.HasOne("Datamodels.Lookups.LookupValue", "AddressType")
.WithMany()
.HasForeignKey("AddressTypeId");
b.HasOne("Datamodels.DatabaseModels.Person", "Person")
.WithMany("Addresses")
.HasForeignKey("PersonId");
});
modelBuilder.Entity("Datamodels.DatabaseModels.Communication", b =>
{
b.HasOne("Datamodels.Lookups.LookupValue", "CommunicationType")
.WithMany()
.HasForeignKey("CommunicationTypeId");
b.HasOne("Datamodels.DatabaseModels.Person", "Person")
.WithMany("Communications")
.HasForeignKey("PersonId");
});
modelBuilder.Entity("Datamodels.DatabaseModels.Person", b =>
{
b.HasOne("Datamodels.Lookups.LookupValue", "Gender")
.WithMany()
.HasForeignKey("GenderId");
});
modelBuilder.Entity("Datamodels.Lookups.LookupValue", b =>
{
b.HasOne("Datamodels.Lookups.LookupCategory", "LookupCategory")
.WithMany("LookupValues")
.HasForeignKey("LookupCategoryId");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,181 @@
using System;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Repositories.Migrations
{
public partial class v1 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "LookupCategories",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
CategoryName = table.Column<string>(nullable: true),
IsActive = table.Column<bool>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_LookupCategories", x => x.Id);
});
migrationBuilder.CreateTable(
name: "LookupValues",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Value = table.Column<string>(nullable: true),
IsActive = table.Column<bool>(nullable: false),
LookupCategoryId = table.Column<long>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_LookupValues", x => x.Id);
table.ForeignKey(
name: "FK_LookupValues_LookupCategories_LookupCategoryId",
column: x => x.LookupCategoryId,
principalTable: "LookupCategories",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "Person",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
LastName = table.Column<string>(nullable: true),
FirstName = table.Column<string>(nullable: true),
Birthday = table.Column<DateTime>(nullable: true),
IsActive = table.Column<bool>(nullable: false),
CreatedAt = table.Column<DateTime>(nullable: false),
ChangedAt = table.Column<DateTime>(nullable: false),
GenderId = table.Column<long>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Person", x => x.Id);
table.ForeignKey(
name: "FK_Person_LookupValues_GenderId",
column: x => x.GenderId,
principalTable: "LookupValues",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "Address",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
StreetName = table.Column<string>(nullable: true),
StreetNumber = table.Column<int>(nullable: false),
Zip = table.Column<string>(nullable: true),
City = table.Column<string>(nullable: true),
CreatedAt = table.Column<DateTime>(nullable: false),
ChangedAt = table.Column<DateTime>(nullable: false),
AddressTypeId = table.Column<long>(nullable: true),
PersonId = table.Column<long>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Address", x => x.Id);
table.ForeignKey(
name: "FK_Address_LookupValues_AddressTypeId",
column: x => x.AddressTypeId,
principalTable: "LookupValues",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_Address_Person_PersonId",
column: x => x.PersonId,
principalTable: "Person",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "Communication",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
CommunicationValue = table.Column<string>(nullable: true),
CommunicationTypeId = table.Column<long>(nullable: true),
CreatedAt = table.Column<DateTime>(nullable: false),
ChangedAt = table.Column<DateTime>(nullable: false),
PersonId = table.Column<long>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Communication", x => x.Id);
table.ForeignKey(
name: "FK_Communication_LookupValues_CommunicationTypeId",
column: x => x.CommunicationTypeId,
principalTable: "LookupValues",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_Communication_Person_PersonId",
column: x => x.PersonId,
principalTable: "Person",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_Address_AddressTypeId",
table: "Address",
column: "AddressTypeId");
migrationBuilder.CreateIndex(
name: "IX_Address_PersonId",
table: "Address",
column: "PersonId");
migrationBuilder.CreateIndex(
name: "IX_Communication_CommunicationTypeId",
table: "Communication",
column: "CommunicationTypeId");
migrationBuilder.CreateIndex(
name: "IX_Communication_PersonId",
table: "Communication",
column: "PersonId");
migrationBuilder.CreateIndex(
name: "IX_LookupValues_LookupCategoryId",
table: "LookupValues",
column: "LookupCategoryId");
migrationBuilder.CreateIndex(
name: "IX_Person_GenderId",
table: "Person",
column: "GenderId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Address");
migrationBuilder.DropTable(
name: "Communication");
migrationBuilder.DropTable(
name: "Person");
migrationBuilder.DropTable(
name: "LookupValues");
migrationBuilder.DropTable(
name: "LookupCategories");
}
}
}

View File

@@ -0,0 +1,200 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Repositories;
namespace Repositories.Migrations
{
[DbContext(typeof(FwDbContext))]
partial class FwDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.16")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Datamodels.DatabaseModels.Address", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<long?>("AddressTypeId")
.HasColumnType("bigint");
b.Property<DateTime>("ChangedAt")
.HasColumnType("datetime(6)");
b.Property<string>("City")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<long?>("PersonId")
.HasColumnType("bigint");
b.Property<string>("StreetName")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<int>("StreetNumber")
.HasColumnType("int");
b.Property<string>("Zip")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.HasKey("Id");
b.HasIndex("AddressTypeId");
b.HasIndex("PersonId");
b.ToTable("Address");
});
modelBuilder.Entity("Datamodels.DatabaseModels.Communication", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("ChangedAt")
.HasColumnType("datetime(6)");
b.Property<long?>("CommunicationTypeId")
.HasColumnType("bigint");
b.Property<string>("CommunicationValue")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<long?>("PersonId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("CommunicationTypeId");
b.HasIndex("PersonId");
b.ToTable("Communication");
});
modelBuilder.Entity("Datamodels.DatabaseModels.Person", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime?>("Birthday")
.HasColumnType("datetime(6)");
b.Property<DateTime>("ChangedAt")
.HasColumnType("datetime(6)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<string>("FirstName")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<long?>("GenderId")
.HasColumnType("bigint");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<string>("LastName")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.HasKey("Id");
b.HasIndex("GenderId");
b.ToTable("Person");
});
modelBuilder.Entity("Datamodels.Lookups.LookupCategory", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("CategoryName")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.HasKey("Id");
b.ToTable("LookupCategories");
});
modelBuilder.Entity("Datamodels.Lookups.LookupValue", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<long?>("LookupCategoryId")
.HasColumnType("bigint");
b.Property<string>("Value")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.HasKey("Id");
b.HasIndex("LookupCategoryId");
b.ToTable("LookupValues");
});
modelBuilder.Entity("Datamodels.DatabaseModels.Address", b =>
{
b.HasOne("Datamodels.Lookups.LookupValue", "AddressType")
.WithMany()
.HasForeignKey("AddressTypeId");
b.HasOne("Datamodels.DatabaseModels.Person", "Person")
.WithMany("Addresses")
.HasForeignKey("PersonId");
});
modelBuilder.Entity("Datamodels.DatabaseModels.Communication", b =>
{
b.HasOne("Datamodels.Lookups.LookupValue", "CommunicationType")
.WithMany()
.HasForeignKey("CommunicationTypeId");
b.HasOne("Datamodels.DatabaseModels.Person", "Person")
.WithMany("Communications")
.HasForeignKey("PersonId");
});
modelBuilder.Entity("Datamodels.DatabaseModels.Person", b =>
{
b.HasOne("Datamodels.Lookups.LookupValue", "Gender")
.WithMany()
.HasForeignKey("GenderId");
});
modelBuilder.Entity("Datamodels.Lookups.LookupValue", b =>
{
b.HasOne("Datamodels.Lookups.LookupCategory", "LookupCategory")
.WithMany("LookupValues")
.HasForeignKey("LookupCategoryId");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Datamodels\Datamodels.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.16" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.16">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.2.6" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.16" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.16" />
</ItemGroup>
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,57 @@
using BusinessLogic.LookupLogic.Interfaces;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
namespace FwSearchApi.Controllers
{
[ApiController]
[Route("[controller]")]
public class LookupController : ControllerBase
{
private readonly IConfiguration _configuration;
private readonly ILogger<LookupController> _logger;
private readonly ILookupLogic _lookupLogic;
public LookupController(IConfiguration configuration, ILogger<LookupController> logger, ILookupLogic lookupLogic)
{
_configuration = configuration;
_logger = logger;
_lookupLogic = lookupLogic;
}
[HttpGet]
[Route("GetAllLookups")]
public async Task<JsonResult> GetAllLookups()
{
var result = await _lookupLogic.GetAllLookups();
_logger.LogInformation($"Lookups zur Verf<72>gung gestellt von {nameof(GetAllLookups)}");
return new JsonResult(result);
}
[HttpGet]
[Route("GetCategoriesById")]
public async Task<JsonResult> GetLookupCategoriesById(long id)
{
var result = await _lookupLogic.GetLookupCategoryById(id);
return new JsonResult(result);
}
[HttpGet]
[Route("GetCategoriesByName")]
public async Task<JsonResult> GetLookupCategoriesByName(string categoryName)
{
var result = await _lookupLogic.GetLookupCategoryByName(categoryName);
return new JsonResult(result);
}
[HttpGet]
[Route("GetActiveCategories")]
public async Task<JsonResult> GetActiveLookupCategories()
{
var result = await _lookupLogic.GetActiveLookupCategories();
return new JsonResult(result);
}
}
}

View File

@@ -0,0 +1,46 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
using SearchLogic;
using Datamodels.SearchModels;
using System.Collections.Generic;
using Datamodels.DatabaseModels;
namespace FwSearchApi.Controllers
{
[ApiController]
[Route("[controller]")]
public class SearchController : ControllerBase
{
private readonly ILogger<SearchController> _logger;
private readonly IConfiguration _configuration;
private readonly ISearchLogic _searchLogic;
public SearchController(ILogger<SearchController> logger, IConfiguration configuration, ISearchLogic searchLogic)
{
_logger = logger;
_configuration = configuration;
_searchLogic = searchLogic;
}
/// <summary>
/// This is for Test only
/// </summary>
[HttpGet]
[Route("GetAddresses")]
public async Task<JsonResult> GetAllAddresses()
{
var result = await _searchLogic.GetAllAddresses();
return new JsonResult(result);
}
[HttpPost]
[Route("GetFilteredData")]
public async Task<JsonResult> GetFilteredData([FromBody] FilterModel filter, [FromQuery] long skip = 0, [FromQuery] long take = -1)
{
var result = await _searchLogic.GetFilteredData(filter, skip, take);
return new JsonResult(result);
}
}
}

42
SearchWebApi/Program.cs Normal file
View File

@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
namespace FwSearchApi
{
public class Program
{
public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true, reloadOnChange: true)
.Build();
public static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.CreateLogger();
try {
CreateWebHostBuilder(args).Build().Run();
}
finally{
Log.CloseAndFlush();
}
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseConfiguration(Configuration)
.UseStartup<Startup>()
.UseSerilog()
.SuppressStatusMessages(true);
}
}

View File

@@ -0,0 +1,29 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:20693",
"sslPort": 0
}
},
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchUrl": "weatherforecast",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"FeatureWerkAPIs": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:5000"
}
}
}

View File

@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.16" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.1.4" />
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="6.1.4" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.1.4" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.1.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BusinessLogic\LookupLogic\LookupLogic.csproj" />
<ProjectReference Include="..\BusinessLogic\SearchLogic\SearchLogic.csproj" />
<ProjectReference Include="..\Datamodels\Datamodels.csproj" />
<ProjectReference Include="..\Repositories\Repositories.csproj" />
</ItemGroup>
</Project>

76
SearchWebApi/Startup.cs Normal file
View File

@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Repositories;
using Repositories.Interfaces;
using BusinessLogic.LookupLogic;
using BusinessLogic.LookupLogic.Interfaces;
using SearchLogic;
namespace FwSearchApi
{
public class Startup
{
readonly ILogger<Startup> _logger;
public IConfiguration _configuration { get; }
public Startup(IConfiguration configuration, ILogger<Startup> logger)
{
_configuration = configuration;
_logger = logger;
_logger.LogInformation("Starting up FeatureWerk Search API");
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers().AddNewtonsoftJson((options) =>
{
// keine Optionen hier
});
services.AddTransient<ILookupLogic, FwLookupLogic>();
services.AddTransient<IFwMariaLookupRepo, FwMariaLookupRepo>();
services.AddTransient<IFwMariaSearchRepo, FwMariaSearchRepo>();
services.AddTransient<ISearchLogic, SearchLogic.SearchLogic>();
services.AddSwaggerGen();
_logger.LogInformation("Services for FeatureWerkAPIs configured");
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "FeatureWerk Search API V1");
});
app.UseHttpsRedirection();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

View File

@@ -0,0 +1,40 @@
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"mariadb": "SERVER=localhost;DATABASE=textor_test;PORT=3333;USER=root;PASSWORD=$64,rf1209",
"postgres": "",
"sqlserver": "",
"oracle": ""
},
"GeneralSettings": {
"DbToUse": "mariadb"
},
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"System": "Information",
"Microsoft": "Warning"
}
},
"WriteTo": [
{ "Name": "File",
"Args": {
"path": "/tmp/FwSearchApi.log",
"rollingInterval": "Day"
}
}
],
"Enrich": ["FromLogContext", "WithMachineName"],
"Properties": {
"Appname": "FeatureWerkSearchAPI",
"Environment": "Development"
}
}
}

View File

@@ -0,0 +1,10 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,79 @@
using System;
using Xunit;
using Repositories;
using Microsoft.EntityFrameworkCore;
using Datamodels.Lookups;
using System.Threading.Tasks;
using System.Linq;
using Datamodels.BusinessModels;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;
using Moq;
namespace fwrepo
{
public class SimpleDbTests
{
private readonly FwDbContext testdb = new FwDbContext();
private readonly FwMariaLookupRepo repo = new FwMariaLookupRepo(Mock.Of<ILogger<FwMariaLookupRepo>>(), Mock.Of<IConfiguration>());
[Fact]
public void CreateSomeLookupData()
{
repo.DeleteAllCategories();
var rand = new Random();
int catCount = rand.Next(10, 50);
for (int i = 0; i < catCount; i++)
{
var category = new LookupCategory
{
CategoryName = $"{i} Category"
};
testdb.LookupCategories.Add(category);
var valRnd = new Random();
int valCount = valRnd.Next(10,50);
for (int x = 0; x < valCount; x++)
{
testdb.LookupValues.Add(new LookupValue
{
Value = $"Category { i } - Value {x}",
LookupCategory = category
});
}
}
int result = testdb.SaveChanges();
Assert.True(result > 0);
}
[Fact]
public async Task GetAllLookupCategories()
{
var result = await repo.GetAllLookups();
Assert.NotEmpty(result.Data);
Assert.NotEmpty(result.Data.First().LookupValues);
}
[Fact]
public async Task GetLookupCategoryById()
{
var result = await repo.GetLookupCategoryById(65);
Assert.NotNull(result.Data);
}
[Fact]
public async Task GetLookupCategoryByName()
{
var result = await repo.GetLookupCategoryByName("Category");
Assert.NotEmpty(result.Data);
}
[Fact]
public async Task GetActiveCategories()
{
var result = await repo.GetActiveLookupCategories();
Assert.NotEmpty(result.Data);
}
}
}

View File

@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="coverlet.collector" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Repositories\Repositories.csproj" />
<ProjectReference Include="..\..\..\Datamodels\Datamodels.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\..\..\Repositories\Repositories.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.16">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,12 @@
using System;
namespace Migration
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}

72
TxSearchApi.sln Normal file
View File

@@ -0,0 +1,72 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31424.327
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SearchWebApi", "SearchWebApi\SearchWebApi.csproj", "{DAB6C3F6-6437-491F-A3AA-D9A2518C96AC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LookupLogic", "BusinessLogic\LookupLogic\LookupLogic.csproj", "{20943D77-BB49-4D84-A466-ADB9EA9ED0A7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SearchLogic", "BusinessLogic\SearchLogic\SearchLogic.csproj", "{566B6716-C97C-4A79-A342-9160C3989EDF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Datamodels", "Datamodels\Datamodels.csproj", "{43A6B0AF-3828-477D-A6B6-37A562E3F289}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Repositories", "Repositories\Repositories.csproj", "{913847E9-2460-4E1A-9C86-F1CA3BA08C40}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Migration", "Tools\EF\Migration\Migration.csproj", "{D258FDB3-484F-4E0A-B48E-42C9139679D3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "fwrepo", "Tests\Repo\fwrepo\fwrepo.csproj", "{38A7FB4F-2874-4D82-A2E7-088AF95CEDBA}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{92B23E8B-5C97-4116-B178-FF2B90FE3B44}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Repo", "Repo", "{16706E07-A95C-476A-90E3-3FF782B4A14E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{37670BBA-CF6C-476A-ACA8-E1F62B30EA77}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DAB6C3F6-6437-491F-A3AA-D9A2518C96AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DAB6C3F6-6437-491F-A3AA-D9A2518C96AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DAB6C3F6-6437-491F-A3AA-D9A2518C96AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DAB6C3F6-6437-491F-A3AA-D9A2518C96AC}.Release|Any CPU.Build.0 = Release|Any CPU
{20943D77-BB49-4D84-A466-ADB9EA9ED0A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{20943D77-BB49-4D84-A466-ADB9EA9ED0A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{20943D77-BB49-4D84-A466-ADB9EA9ED0A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{20943D77-BB49-4D84-A466-ADB9EA9ED0A7}.Release|Any CPU.Build.0 = Release|Any CPU
{566B6716-C97C-4A79-A342-9160C3989EDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{566B6716-C97C-4A79-A342-9160C3989EDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{566B6716-C97C-4A79-A342-9160C3989EDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{566B6716-C97C-4A79-A342-9160C3989EDF}.Release|Any CPU.Build.0 = Release|Any CPU
{43A6B0AF-3828-477D-A6B6-37A562E3F289}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{43A6B0AF-3828-477D-A6B6-37A562E3F289}.Debug|Any CPU.Build.0 = Debug|Any CPU
{43A6B0AF-3828-477D-A6B6-37A562E3F289}.Release|Any CPU.ActiveCfg = Release|Any CPU
{43A6B0AF-3828-477D-A6B6-37A562E3F289}.Release|Any CPU.Build.0 = Release|Any CPU
{913847E9-2460-4E1A-9C86-F1CA3BA08C40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{913847E9-2460-4E1A-9C86-F1CA3BA08C40}.Debug|Any CPU.Build.0 = Debug|Any CPU
{913847E9-2460-4E1A-9C86-F1CA3BA08C40}.Release|Any CPU.ActiveCfg = Release|Any CPU
{913847E9-2460-4E1A-9C86-F1CA3BA08C40}.Release|Any CPU.Build.0 = Release|Any CPU
{D258FDB3-484F-4E0A-B48E-42C9139679D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D258FDB3-484F-4E0A-B48E-42C9139679D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D258FDB3-484F-4E0A-B48E-42C9139679D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D258FDB3-484F-4E0A-B48E-42C9139679D3}.Release|Any CPU.Build.0 = Release|Any CPU
{38A7FB4F-2874-4D82-A2E7-088AF95CEDBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38A7FB4F-2874-4D82-A2E7-088AF95CEDBA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38A7FB4F-2874-4D82-A2E7-088AF95CEDBA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38A7FB4F-2874-4D82-A2E7-088AF95CEDBA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{38A7FB4F-2874-4D82-A2E7-088AF95CEDBA} = {16706E07-A95C-476A-90E3-3FF782B4A14E}
{16706E07-A95C-476A-90E3-3FF782B4A14E} = {92B23E8B-5C97-4116-B178-FF2B90FE3B44}
{37670BBA-CF6C-476A-ACA8-E1F62B30EA77} = {92B23E8B-5C97-4116-B178-FF2B90FE3B44}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {52A7E990-B64B-4E17-BA59-FE07B325B88C}
EndGlobalSection
EndGlobal