3.0.0.1 Demo repository registration

This commit is contained in:
Andy Howard
2025-02-08 16:41:08 +00:00
parent 0d8e7d5619
commit c4e5712d0a
312 changed files with 13145 additions and 30232 deletions
@@ -107,7 +107,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
};
// Query items.
using (DbResultSet resultSet = instanceConsole.Database_Core.ExecuteQuery(String.Join("\n", sql)))
using (DbResultSet resultSet = instanceConsole.Database.ExecuteQuery(String.Join("\n", sql)))
{
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
{
@@ -6,6 +6,7 @@ using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
using Sarand.BusinessMgr.Net.Standard.Base.Consoles;
using Sarand.BusinessMgr.Net.Standard.Base.Data;
using Sarand.BusinessMgr.Web.Control.Components;
using Sarand.BusinessMgr.Web.Control.Consoles;
using Sarand.BusinessMgr.Web.Control.Models.Instance;
@@ -135,12 +136,12 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
// Query Organisations.
SbmAssociation.Params prm = new SbmAssociation.Params();
prm.AssociationType = Sbm.AssociationType.Internal;
prm.StatusCat = SbmAssociation.StatusCat.Current;
foreach (SbmAssociation association in instanceConsole.Internals_Core.AccountMgr.GetAssociationList(prm))
prm.StatusCat = SbmAssociation.StatusCat.CurrentOnly;
foreach (SbmAssociation association in instanceConsole.Internals.AccountMgr.GetAssociationList(prm))
{
// Retrieve Organisation details.
disposables.Add(association);
SbmAffiliate affiliateOrganisation = instanceConsole.Internals_Core.AccountMgr.GetAffiliateById(association.AffiliateIdOwner);
SbmAffiliate affiliateOrganisation = instanceConsole.Internals.AccountMgr.GetAffiliateById(association.AffiliateIdOwner);
disposables.Add(affiliateOrganisation);
// Organisation details.
@@ -159,19 +160,19 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
prmAffiliateUser.AffiliateIdAssocOwner = affiliateOrganisation.Id;
prmAffiliateUser.AssociationType = Sbm.AssociationType.Member;
prmAffiliateUser.StatusCat = SbmAffiliate.StatusCat.CurrentOnly;
prmAffiliateUser.SortColumns.Add(instanceConsole.Internals_Core.AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Id));
foreach (SbmAffiliate affiliateUser in instanceConsole.Internals_Core.AccountMgr.GetAffiliateList(prmAffiliateUser))
prmAffiliateUser.SortColumns.Add(instanceConsole.Internals.AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Id));
foreach (SbmAffiliate affiliateUser in instanceConsole.Internals.AccountMgr.GetAffiliateList(prmAffiliateUser))
{
disposables.Add(affiliateUser);
// Lookup security details.
if (!SysId.IsValid(affiliateUser.UserId)) continue;
SaSecurityItem securityItemUser = instanceConsole.Internals_Core.SecurityConsole.GetSecurityItemById(SaSecurity.ItemType.User, affiliateUser.UserId);
SaSecurityItem securityItemUser = instanceConsole.Internals.SecurityConsole.GetSecurityItemById(SaSecurity.ItemType.User, affiliateUser.UserId);
disposables.Add(securityItemUser);
if (securityItemUser == null) continue;
// Confirm security rights (SuperUser).
SaSecurityProfile securityProfile = instanceConsole.Internals_Core.SecurityConsole.GetUserSecurityProfile(securityItemUser.Id);
SaSecurityProfile securityProfile = instanceConsole.Internals.SecurityConsole.GetUserSecurityProfile(securityItemUser.Id);
if (!securityProfile.Groups.Any(group => group.Code.EqualsCI(SaSecurityConsole.GroupCode_Super))) continue;
// Add User to the Organisation.
@@ -252,7 +253,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
}
// Validate Organisation Affiliate.
SbmAffiliate affiliateOrganisation = instanceConsole.Internals_Core.AccountMgr.GetAffiliateById(affiliateIdOrganisation);
SbmAffiliate affiliateOrganisation = instanceConsole.Internals.AccountMgr.GetAffiliateById(affiliateIdOrganisation);
disposables.Add(affiliateOrganisation);
if (affiliateOrganisation == null)
{
@@ -276,7 +277,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
else
{
// Validate Internal Association.
SbmAssociation associationOrganisation = instanceConsole.Internals_Core.AccountMgr.GetAssociationById(associationIdInternal);
SbmAssociation associationOrganisation = instanceConsole.Internals.AccountMgr.GetAssociationById(associationIdInternal);
disposables.Add(associationOrganisation);
if (associationOrganisation == null)
{
@@ -303,12 +304,12 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
else
{
// Organisation does not exist.
if (!SysId.IsValid(SysId.ToSysId(model.Organisation.AffiliateId)))
if (SysId.IsValid(SysId.ToSysId(model.Organisation.AffiliateId)))
{
SaLogger.Warn($"{SysUtil.Fn} Affiliate Id specified for new Organisation. Id: {model.Organisation.AffiliateId}.");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
if (!SysId.IsValid(SysId.ToSysId(model.Organisation.AssociationId)))
if (SysId.IsValid(SysId.ToSysId(model.Organisation.AssociationId)))
{
SaLogger.Warn($"{SysUtil.Fn} Association Id specified for new Organisation. Id: {model.Organisation.AssociationId}.");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
@@ -327,7 +328,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
}
// Validate User Affiliate.
SbmAffiliate affiliateUser = instanceConsole.Internals_Core.AccountMgr.GetAffiliateById(affiliateIdUser);
SbmAffiliate affiliateUser = instanceConsole.Internals.AccountMgr.GetAffiliateById(affiliateIdUser);
disposables.Add(affiliateUser);
if (affiliateUser == null)
{
@@ -350,7 +351,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
else
{
// Validate User Security Item.
SaSecurityItem securityItemUser = instanceConsole.Internals_Core.SecurityConsole.GetSecurityItemById(SaSecurity.ItemType.User, secItemIdUser);
SaSecurityItem securityItemUser = instanceConsole.Internals.SecurityConsole.GetSecurityItemById(SaSecurity.ItemType.User, secItemIdUser);
disposables.Add(securityItemUser);
if (securityItemUser == null)
{
@@ -367,12 +368,12 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
else
{
// User does not exist.
if (!SysId.IsValid(SysId.ToSysId(model.User.AffiliateId)))
if (SysId.IsValid(SysId.ToSysId(model.User.AffiliateId)))
{
SaLogger.Warn($"{SysUtil.Fn} Affiliate Id specified for new User. Id: {model.User.AffiliateId}.");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
if (!SysId.IsValid(SysId.ToSysId(model.User.SecurityItemId)))
if (SysId.IsValid(SysId.ToSysId(model.User.SecurityItemId)))
{
SaLogger.Warn($"{SysUtil.Fn} Security Item Id specified for new User. Id: {model.User.SecurityItemId}.");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
@@ -388,7 +389,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
SbmCoreInstanceConsole_Control repositoryConsole = new SbmCoreInstanceConsole_Control(SessionData_Control, repository);
disposables.Add(repositoryConsole);
SbmCoreInstanceConsole_Base.RepositoryInitialisationData repoInitData = new SbmCoreInstanceConsole_Base.RepositoryInitialisationData();
SbmRepositoryInitialisationData repoInitData = new SbmRepositoryInitialisationData();
repoInitData.Organisation.AffiliateId = SysId.ToSysId(model.Organisation.AffiliateId);
repoInitData.Organisation.AssociationId = SysId.ToSysId(model.Organisation.AssociationId);
repoInitData.Organisation.Name = model.Organisation.Name;
@@ -400,7 +401,8 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
repoInitData.User.LastName = model.User.LastName;
repoInitData.User.Email = model.User.Email;
repoInitData.User.SecurityItemId = SysId.ToSysId(model.User.SecurityItemId);
repoInitData.User.Code = model.User.Code;
// User Email is used for the Security Item Code for login.
repoInitData.User.Code = model.User.Email;
repoInitData.User.Password = model.User.Password;
repoInitData.User.PasswordSet = StringUtil.ToBool(model.User.PasswordSet);
if (!repositoryConsole.InitialiseRepository(repoInitData))
@@ -0,0 +1,489 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using NPOI.SS.Formula.Functions;
using Sarand.BusinessMgr.Net.Core.Web.App;
using Sarand.BusinessMgr.Net.Standard.Dbas.App;
using Sarand.BusinessMgr.Web.Control.Components;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
using Sarand.Net.Standard.Base.Helpers;
using Sarand.Net.Standard.Base.Utils;
using Sarand.Net.Standard.Dbas.Data;
using Sarand.Net.Standard.Dbas.Proc;
using System.Collections.Generic;
using System;
using Sarand.BusinessMgr.Web.Control.Models.System;
using Sarand.BusinessMgr.Net.Standard.Base.App;
using DocumentFormat.OpenXml.EMMA;
using System.Linq;
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
using Sarand.Net.Standard.Dbas.Base;
using Sarand.BusinessMgr.Web.Control.Consoles;
using System.Reflection;
using static Sarand.BusinessMgr.Net.Standard.Dbas.Utils.SbmDbDfnGenerator;
using Sarand.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Dbas.Consoles;
namespace Sarand.BusinessMgr.Web.Control.Controllers.System
{
//======================================================================
// System Controller - Ajax - Database.
//======================================================================
partial class SystemController
{
//-------------------------------------------------------------------
// Database data.
private class DatabaseTableData
{
public String SchemaName { get; set; }
public String TableName { get; set; }
public String QualifiedName { get; set; }
public int RowCount { get; set; }
public int ColumnCount { get; set; }
public int IndexCount { get; set; }
}
//-------------------------------------------------------------------
// Get Database Table List ajax request.
//-------------------------------------------------------------------
private class AjaxResponse_DatabaseTableList : AjaxResponse_Data
{
// Construction.
public AjaxResponse_DatabaseTableList(SbmModel_Control model) : base(model) { }
// Table list.
public List<DatabaseTableData> Tables { get; } = new List<DatabaseTableData>();
}
//-------------------------------------------------------------------
[HttpPost]
[Route("System/Ajax/GetDatabaseTables")]
public IActionResult Ajax_GetDatabaseTables(Model_System model)
{
String messageTitle = Localiser["system.caption.database"];
AjaxResponse_DatabaseTableList responseData = new AjaxResponse_DatabaseTableList(model);
// Validate session.
if (!ValidUserSession)
return GetAjaxResult_InvalidSession(responseData);
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsDisposable> disposableItems = new DisposableCollection<SacsDisposable>())
{
// Database connection.
Sbm.Database databaseInstance = EnumUtil.ParseEnum(StringUtil.EmptyOnNull(model.DatabaseFilter.Instance), Sbm.Database.Unknown);
if (databaseInstance <= 0)
return Json(responseData.SetMessage(messageTitle, $"Database instance must be specified."));
ISacsDatabase db = GetDatabase(databaseInstance);
if (db == null)
return Json(responseData.SetMessage(messageTitle, $"Database unavailable for instance '{databaseInstance}'."));
// Database table row counts.
Dictionary<String, int> tableRowCounts = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
String query =
"SELECT QUOTENAME(SCHEMA_NAME(sOBJ.schema_id)) + '.' + QUOTENAME(sOBJ.name) As [TableName], SUM(sPTN.Rows) As [RowCount] " +
"FROM sys.objects AS sOBJ " +
"INNER JOIN sys.partitions AS sPTN ON sOBJ.object_id = sPTN.object_id " +
"WHERE sOBJ.type = 'U' AND sOBJ.is_ms_shipped = 0x0 AND index_id< 2 /*Index Id: 0:Heap,1:Clustered*/ " +
"GROUP BY sOBJ.schema_id, sOBJ.name";
using (DbResultSet dbResultSet = DbResultSet_DataReader.ExecuteQuery(db, query))
{
while (dbResultSet != null && dbResultSet.NextRecord())
{
tableRowCounts.Add(dbResultSet.GetRecordValues().GetValue("TableName").ToString(), (int)dbResultSet.GetRecordValues().GetValue("RowCount").AsLong());
}
}
// Database tables.
List<DbDfnTable> tableDfns = db.GetTableDfns();
foreach (DbDfnTable tableDfn in tableDfns.OrderBy(item => item.Name))
{
// Filter by table name.
if (!StringUtil.IsEmpty(model.DatabaseFilter.Search) && !tableDfn.Name.ContainsCI(model.DatabaseFilter.Search))
continue;
DatabaseTableData tableData = new DatabaseTableData();
tableData.SchemaName = tableDfn.Schema;
tableData.TableName = tableDfn.Name;
tableData.QualifiedName = tableDfn.QualifiedName;
tableData.ColumnCount = tableDfn.ColumnCount;
tableData.IndexCount = tableDfn.IndexCount;
// Row count.
tableData.RowCount = tableRowCounts.GetValueOrDefault(tableDfn.QuotedQualifiedName, 0);
responseData.Tables.Add(tableData);
}
}
// Complete response.
responseData.Success = true;
return Json(responseData);
}
//-------------------------------------------------------------------
/// <summary>
/// Get database by type.
/// </summary>
private ISacsDatabase GetDatabase(Sbm.Database databaseInstance)
{
switch (databaseInstance)
{
case Sbm.Database.Control:
return App.GetControlDatabase();
case Sbm.Database.Template:
return GetDatabaseByContext(Sbm.RepositoryContext_Template);
case Sbm.Database.Demo:
return GetDatabaseByContext(Sbm.RepositoryContext_Demo);
}
return null;
}
/// <summary>
/// Get database by Instance Context.
/// </summary>
private ISacsDatabase GetDatabaseByContext(String instanceContext)
{
SbmcRepository repository = ControlInstanceMgr.GetRepositoryByContext(instanceContext);
if (repository != null)
{
SacsDatabaseConsole.OdbcConfig config = SbmCoreInstanceConsole_Dbas.GetRepositoryOdbcConfig(repository);
return SacsDatabaseConsole.OpenOdbcDatabase(config);
}
return null;
}
//-------------------------------------------------------------------
// Validate Database Schema ajax request.
//-------------------------------------------------------------------
private class DbSchemaItemResponseData
{
public int Id { get; set; }
public String SchemaName { get; set; }
public String TableName { get; set; }
public String ColumnName { get; set; }
public int ColumnPosition { get; set; }
public String IndexName { get; set; }
public String Comment { get; set; }
}
private class AjaxResponse_ValidateDatabaseSchema : AjaxResponse_Data
{
// Construction.
public AjaxResponse_ValidateDatabaseSchema(SbmModel_Control model) : base(model) { }
// Database instance.
public String Instance { get; set; }
// Schema validation list.
public List<DbSchemaItemResponseData> Items { get; } = new List<DbSchemaItemResponseData>();
}
//-------------------------------------------------------------------
[HttpPost]
[Route("System/Ajax/ValidateDatabaseSchema")]
public IActionResult Ajax_ValidateDatabaseSchema(Model_System model)
{
String messageTitle = Localiser["system.caption.database"];
AjaxResponse_ValidateDatabaseSchema responseData = new AjaxResponse_ValidateDatabaseSchema(model);
// Validate session.
if (!ValidUserSession)
return GetAjaxResult_InvalidSession(responseData);
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsDisposable> disposableItems = new DisposableCollection<SacsDisposable>())
{
// Database instance.
Sbm.Database databaseInstance = EnumUtil.ParseEnum(StringUtil.EmptyOnNull(model.DatabaseFilter.Instance), Sbm.Database.Unknown);
if (databaseInstance <= 0)
return Json(responseData.SetMessage(messageTitle, "Database instance must be specified"));
responseData.Instance = databaseInstance.ToString();
// Database connection.
ISacsDatabase db = GetDatabase(databaseInstance);
if (db == null)
return Json(responseData.SetMessage(messageTitle, $"Unrecognised database instance specified: '{model.DatabaseFilter.Instance}'."));
// Retrieve XML database schema definition.
Dictionary<String, String> xmlSchemas = GetSmlSchema(databaseInstance);
if (!xmlSchemas.Any())
return Json(responseData.SetMessage(messageTitle, "Failed to extract XML schema definitions."));
// Extract schema from XML definition.
SaDbProcess_ConvertDbSchema.Config cfgSchemaConvert = new SaDbProcess_ConvertDbSchema.Config();
SaDbProcess_ConvertDbSchema procSchemaConvert = new SaDbProcess_ConvertDbSchema(cfgSchemaConvert);
List<DbDfnTable> tables = new List<DbDfnTable>();
foreach (String schemaName in xmlSchemas.Keys)
{
String xmlSchema = xmlSchemas[schemaName];
foreach (DbDfnTable table in procSchemaConvert.ConvertXmlToTables(xmlSchema))
{
if (tables.Any(item => item.Matches(table)))
{
SaLogger.Debug($"{SysUtil.Fn} Duplicate table '{table.QualifiedName}' found in schema '{schemaName}'.");
continue;
}
tables.Add(table);
}
if (procSchemaConvert.HasErrorMessage())
return Json(responseData.SetMessage(messageTitle, $"Failed to convert XML schema '{schemaName}': {procSchemaConvert.GetErrorMessage().TrimEnd('.')}."));
}
SaDbProcess_CompareDatabaseSchemas.Config cfgSchemaCompare = new SaDbProcess_CompareDatabaseSchemas.Config(tables, db);
cfgSchemaCompare.HideIdenticalObjects = true;
cfgSchemaCompare.IgnorePosition = true;
SaDbProcess_CompareDatabaseSchemas procSchemaCompare = new SaDbProcess_CompareDatabaseSchemas(cfgSchemaCompare);
procSchemaCompare.OnSchemaComparisonItemAdded += OnSchemaComparisonItemAdded;
procSchemaCompare.RunProcess();
List<SaDbProcess_CompareDatabaseSchemas.SchemaComparisonItem> schemaComparisonItems = procSchemaCompare.GetSchemaComparisonItems();
foreach (SaDbProcess_CompareDatabaseSchemas.SchemaComparisonItem schemaComparisonItem in schemaComparisonItems)
{
DbSchemaItemResponseData item = new DbSchemaItemResponseData()
{
Id = schemaComparisonItem.Id,
SchemaName = schemaComparisonItem.SchemaName,
TableName = schemaComparisonItem.TableName,
ColumnName = schemaComparisonItem.ColumnName,
ColumnPosition = schemaComparisonItem.ColumnPosition,
IndexName = schemaComparisonItem.IndexName,
Comment = schemaComparisonItem.Comment
};
responseData.Items.Add(item);
}
}
// Complete response.
responseData.Success = true;
return Json(responseData);
}
private Dictionary<String, String> GetSmlSchema(Sbm.Database databaseInstance)
{
Dictionary<String, String> schemas = new Dictionary<String, String>();
switch (databaseInstance)
{
case Sbm.Database.Control:
{
var assembly = typeof(SbmSystem_Dbas).GetTypeInfo().Assembly;
schemas.Add("SbmDbDfn_Control.xml", SacsResourceHelper.GetManifestResourceAsText(assembly, "", "SbmDbDfn_Control.xml"));
break;
}
case Sbm.Database.Template:
case Sbm.Database.Demo:
{
var assembly = typeof(SbmSystem_Dbas).GetTypeInfo().Assembly;
schemas.Add("SbmDbDfn.xml", SacsResourceHelper.GetManifestResourceAsText(assembly, "", "SbmDbDfn.xml"));
assembly = typeof(SacsDatabase).GetTypeInfo().Assembly;
HashSet<String> schemaNames = new HashSet<String>()
{
// Originally included common database definitions but these tables are now in the main BusMgr schema definition.
//"SaSecurityDbDfn.xml","SaCodeTypeDbDfn.xml", "SaReferenceDataDbDfn.xml", "SaItemOptionDbDfn.xml",
//"SaInterfaceDbDfn.xml", "SaItemDataDbDfn.xml", "SaItemDocsDbDfn.xml", "SaUpdateLogDbDfn.xml"
};
foreach (String schemaName in schemaNames)
schemas.Add(schemaName, SacsResourceHelper.GetManifestResourceAsText(assembly, "", schemaName));
break;
}
}
return schemas;
}
// Processing events.
public void OnSchemaComparisonItemAdded(object sender, SaDbProcess_CompareDatabaseSchemas.SchemaComparisonItemAddedEventArgs e)
{
SaDbProcess_CompareDatabaseSchemas proc = sender as SaDbProcess_CompareDatabaseSchemas;
}
//-------------------------------------------------------------------
// Database Table ajax request.
//-------------------------------------------------------------------
private class AjaxResponseData_Table
{
public AjaxResponseData_Table(DbDfnTable tableDfn)
{
Schema = tableDfn.Schema;
Name = tableDfn.Name;
if (!StringUtil.IsEmpty(tableDfn.Remarks))
Remarks = tableDfn.Remarks;
foreach (DbDfnColumn columnDfn in tableDfn.Columns)
Columns.Add(new AjaxResponseData_Column(columnDfn));
foreach (DbDfnIndex indexDfn in tableDfn.Indices)
Indices.Add(new AjaxResponseData_Index(indexDfn));
}
public String Schema { get; }
public String Name { get; }
public String QualifiedName { get { return (!StringUtil.IsEmpty(Schema) ? Schema + "." : "") + Name; } }
public String QuotedQualifiedName { get { return (!StringUtil.IsEmpty(Schema) ? "[" + Schema + "]." : "") + "[" + Name + "]"; } }
public String Remarks { get; set; } = String.Empty;
public List<AjaxResponse_Data.ItemLabelValue> Properties { get; } = new List<AjaxResponse_Data.ItemLabelValue>();
public List<AjaxResponseData_Column> Columns { get; } = new List<AjaxResponseData_Column>();
public List<AjaxResponseData_Index> Indices { get; } = new List<AjaxResponseData_Index>();
}
private class AjaxResponseData_Column
{
public int Pos { get; }
public String Name { get; }
public String Format { get; }
public String DataTypeName { get; }
public short? DataTypeNative { get; }
public String DataTypeNameNative { get; }
public bool? IsIdentity { get; }
public long? Size { get; }
public long? BufferLen { get; }
public short? DecimalDigits { get; }
public bool? Nullable { get; }
public bool? IsNullable { get; }
public String Remarks { get; }
public AjaxResponseData_Column(DbDfnColumn columnDfn)
{
Pos = columnDfn.Pos;
Name = columnDfn.Name;
Format = columnDfn.GetFormat();
if (!StringUtil.IsEmpty(columnDfn.DataTypeName))
DataTypeName = columnDfn.DataTypeName;
if (columnDfn.DataTypeNative > 0)
DataTypeNative = columnDfn.DataTypeNative;
if (!StringUtil.IsEmpty(columnDfn.DataTypeNameNative))
DataTypeNameNative = columnDfn.DataTypeNameNative;
if (columnDfn.IsIdentity)
IsIdentity = columnDfn.IsIdentity;
if (columnDfn.Size > 0)
Size = columnDfn.Size;
if (columnDfn.BufferLen > 0)
BufferLen = columnDfn.BufferLen;
if (columnDfn.DecimalDigits > 0)
DecimalDigits = columnDfn.DecimalDigits;
if (columnDfn.Nullable == DbColumnNullable.Nullable)
Nullable = true;
if (columnDfn.IsNullable)
IsNullable = columnDfn.IsNullable;
if (!StringUtil.IsEmpty(columnDfn.Remarks))
Remarks = columnDfn.Remarks;
}
}
private class AjaxResponseData_Index
{
public String Name { get; }
public int? IndexType { get; }
public bool? Unique { get; }
public bool? Primary { get; }
public bool? Clustered { get; }
public bool? Nullable { get; }
public int? Pages { get; }
public int? UniqueValues { get; }
public List<AjaxResponseData_IndexColumn> Columns { get; } = new List<AjaxResponseData_IndexColumn>();
public AjaxResponseData_Index(DbDfnIndex indexDfn)
{
Name = indexDfn.Name;
if (indexDfn.IndexType > 0)
IndexType = indexDfn.IndexType;
if (indexDfn.Unique)
Unique = indexDfn.Unique;
if (indexDfn.Primary)
Primary = indexDfn.Primary;
if (indexDfn.Clustered)
Clustered = indexDfn.Clustered;
if (indexDfn.Nullable)
Nullable = indexDfn.Nullable;
if (indexDfn.Pages > 0)
Pages = indexDfn.Pages;
if (indexDfn.UniqueValues > 0)
UniqueValues = indexDfn.UniqueValues;
foreach (DbDfnIndexColumn indexColumnDfn in indexDfn.Columns)
Columns.Add(new AjaxResponseData_IndexColumn(indexColumnDfn));
}
}
private class AjaxResponseData_IndexColumn
{
public short Seq { get; }
public String Name { get; }
public bool? Desc { get; }
public AjaxResponseData_IndexColumn(DbDfnIndexColumn indexColumnDfn)
{
Seq = indexColumnDfn.Seq;
Name = indexColumnDfn.Name;
if (!indexColumnDfn.Ascend)
Desc = true;
}
}
private class AjaxResponse_DatabaseTable : AjaxResponse_Data
{
// Construction.
public AjaxResponse_DatabaseTable(SbmModel_Control model) : base(model) { }
// Database table.
public String PopupTitle { get; set; }
public AjaxResponseData_Table Table { get; set; }
}
//-------------------------------------------------------------------
[HttpPost]
[Route("System/Ajax/GetDatabaseTable")]
public IActionResult Ajax_GetDatabaseTable(Model_System model)
{
String messageTitle = Localiser["system.caption.database"];
AjaxResponse_DatabaseTable responseData = new AjaxResponse_DatabaseTable(model);
// Validate session.
if (!ValidUserSession)
return GetAjaxResult_InvalidSession(responseData);
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsDisposable> disposableItems = new DisposableCollection<SacsDisposable>())
{
// Parameters.
if (StringUtil.IsEmpty(model.DatabaseTable.Name))
return Json(responseData.SetMessage(messageTitle, "Table name must be supplied."));
// Database instance.
Sbm.Database databaseInstance = EnumUtil.ParseEnum(StringUtil.EmptyOnNull(model.DatabaseTable.Instance), Sbm.Database.Unknown);
if (databaseInstance <= 0)
return Json(responseData.SetMessage(messageTitle, "Database instance must be specified"));
// Database connection.
ISacsDatabase db = GetDatabase(databaseInstance);
// Table definition.
DbDfnTable tableDfn = db.GetTableDfn(model.DatabaseTable.Name, true);
if (tableDfn == null)
return Json(responseData.SetMessage(messageTitle, "Invalid Table name supplied."));
// Populate table response.
responseData.Table = new AjaxResponseData_Table(tableDfn);
responseData.PopupTitle = Localiser["label.table"] + ": " + tableDfn.Name;
// Database sizing.
String query = "Exec sp_SpaceUsed [" + tableDfn.QualifiedName + "];";
using (DbResultSet dbResultSet = DbResultSet_DataReader.ExecuteQuery(db, query))
{
if (dbResultSet != null && dbResultSet.NextRecord())
{
// Row count.
long rows = StringUtil.ToLong(dbResultSet.GetRecordValues().GetValue("rows").ToString());
if (rows > 0)
responseData.Table.Properties.Add(new AjaxResponse_Data.ItemLabelValue() { Label = "Rows", Value = rows.ToString() });
// Reserved space.
String reserved = dbResultSet.GetRecordValues().GetValue("reserved").AsString();
if (!StringUtil.IsEmpty(reserved))
responseData.Table.Properties.Add(new AjaxResponse_Data.ItemLabelValue() { Label = "Reserved", Value = reserved });
// Data space.
String data = dbResultSet.GetRecordValues().GetValue("data").AsString();
if (!StringUtil.IsEmpty(data))
responseData.Table.Properties.Add(new AjaxResponse_Data.ItemLabelValue() { Label = "Data", Value = data });
// Index space.
String index = dbResultSet.GetRecordValues().GetValue("index_size").AsString();
if (!StringUtil.IsEmpty(index))
responseData.Table.Properties.Add(new AjaxResponse_Data.ItemLabelValue() { Label = "Indices", Value = index });
// Unused space.
String unused = dbResultSet.GetRecordValues().GetValue("unused").AsString();
if (!StringUtil.IsEmpty(unused))
responseData.Table.Properties.Add(new AjaxResponse_Data.ItemLabelValue() { Label = "Unused", Value = unused });
}
}
}
// Complete response.
responseData.Success = true;
return Json(responseData);
}
//-------------------------------------------------------------------
}
//======================================================================
}
@@ -0,0 +1,35 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Sarand.BusinessMgr.Net.Core.Web.App;
using Sarand.BusinessMgr.Web.Control.Components;
namespace Sarand.BusinessMgr.Web.Control.Controllers.System
{
//======================================================================
public partial class SystemController : SbmController_Control
{
//-------------------------------------------------------------------
// Data members.
//-------------------------------------------------------------------
// Construction.
public SystemController(SbmLocaliser localiser, ILogger<HomeController> logger) :
base(localiser, logger)
{
}
//-------------------------------------------------------------------
/// <summary>
/// System - Home.
/// <para>- No 'System' home page for now, redirect to home page.</para>
/// </summary>
[HttpGet]
public IActionResult Index()
{
return RedirectToAction("", "");
}
//-------------------------------------------------------------------
}
//======================================================================
}