-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
38 changed files
with
622 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# Reporting | ||
|
||
Implementations of this feature registers a singleton `IReportContext` with | ||
which you can read raw data from database. Add this feature using | ||
`AddReporting()` extension; | ||
|
||
```csharp | ||
app.Features.AddReporting(...); | ||
``` | ||
|
||
## Fake | ||
|
||
Adds a fake report context that allows you to return data directly from `.json` | ||
resources. | ||
|
||
```csharp | ||
c => c.Fake(basePath: "Fake") | ||
``` | ||
|
||
## Mock | ||
|
||
Adds a mock instance of report context to be used during spec tests. | ||
|
||
```csharp | ||
c => c.Mock() | ||
``` | ||
|
||
## Native SQL | ||
|
||
Adds a report context instance that uses a `IStatelessSession` instance to | ||
execute native SQL queries read from `.sql` resources in your project. | ||
|
||
```csharp | ||
c => c.NativeSql(basePath: "Queries/MySql") | ||
``` | ||
|
||
> [!TIP] | ||
> | ||
> You may group your RDBMS specific queries in different folders, and use | ||
> setting to specify which folder to use depending on environment. | ||
> | ||
> ```csharp | ||
> c => c.NativeSql(basePath: Settings.Required("Reporting:NativeSql:BasePath")) | ||
> ``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
src/recipe/Baked.Recipe.Service.Application/Reporting/Fake/FakeData.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
using System.Text.RegularExpressions; | ||
|
||
namespace Baked.Reporting.Fake; | ||
|
||
public record FakeData( | ||
Dictionary<string, string?>? Parameters, | ||
List<Dictionary<string, object?>> Result | ||
) | ||
{ | ||
public bool Matches(Dictionary<string, object> parameters) | ||
{ | ||
if (Parameters is null) { return true; } | ||
|
||
foreach (var (key, pattern) in Parameters) | ||
{ | ||
if (!parameters.ContainsKey(key)) | ||
{ | ||
return false; | ||
} | ||
|
||
if (pattern is null) { continue; } | ||
if (Regex.IsMatch($"{parameters[key]}", pattern)) { continue; } | ||
|
||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/recipe/Baked.Recipe.Service.Application/Reporting/Fake/FakeReportingExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using Baked.Reporting; | ||
using Baked.Reporting.Fake; | ||
using Baked.Testing; | ||
using Microsoft.Extensions.FileProviders; | ||
|
||
namespace Baked; | ||
|
||
public static class FakeReportingExtensions | ||
{ | ||
public static FakeReportingFeature Fake(this ReportingConfigurator _) => | ||
new(); | ||
|
||
public static IReportContext AFakeReportContext(this Stubber giveMe, | ||
string basePath = "Fake" | ||
) => new ReportContext(giveMe.The<IFileProvider>(), new(basePath)); | ||
} |
15 changes: 15 additions & 0 deletions
15
src/recipe/Baked.Recipe.Service.Application/Reporting/Fake/FakeReportingFeature.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using Baked.Architecture; | ||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
namespace Baked.Reporting.Fake; | ||
|
||
public class FakeReportingFeature : IFeature<ReportingConfigurator> | ||
{ | ||
public void Configure(LayerConfigurator configurator) | ||
{ | ||
configurator.ConfigureServiceCollection(services => | ||
{ | ||
services.AddSingleton<IReportContext, ReportContext>(); | ||
}); | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
src/recipe/Baked.Recipe.Service.Application/Reporting/Fake/ReportContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using Microsoft.Extensions.FileProviders; | ||
using Newtonsoft.Json; | ||
|
||
namespace Baked.Reporting.Fake; | ||
|
||
public class ReportContext(IFileProvider _fileProvider, ReportOptions _options) | ||
: IReportContext | ||
{ | ||
public async Task<object?[][]> Execute(string queryName, Dictionary<string, object> parameters) | ||
{ | ||
var dataPath = $"/{Path.Join(_options.BasePath, $"{queryName}.json")}"; | ||
if (!_fileProvider.Exists(dataPath)) { throw new QueryNotFoundException(queryName); } | ||
|
||
var dataString = await _fileProvider.ReadAsStringAsync(dataPath) ?? string.Empty; | ||
|
||
var fakes = JsonConvert.DeserializeObject<List<FakeData>>(dataString) ?? new(); | ||
var match = fakes.FirstOrDefault(fake => fake.Matches(parameters)); | ||
if (match is null) { return []; } | ||
|
||
return match.Result.Select(row => row.Values.ToArray()).ToArray(); | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
src/recipe/Baked.Recipe.Service.Application/Reporting/Fake/ReportOptions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
using Baked.Runtime; | ||
|
||
namespace Baked.Reporting.Fake; | ||
|
||
public record ReportOptions(Setting<string> BasePath); |
10 changes: 10 additions & 0 deletions
10
src/recipe/Baked.Recipe.Service.Application/Reporting/Mock/MockReportingExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using Baked.Reporting; | ||
using Baked.Reporting.Mock; | ||
|
||
namespace Baked; | ||
|
||
public static class MockReportingExtensions | ||
{ | ||
public static MockReportingFeature Mock(this ReportingConfigurator _) => | ||
new(); | ||
} |
14 changes: 14 additions & 0 deletions
14
src/recipe/Baked.Recipe.Service.Application/Reporting/Mock/MockReportingFeature.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using Baked.Architecture; | ||
|
||
namespace Baked.Reporting.Mock; | ||
|
||
public class MockReportingFeature : IFeature<ReportingConfigurator> | ||
{ | ||
public void Configure(LayerConfigurator configurator) | ||
{ | ||
configurator.ConfigureTestConfiguration(test => | ||
{ | ||
test.Mocks.Add<IReportContext>(singleton: true); | ||
}); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
...cipe/Baked.Recipe.Service.Application/Reporting/NativeSql/NativeSqlReportingExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using Baked.Reporting; | ||
using Baked.Reporting.NativeSql; | ||
using Baked.Runtime; | ||
|
||
namespace Baked; | ||
|
||
public static class NativeSqlReportingExtensions | ||
{ | ||
public static NativeSqlReportingFeature NativeSql(this ReportingConfigurator _, | ||
Setting<string>? basePath = default | ||
) => new(basePath ?? string.Empty); | ||
} |
35 changes: 35 additions & 0 deletions
35
src/recipe/Baked.Recipe.Service.Application/Reporting/NativeSql/NativeSqlReportingFeature.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using Baked.Architecture; | ||
using Baked.Runtime; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using NHibernate; | ||
|
||
namespace Baked.Reporting.NativeSql; | ||
|
||
public class NativeSqlReportingFeature(Setting<string> _basePath) | ||
: IFeature<ReportingConfigurator> | ||
{ | ||
public void Configure(LayerConfigurator configurator) | ||
{ | ||
configurator.ConfigureConfigurationBuilder(configuration => | ||
{ | ||
configuration.AddJsonAsDefault($$""" | ||
{ | ||
"Logging": { | ||
"LogLevel": { | ||
"NHibernate": "None", | ||
"NHibernate.Sql": "{{(configurator.IsDevelopment() ? "Debug" : "None")}}" | ||
} | ||
} | ||
} | ||
"""); | ||
}); | ||
|
||
configurator.ConfigureServiceCollection(services => | ||
{ | ||
services.AddSingleton(new ReportOptions(_basePath)); | ||
services.AddSingleton<IReportContext, ReportContext>(); | ||
services.AddScoped(sp => sp.GetRequiredService<ISessionFactory>().OpenStatelessSession()); | ||
services.AddSingleton<Func<IStatelessSession>>(sp => () => sp.UsingCurrentScope().GetRequiredService<IStatelessSession>()); | ||
}); | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/recipe/Baked.Recipe.Service.Application/Reporting/NativeSql/ReportContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
using Microsoft.Extensions.FileProviders; | ||
|
||
namespace Baked.Reporting.NativeSql; | ||
|
||
public class ReportContext(IFileProvider _fileProvider, Func<NHibernate.IStatelessSession> _getStatelessSession, ReportOptions _options) | ||
: IReportContext | ||
{ | ||
public async Task<object?[][]> Execute(string queryName, Dictionary<string, object> parameters) | ||
{ | ||
var queryPath = $"/{Path.Join(_options.BasePath, $"{queryName}.sql")}"; | ||
if (!_fileProvider.Exists(queryPath)) | ||
{ | ||
throw new QueryNotFoundException(queryName); | ||
} | ||
|
||
var queryString = await _fileProvider.ReadAsStringAsync(queryPath); | ||
var query = _getStatelessSession().CreateSQLQuery(queryString); | ||
foreach (var (name, value) in parameters) | ||
{ | ||
query.SetParameter(name, value); | ||
} | ||
|
||
var result = await query.ListAsync(); | ||
|
||
return result.Cast<object[]>().ToArray(); | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
src/recipe/Baked.Recipe.Service.Application/Reporting/NativeSql/ReportOptions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
using Baked.Runtime; | ||
|
||
namespace Baked.Reporting.NativeSql; | ||
|
||
public record ReportOptions(Setting<string> BasePath); |
3 changes: 3 additions & 0 deletions
3
src/recipe/Baked.Recipe.Service.Application/Reporting/ReportingConfigurator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
namespace Baked.Reporting; | ||
|
||
public class ReportingConfigurator { } |
48 changes: 48 additions & 0 deletions
48
src/recipe/Baked.Recipe.Service.Application/Reporting/ReportingExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
using Baked.Architecture; | ||
using Baked.Reporting; | ||
using Baked.Testing; | ||
using Moq; | ||
|
||
namespace Baked; | ||
|
||
public static class ReportingExtensions | ||
{ | ||
public static void AddReporting(this List<IFeature> features, Func<ReportingConfigurator, IFeature<ReportingConfigurator>> configure) => | ||
features.Add(configure(new())); | ||
|
||
public static IReportContext TheReportContext(this Mocker mockMe, | ||
object?[][]? data = default | ||
) | ||
{ | ||
data ??= []; | ||
|
||
var result = Mock.Get(mockMe.Spec.GiveMe.The<IReportContext>()); | ||
|
||
if (data is not null) | ||
{ | ||
result | ||
.Setup(df => df.Execute(It.IsAny<string>(), It.IsAny<Dictionary<string, object>>())) | ||
.ReturnsAsync(data); | ||
} | ||
|
||
return result.Object; | ||
} | ||
|
||
public static void VerifyExecute(this IReportContext dataFetcher, | ||
string? queryName = default, | ||
(string key, object value)? parameter = default, | ||
List<(string key, object value)>? parameters = default | ||
) | ||
{ | ||
parameters ??= parameter is not null ? [parameter.Value] : []; | ||
|
||
Mock.Get(dataFetcher).Verify( | ||
df => df.Execute( | ||
It.Is<string>(q => queryName == null || q == queryName), | ||
It.Is<Dictionary<string, object>>(p => | ||
parameters.All((kvp) => p.ContainsKey(kvp.key) && Equals(p[kvp.key], kvp.value)) | ||
) | ||
) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Baked.Reporting; | ||
|
||
public interface IReportContext | ||
{ | ||
Task<object?[][]> Execute(string queryName, Dictionary<string, object> parameters); | ||
} |
4 changes: 4 additions & 0 deletions
4
src/recipe/Baked.Recipe.Service/Reporting/QueryNotFoundException.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
namespace Baked.Reporting; | ||
|
||
public class QueryNotFoundException(string queryName) | ||
: Exception($"No query file with '{queryName}' was found"); |
Oops, something went wrong.