223 lines
9.1 KiB
C#
223 lines
9.1 KiB
C#
using DocumentFormat.OpenXml.Drawing.Charts;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using NPOI.SS.Formula.Functions;
|
|
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
|
|
using Sarand.BusinessMgr.Net.Standard.Dbas.Consoles;
|
|
using Sarand.BusinessMgr.Web.Control.Components;
|
|
using Sarand.BusinessMgr.Web.Control.Consoles;
|
|
using Sarand.BusinessMgr.Web.Control.Models.Instance;
|
|
using Sarand.Net.Standard.Base.App;
|
|
using Sarand.Net.Standard.Base.Bus;
|
|
using Sarand.Net.Standard.Base.Core;
|
|
using Sarand.Net.Standard.Base.Dbas;
|
|
using Sarand.Net.Standard.Base.Utils;
|
|
using Sarand.Net.Standard.Dbas.Base;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
|
|
{
|
|
//=======================================================================
|
|
partial class RepositoryDatabaseController
|
|
{
|
|
//-------------------------------------------------------------------
|
|
// Definitions.
|
|
|
|
// Core Database Table list data.
|
|
private class TableListData : AjaxResponse_Data.ItemData_Base
|
|
{
|
|
public String SchemaName { get; set; }
|
|
public String TableName { get; set; }
|
|
public long? ColumnCount { get; set; }
|
|
public long? IndexCount { get; set; }
|
|
public long? RowCount { get; set; }
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Get Core Database Table list ajax request.
|
|
//-------------------------------------------------------------------
|
|
private class AjaxResponse_RepositoryTableList : AjaxResponse_Data
|
|
{
|
|
// Construction.
|
|
public AjaxResponse_RepositoryTableList(SbmModel_Control model) : base(model) { }
|
|
// Table list.
|
|
public List<TableListData> Tables { get; } = new List<TableListData>();
|
|
}
|
|
//-------------------------------------------------------------------
|
|
[HttpPost]
|
|
[Route("Instance/Repository/Ajax/GetTableList")]
|
|
[Route("Instance/Repository/Ajax/GetTables")]
|
|
public IActionResult Ajax_GetTableList(Model_RepositoryDatabase model)
|
|
{
|
|
String messageTitle = Localiser["label.database"];
|
|
AjaxResponse_RepositoryTableList responseData = new AjaxResponse_RepositoryTableList(model);
|
|
|
|
// Validate session and referrer.
|
|
if (!ValidReferer) return Forbid();
|
|
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
|
RefreshModel(model);
|
|
|
|
// Record disposable items as they are created so all can be disposed when needed.
|
|
using (DisposableCollection<ISacsDisposable> disposables = new DisposableCollection<ISacsDisposable>())
|
|
{
|
|
|
|
// Validate Repository.
|
|
SessionData_Control.Profile.Filter.RepositoryContext = model.DatabaseFilter.Context;
|
|
if (StringUtil.IsBlank(model.DatabaseFilter.Context))
|
|
{
|
|
SaLogger.Warn($"{SysUtil.Fn} Repository Context not supplied.");
|
|
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
|
|
}
|
|
SbmcRepository repository = ControlInstanceMgr.GetRepositoryByContext(model.DatabaseFilter.Context);
|
|
if (repository == null)
|
|
{
|
|
SaLogger.Warn($"{SysUtil.Fn} Repository does not exist. Context: {model.DatabaseFilter.Context}.");
|
|
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
|
|
}
|
|
|
|
// Repository Console.
|
|
SbmCoreInstanceConsole_Control instanceConsole = new SbmCoreInstanceConsole_Control(SessionData_Control, repository);
|
|
disposables.Add(instanceConsole);
|
|
|
|
// Columns.
|
|
String colSchemaName = "SchemaName";
|
|
String colTableName = "TableName";
|
|
String colColumnCount = "ColumnCount";
|
|
String colIndexCount = "IndexCount";
|
|
String colRowCount = "RowCount";
|
|
|
|
// Table filter.
|
|
List<String> filter = new List<string>();
|
|
if (!StringUtil.IsBlank(model.DatabaseFilter.Search))
|
|
filter.Add($"tbl.name Like '%{DbQuery.FormatForLike(model.DatabaseFilter.Search)}%'");
|
|
if (!filter.Any()) filter.Add("1=1");
|
|
|
|
// Construction query.
|
|
List<String> sql = new List<string>()
|
|
{
|
|
$"Select Top 2000",
|
|
$"[{colSchemaName}]=sch.name, [{colTableName}]=tbl.name,",
|
|
$"[{colColumnCount}]=(Select Count(*) From sys.columns col Where col.object_id=tbl.object_id),",
|
|
$"[{colIndexCount}]=(Select Count(*) From sys.indexes idx Where idx.object_id=tbl.object_id),",
|
|
$"[{colRowCount}]=(Select Sum(ptn.rows) From sys.partitions ptn Where ptn.object_id=tbl.object_id And ptn.index_id<2)",
|
|
$"From sys.tables tbl",
|
|
$"Left Join sys.schemas sch On sch.schema_id=tbl.schema_id",
|
|
$"Where tbl.type='U' And {filter.Concat(" And ","(",")")}",
|
|
$"Order By tbl.name, sch.name;"
|
|
};
|
|
|
|
// Query items.
|
|
using (DbResultSet resultSet = instanceConsole.Database.ExecuteQuery(String.Join("\n", sql)))
|
|
{
|
|
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
|
|
{
|
|
NamedValue.Map values = resultSet.GetRecordValues();
|
|
TableListData tableData = new TableListData()
|
|
{
|
|
SchemaName = values.GetString(colSchemaName),
|
|
TableName = values.GetString(colTableName),
|
|
ColumnCount = values.GetLong(colColumnCount),
|
|
IndexCount = values.GetLong(colIndexCount),
|
|
RowCount = values.GetLong(colRowCount),
|
|
};
|
|
responseData.Tables.Add(tableData);
|
|
}
|
|
}
|
|
if (model.Paging.IsPaged)
|
|
model.Paging.ItemCount = (ushort)responseData.Tables.Count;
|
|
}
|
|
|
|
// Complete response.
|
|
responseData.SetPaging(model);
|
|
responseData.Success = true;
|
|
return Json(responseData);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Populate Repository Database Indices ajax request.
|
|
//-------------------------------------------------------------------
|
|
private class AjaxResponse_RepositoryIndexPopulation : AjaxResponse_Data
|
|
{
|
|
// Construction.
|
|
public AjaxResponse_RepositoryIndexPopulation(SbmModel_Control model) : base(model) { }
|
|
// Stats.
|
|
public class StatsData
|
|
{
|
|
public int? PrimaryIndicesCreated { get; set; }
|
|
public int? IndicesCreated { get; set; }
|
|
public int? IndicesDropped { get; set; }
|
|
}
|
|
public StatsData Stats { get; } = new StatsData();
|
|
}
|
|
//-------------------------------------------------------------------
|
|
[HttpPost]
|
|
[Route("Instance/Repository/Ajax/PopulateIndices")]
|
|
public IActionResult Ajax_PopulateRepositoryDatabaseIndices(Model_RepositoryDatabase model)
|
|
{
|
|
String messageTitle = Localiser["label.database"];
|
|
AjaxResponse_RepositoryIndexPopulation responseData = new AjaxResponse_RepositoryIndexPopulation(model);
|
|
|
|
// Validate session and referrer.
|
|
if (!ValidReferer) return Forbid();
|
|
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
|
RefreshModel(model);
|
|
|
|
// Record disposable items as they are created so all can be disposed when needed.
|
|
using (DisposableCollection<ISacsDisposable> disposables = new DisposableCollection<ISacsDisposable>())
|
|
{
|
|
|
|
// Validate Repository.
|
|
SessionData_Control.Profile.Filter.RepositoryContext = model.DatabaseFilter.Context;
|
|
if (StringUtil.IsBlank(model.DatabaseFilter.Context))
|
|
{
|
|
SaLogger.Warn($"{SysUtil.Fn} Repository Context not supplied.");
|
|
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
|
|
}
|
|
SbmcRepository repository = ControlInstanceMgr.GetRepositoryByContext(model.DatabaseFilter.Context);
|
|
if (repository == null)
|
|
{
|
|
SaLogger.Warn($"{SysUtil.Fn} Repository does not exist. Context: {model.DatabaseFilter.Context}.");
|
|
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
|
|
}
|
|
|
|
// Repository Console.
|
|
SbmCoreInstanceConsole_Control instanceConsole = new SbmCoreInstanceConsole_Control(SessionData_Control, repository);
|
|
disposables.Add(instanceConsole);
|
|
|
|
SbmDatabaseConsole dbConsole = new SbmDatabaseConsole(instanceConsole.Internals.SessionContext);
|
|
|
|
// Populate indices.
|
|
SaLogger.Info($"{SysUtil.Fn} Populating indices for Repository Context '{model.DatabaseFilter.Context}'.", true);
|
|
SacsDatabaseConsole.IndexStats indexStats = new SacsDatabaseConsole.IndexStats();
|
|
dbConsole.InstallDbIndices(indexStats);
|
|
if (dbConsole.HasErrorState())
|
|
return Json(responseData.SetMessage(messageTitle, $"Error encountered: {dbConsole.ErrorStateMessage.Trim('.')}."));
|
|
|
|
// Statistics.
|
|
if (indexStats.PrimaryIndicesCreated > 0)
|
|
responseData.Stats.PrimaryIndicesCreated = indexStats.PrimaryIndicesCreated;
|
|
if (indexStats.IndicesCreated > 0)
|
|
responseData.Stats.IndicesCreated = indexStats.IndicesCreated;
|
|
if (indexStats.IndicesDropped > 0)
|
|
responseData.Stats.IndicesDropped = indexStats.IndicesDropped;
|
|
List<String> statsOutput = new List<string>();
|
|
if (indexStats.PrimaryIndicesCreated > 0)
|
|
statsOutput.Add($"Primary Created: {indexStats.PrimaryIndicesCreated}.");
|
|
if (indexStats.IndicesCreated > 0)
|
|
statsOutput.Add($"Indices Created: {indexStats.IndicesCreated}.");
|
|
if (indexStats.IndicesDropped > 0)
|
|
statsOutput.Add($"Indices dropped: {indexStats.IndicesDropped}.");
|
|
responseData.SetMessage(messageTitle, $"Indices populated.\n{statsOutput.Concat("", "\n")}");
|
|
}
|
|
|
|
// Complete response.
|
|
responseData.Success = true;
|
|
return Json(responseData);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
}
|
|
//=======================================================================
|
|
}
|