Skip to content

Commit

Permalink
Merge pull request #6 from maximgorbatyuk/dev
Browse files Browse the repository at this point in the history
Have added endpoint for table meta info
  • Loading branch information
maximgorbatyuk authored Sep 23, 2022
2 parents 2847783 + 6c41852 commit 4bfb8ef
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public static class DatabaseTablesViewExtensions
{
public const string DefaultOutputRoute = "/database-sql-endpoints/table";
public const string DefaultReadRoute = "/database-sql-endpoints/read";
public const string DefaultTablesMetaRoute = "/database-sql-endpoints/tables-meta";
public const string DefaultExecuteRoute = "/database-sql-endpoints/execute";

public static IDatabaseTablesSettings<TDbContext> UseSqlEndpoints<TDbContext>(
Expand All @@ -18,16 +19,14 @@ public static IDatabaseTablesSettings<TDbContext> UseSqlEndpoints<TDbContext>(
string roleToCheckForAuthorization = null,
SqlEngine sqlEngine = default,
int timeoutSeconds = Constants.DefaultSqlCommandTimeoutSec)
where TDbContext : DbContext
{
return new DatabaseTablesSettings<TDbContext>(
where TDbContext : DbContext =>
new DatabaseTablesSettings<TDbContext>(
app,
port,
checkForAuthentication,
roleToCheckForAuthorization,
sqlEngine,
timeoutSeconds);
}

/// <summary>
/// Returns content of the table.
Expand All @@ -41,14 +40,12 @@ public static IDatabaseTablesSettings<TDbContext> UseSqlEndpoints<TDbContext>(
public static IDatabaseTablesSettings<TDbContext> UseTableOutputEndpoint<TDbContext>(
this IDatabaseTablesSettings<TDbContext> settings,
PathString path = default)
where TDbContext : DbContext
{
return new MiddlewareRoute<DatabaseTablesMiddleware<TDbContext>, TDbContext>(
where TDbContext : DbContext =>
new MiddlewareRoute<DatabaseTablesMiddleware<TDbContext>, TDbContext>(
settings: settings,
path: path,
methodName: HttpMethods.Get,
defaultPathRoute: DefaultOutputRoute).Setup();
}

/// <summary>
/// Executes and read any SQL command.
Expand All @@ -62,14 +59,31 @@ public static IDatabaseTablesSettings<TDbContext> UseTableOutputEndpoint<TDbCont
public static IDatabaseTablesSettings<TDbContext> UseReadEndpoint<TDbContext>(
this IDatabaseTablesSettings<TDbContext> settings,
PathString path = default)
where TDbContext : DbContext
{
return new MiddlewareRoute<ReadSQlMiddleware<TDbContext>, TDbContext>(
where TDbContext : DbContext =>
new MiddlewareRoute<ReadSQlMiddleware<TDbContext>, TDbContext>(
settings: settings,
path: path,
methodName: HttpMethods.Post,
defaultPathRoute: DefaultReadRoute).Setup();
}

/// <summary>
/// Returns tables, their sizes and count of rows.
///
/// POST /database-sql-endpoints/tables-meta is a default route.
/// </summary>
/// <typeparam name="TDbContext">Database context.</typeparam>
/// <param name="settings">Settings.</param>
/// <param name="path">Path.</param>
/// <returns>Settings instance.</returns>
public static IDatabaseTablesSettings<TDbContext> UseTablesInfoEndpoint<TDbContext>(
this IDatabaseTablesSettings<TDbContext> settings,
PathString path = default)
where TDbContext : DbContext =>
new MiddlewareRoute<TablesWithSizeAndRowsMiddleware<TDbContext>, TDbContext>(
settings: settings,
path: path,
methodName: HttpMethods.Post,
defaultPathRoute: DefaultTablesMetaRoute).Setup();

/// <summary>
/// Executes any changing SQL command. POST /database-sql-endpoints/execute is a default route.
Expand All @@ -81,13 +95,11 @@ public static IDatabaseTablesSettings<TDbContext> UseReadEndpoint<TDbContext>(
public static IDatabaseTablesSettings<TDbContext> UseExecuteEndpoint<TDbContext>(
this IDatabaseTablesSettings<TDbContext> settings,
PathString path = default)
where TDbContext : DbContext
{
return new MiddlewareRoute<ExecuteSQlMiddleware<TDbContext>, TDbContext>(
where TDbContext : DbContext =>
new MiddlewareRoute<ExecuteSQlMiddleware<TDbContext>, TDbContext>(
settings: settings,
path: path,
methodName: HttpMethods.Post,
defaultPathRoute: DefaultExecuteRoute).Setup();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<LangVersion>latest</LangVersion>
<Version>1.0.2</Version>
<Version>1.0.3</Version>
<Company>@maximgorbatyuk</Company>
<Copyright>Copyright © @maximgorbatyuk</Copyright>
<RepositoryUrl>https://github.com/maximgorbatyuk/MaximGorbatyuk.DatabaseSqlEndpoints</RepositoryUrl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<package >
<metadata>
<id>MaximGorbatyuk.DatabaseSqlEndpoints</id>
<version>1.0.2</version>
<version>1.0.3</version>
<title>MaximGorbatyuk.DatabaseSqlEndpoints for executing SQL commands</title>
<authors>@maximgorbatyuk</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
Expand Down
5 changes: 4 additions & 1 deletion src/MaximGorbatyuk.DatabaseSqlEndpoints/MiddlewareRoute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ public MiddlewareRoute(

public IDatabaseTablesSettings<TDbContext> Setup()
{
_settings.App.MapWhen(Condition, b => b.UseMiddleware<TMiddleware>(Options.Create((IDatabaseTablesSettingsBase)_settings)));
_settings.App.MapWhen(
Condition,
b => b.UseMiddleware<TMiddleware>(
Options.Create((IDatabaseTablesSettingsBase)_settings)));
return _settings;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ private static SqlRequest DeserializeOrFail(string source)
}
}

protected abstract Task<string> ResponseContentAsync(string query, HttpContext httpContext, TDbContext context);
protected abstract Task<string> ResponseContentAsync(
string query,
HttpContext httpContext,
TDbContext context);

public record SqlRequest
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@ namespace MaximGorbatyuk.DatabaseSqlEndpoints.Middlewares
public abstract class DatabaseTableBaseMiddleware<TDbContext>
where TDbContext : DbContext
{
protected const string DefaultContentType = "text/plain; charset=UTF-8";

private readonly RequestDelegate _next;
private readonly string _contentType;

protected IDatabaseTablesSettingsBase Settings { get; }

protected DatabaseTableBaseMiddleware(RequestDelegate next, IOptions<IDatabaseTablesSettingsBase> settingsBase, string contentType = "text/plain; charset=UTF-8")
protected DatabaseTableBaseMiddleware(
RequestDelegate next,
IOptions<IDatabaseTablesSettingsBase> settingsBase,
string contentType = DefaultContentType)
{
_next = next;
_contentType = contentType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ namespace MaximGorbatyuk.DatabaseSqlEndpoints.Middlewares
public class ReadSQlMiddleware<TDbContext> : BasePostRequestMiddleware<TDbContext>
where TDbContext : DbContext
{
public ReadSQlMiddleware(RequestDelegate next, IOptions<IDatabaseTablesSettingsBase> settingsBase)
public ReadSQlMiddleware(
RequestDelegate next,
IOptions<IDatabaseTablesSettingsBase> settingsBase)
: base(next, settingsBase)
{
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;

namespace MaximGorbatyuk.DatabaseSqlEndpoints.Middlewares
{
public class TablesWithSizeAndRowsMiddleware<TDbContext> : DatabaseTableBaseMiddleware<TDbContext>
where TDbContext : DbContext
{
internal const string SqlServerQuery = @"
SELECT
t.NAME AS TableName,
s.Name AS SchemaName,
p.rows,
SUM(a.total_pages) * 8 AS TotalSpaceKB,
CAST(ROUND(((SUM(a.total_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS TotalSpaceMB,
SUM(a.used_pages) * 8 AS UsedSpaceKB,
CAST(ROUND(((SUM(a.used_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS UsedSpaceMB,
(SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB,
CAST(ROUND(((SUM(a.total_pages) - SUM(a.used_pages)) * 8) / 1024.00, 2) AS NUMERIC(36, 2)) AS UnusedSpaceMB
FROM
sys.tables t
INNER JOIN
sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN
sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN
sys.allocation_units a ON p.partition_id = a.container_id
LEFT OUTER JOIN
sys.schemas s ON t.schema_id = s.schema_id
WHERE
t.NAME NOT LIKE 'dt%'
AND t.is_ms_shipped = 0
AND i.OBJECT_ID > 255
GROUP BY
t.Name, s.Name, p.Rows
ORDER BY
TotalSpaceMB DESC, t.Name";

public TablesWithSizeAndRowsMiddleware(
RequestDelegate next,
IOptions<IDatabaseTablesSettingsBase> settingsBase,
string contentType = DefaultContentType)
: base(next, settingsBase, contentType)
{
}

protected override async Task<string> ResponseContentAsync(
HttpContext httpContext,
TDbContext context)
{
return new DataTableTextOutput(
await new ReadTableSqlCommand<TDbContext>(
Query(),
context,
Settings.TimeoutSec)
.AsDataTableAsync())
.AsText();
}

private string Query() =>
Settings.SqlEngine switch
{
SqlEngine.MSSQL => SqlServerQuery,
_ => throw new NotSupportedException(
$"Sql engine {Settings.SqlEngine} is not supported")
};
}
}

0 comments on commit 4bfb8ef

Please sign in to comment.