-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(sql-providers): unify SQL query generation (#147)
- Loading branch information
Showing
50 changed files
with
1,296 additions
and
743 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 |
---|---|---|
@@ -1,2 +1,3 @@ | ||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> | ||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Mongo/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> | ||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Mongo/@EntryIndexedValue">True</s:Boolean> | ||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Postgre/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> |
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,37 @@ | ||
namespace Serilog.Ui.Core.QueryBuilder.Sql; | ||
|
||
/// <summary> | ||
/// Represents the column names used in the SQL-based sink for logging. | ||
/// </summary> | ||
public abstract class SinkColumnNames | ||
{ | ||
/// <summary> | ||
/// Gets or sets the message of the log entry. | ||
/// </summary> | ||
public string Message { get; set; } = string.Empty; | ||
|
||
/// <summary> | ||
/// Gets or sets the message template of the log entry. | ||
/// </summary> | ||
public string MessageTemplate { get; set; } = string.Empty; | ||
|
||
/// <summary> | ||
/// Gets or sets the level of the log entry. | ||
/// </summary> | ||
public string Level { get; set; } = string.Empty; | ||
|
||
/// <summary> | ||
/// Gets or sets the timestamp of the log entry. | ||
/// </summary> | ||
public string Timestamp { get; set; } = string.Empty; | ||
|
||
/// <summary> | ||
/// Gets or sets the exception of the log entry. | ||
/// </summary> | ||
public string Exception { get; set; } = string.Empty; | ||
|
||
/// <summary> | ||
/// Gets or sets the serialized log event like properties. | ||
/// </summary> | ||
public string LogEventSerialized { get; set; } = string.Empty; | ||
} |
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,67 @@ | ||
using Serilog.Ui.Core.Attributes; | ||
using Serilog.Ui.Core.Models; | ||
using System.Reflection; | ||
using static Serilog.Ui.Core.Models.SearchOptions; | ||
|
||
namespace Serilog.Ui.Core.QueryBuilder.Sql; | ||
|
||
/// <summary> | ||
/// Abstract class that provides methods to build SQL queries for fetching and counting logs. | ||
/// </summary> | ||
public abstract class SqlQueryBuilder<TModel> where TModel : LogModel | ||
{ | ||
/// <summary> | ||
/// Builds a SQL query to fetch logs from the specified table. | ||
/// </summary> | ||
/// <param name="columns">The column names used in the sink for logging.</param> | ||
/// <param name="schema">The schema of the table.</param> | ||
/// <param name="tableName">The name of the table.</param> | ||
/// <param name="query">The query parameters for fetching logs.</param> | ||
/// <returns>A SQL query string to fetch logs.</returns> | ||
public abstract string BuildFetchLogsQuery(SinkColumnNames columns, string schema, string tableName, FetchLogsQuery query); | ||
|
||
/// <summary> | ||
/// Builds a SQL query to count logs in the specified table. | ||
/// </summary> | ||
/// <param name="columns">The column names used in the sink for logging.</param> | ||
/// <param name="schema">The schema of the table.</param> | ||
/// <param name="tableName">The name of the table.</param> | ||
/// <param name="query">The query parameters for counting logs.</param> | ||
/// <returns>A SQL query string to count logs.</returns> | ||
public abstract string BuildCountLogsQuery(SinkColumnNames columns, string schema, string tableName, FetchLogsQuery query); | ||
|
||
/// <summary> | ||
/// Generates a SQL sort clause based on the specified sort property and direction. | ||
/// </summary> | ||
/// <param name="columns">The column names used in the sink for logging.</param> | ||
/// <param name="sortOn">The property to sort on.</param> | ||
/// <param name="sortBy">The direction to sort by.</param> | ||
/// <returns>A SQL sort clause string.</returns> | ||
protected abstract string GenerateSortClause(SinkColumnNames columns, SortProperty sortOn, SortDirection sortBy); | ||
|
||
/// <summary> | ||
/// Generates a SQL sort clause based on the specified sort property and direction. | ||
/// </summary> | ||
/// <param name="columns">The column names used in the sink for logging.</param> | ||
/// <param name="sortOn">The property to sort on.</param> | ||
/// <returns>A SQL sort clause string.</returns> | ||
protected static string GetSortColumnName(SinkColumnNames columns, SortProperty sortOn) => sortOn switch | ||
{ | ||
SortProperty.Timestamp => columns.Timestamp, | ||
SortProperty.Level => columns.Level, | ||
SortProperty.Message => columns.Message, | ||
_ => columns.Timestamp | ||
}; | ||
|
||
/// <summary> | ||
/// Determines whether to add the exception column to the WHERE clause based on the presence of the RemovedColumnAttribute. | ||
/// </summary> | ||
/// <returns>True if the exception column should be added to the WHERE clause; otherwise, false.</returns> | ||
protected static bool AddExceptionToWhereClause() | ||
{ | ||
PropertyInfo? exceptionProperty = typeof(TModel).GetProperty("Exception"); | ||
RemovedColumnAttribute? att = exceptionProperty?.GetCustomAttribute<RemovedColumnAttribute>(); | ||
|
||
return att is null; | ||
} | ||
} |
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
104 changes: 52 additions & 52 deletions
104
src/Serilog.Ui.MsSqlServerProvider/Extensions/SerilogUiOptionBuilderExtensions.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 |
---|---|---|
@@ -1,64 +1,64 @@ | ||
using System; | ||
using Dapper; | ||
using Dapper; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Serilog.Ui.Core; | ||
using Serilog.Ui.Core.Interfaces; | ||
using Serilog.Ui.Core.Models.Options; | ||
using System; | ||
|
||
namespace Serilog.Ui.MsSqlServerProvider.Extensions | ||
{ | ||
/// <summary> | ||
/// SQL Server data provider specific extension methods for <see cref="ISerilogUiOptionsBuilder"/>. | ||
/// </summary> | ||
public static class SerilogUiOptionBuilderExtensions | ||
{ | ||
/// <summary>Configures the SerilogUi to connect to a SQL Server database.</summary> | ||
/// <param name="optionsBuilder"> The options builder. </param> | ||
/// <param name="setupOptions">The Ms Sql options action.</param> | ||
/// <param name="dateTimeCustomParsing"> | ||
/// Delegate to customize the DateTime parsing. | ||
/// It throws <see cref="InvalidOperationException" /> if the return DateTime isn't UTC kind. | ||
/// </param> | ||
public static ISerilogUiOptionsBuilder UseSqlServer( | ||
this ISerilogUiOptionsBuilder optionsBuilder, | ||
Action<RelationalDbOptions> setupOptions, | ||
Func<string, DateTime>? dateTimeCustomParsing = null | ||
) => optionsBuilder.UseSqlServer<SqlServerLogModel>(setupOptions, dateTimeCustomParsing); | ||
|
||
/// <summary>Configures the SerilogUi to connect to a SQL Server database.</summary> | ||
/// <typeparam name="T">The log model, containing any additional columns. It must inherit <see cref="SqlServerLogModel"/>.</typeparam> | ||
/// <param name="optionsBuilder"> The options builder. </param> | ||
/// <param name="setupOptions">The Ms Sql options action.</param> | ||
/// <param name="dateTimeCustomParsing"> | ||
/// Delegate to customize the DateTime parsing. | ||
/// It throws <see cref="InvalidOperationException" /> if the return DateTime isn't UTC kind. | ||
/// </param> | ||
public static ISerilogUiOptionsBuilder UseSqlServer<T>( | ||
this ISerilogUiOptionsBuilder optionsBuilder, | ||
Action<RelationalDbOptions> setupOptions, | ||
Func<string, DateTime>? dateTimeCustomParsing = null | ||
) where T : SqlServerLogModel | ||
{ | ||
var dbOptions = new RelationalDbOptions("dbo"); | ||
setupOptions(dbOptions); | ||
dbOptions.Validate(); | ||
|
||
var providerName = dbOptions.GetProviderName(SqlServerDataProvider.MsSqlProviderName); | ||
namespace Serilog.Ui.MsSqlServerProvider.Extensions; | ||
|
||
optionsBuilder.RegisterExceptionAsStringForProviderKey(providerName); | ||
SqlMapper.AddTypeHandler(new DapperDateTimeHandler(dateTimeCustomParsing)); | ||
/// <summary> | ||
/// SQL Server data provider specific extension methods for <see cref="ISerilogUiOptionsBuilder"/>. | ||
/// </summary> | ||
public static class SerilogUiOptionBuilderExtensions | ||
{ | ||
/// <summary>Configures the SerilogUi to connect to a SQL Server database.</summary> | ||
/// <param name="optionsBuilder"> The options builder. </param> | ||
/// <param name="setupOptions">The Ms Sql options action.</param> | ||
/// <param name="dateTimeCustomParsing"> | ||
/// Delegate to customize the DateTime parsing. | ||
/// It throws <see cref="InvalidOperationException" /> if the return DateTime isn't UTC kind. | ||
/// </param> | ||
public static ISerilogUiOptionsBuilder UseSqlServer( | ||
this ISerilogUiOptionsBuilder optionsBuilder, | ||
Action<RelationalDbOptions> setupOptions, | ||
Func<string, DateTime>? dateTimeCustomParsing = null | ||
) => optionsBuilder.UseSqlServer<SqlServerLogModel>(setupOptions, dateTimeCustomParsing); | ||
|
||
var customModel = typeof(T) != typeof(SqlServerLogModel); | ||
if (customModel) | ||
{ | ||
optionsBuilder.RegisterColumnsInfo<T>(providerName); | ||
optionsBuilder.Services.AddScoped<IDataProvider>(_ => new SqlServerDataProvider<T>(dbOptions)); | ||
/// <summary>Configures the SerilogUi to connect to a SQL Server database.</summary> | ||
/// <typeparam name="T">The log model, containing any additional columns. It must inherit <see cref="SqlServerLogModel"/>.</typeparam> | ||
/// <param name="optionsBuilder"> The options builder. </param> | ||
/// <param name="setupOptions">The Ms Sql options action.</param> | ||
/// <param name="dateTimeCustomParsing"> | ||
/// Delegate to customize the DateTime parsing. | ||
/// It throws <see cref="InvalidOperationException" /> if the return DateTime isn't UTC kind. | ||
/// </param> | ||
public static ISerilogUiOptionsBuilder UseSqlServer<T>( | ||
this ISerilogUiOptionsBuilder optionsBuilder, | ||
Action<RelationalDbOptions> setupOptions, | ||
Func<string, DateTime>? dateTimeCustomParsing = null | ||
) where T : SqlServerLogModel | ||
{ | ||
SqlServerDbOptions dbOptions = new("dbo"); | ||
setupOptions(dbOptions); | ||
dbOptions.Validate(); | ||
|
||
return optionsBuilder; | ||
} | ||
string providerName = dbOptions.GetProviderName(SqlServerDataProvider.MsSqlProviderName); | ||
optionsBuilder.RegisterExceptionAsStringForProviderKey(providerName); | ||
SqlMapper.AddTypeHandler(new DapperDateTimeHandler(dateTimeCustomParsing)); | ||
|
||
optionsBuilder.Services.AddScoped<IDataProvider>(_ => new SqlServerDataProvider(dbOptions)); | ||
return optionsBuilder; | ||
bool customModel = typeof(T) != typeof(SqlServerLogModel); | ||
if (customModel) | ||
{ | ||
optionsBuilder.RegisterColumnsInfo<T>(providerName); | ||
optionsBuilder.Services.AddScoped<IDataProvider>(_ => new SqlServerDataProvider<T>(dbOptions, new SqlServerQueryBuilder<T>())); | ||
} | ||
else | ||
{ | ||
optionsBuilder.Services.AddScoped<IDataProvider>(_ => | ||
new SqlServerDataProvider(dbOptions, new SqlServerQueryBuilder<SqlServerLogModel>())); | ||
} | ||
|
||
return optionsBuilder; | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/Serilog.Ui.MsSqlServerProvider/Extensions/SqlServerDbOptions.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 Serilog.Ui.Core.Models.Options; | ||
using Serilog.Ui.Core.QueryBuilder.Sql; | ||
using Serilog.Ui.MsSqlServerProvider.Models; | ||
|
||
namespace Serilog.Ui.MsSqlServerProvider.Extensions; | ||
|
||
public class SqlServerDbOptions(string defaultSchemaName) : RelationalDbOptions(defaultSchemaName) | ||
{ | ||
public SinkColumnNames ColumnNames { get; } = new SqlServerSinkColumnNames(); | ||
} |
File renamed without changes.
16 changes: 16 additions & 0 deletions
16
src/Serilog.Ui.MsSqlServerProvider/Models/SqlServerSinkColumnNames.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 Serilog.Ui.Core.QueryBuilder.Sql; | ||
|
||
namespace Serilog.Ui.MsSqlServerProvider.Models; | ||
|
||
internal class SqlServerSinkColumnNames : SinkColumnNames | ||
{ | ||
public SqlServerSinkColumnNames() | ||
{ | ||
Exception = "Exception"; | ||
Level = "Level"; | ||
LogEventSerialized = "Properties"; | ||
Message = "Message"; | ||
MessageTemplate = ""; | ||
Timestamp = "TimeStamp"; | ||
} | ||
} |
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
Oops, something went wrong.