Files
egtbeamwall/EgtBEAMWALL.DataLayer/Controllers/DbController.cs
T

230 lines
8.2 KiB
C#

using NLog;
using System;
using System.Linq;
using System.Threading;
namespace EgtBEAMWALL.DataLayer.Controllers
{
public class DbController : IDisposable
{
#region Public Fields
/// <summary>
/// Singleton gestione
/// </summary>
public static DbController man = new DbController();
#endregion Public Fields
#region Public Constructors
public DbController()
{
// Initialize database context for ADMIN
adbCtx = new AdminContext(DbConfig.ADMIN_CONNECTION_STRING);
// DB standard utente
dbCtx = new AdminContext(DbConfig.CONNECTION_STRING);
}
#endregion Public Constructors
#region Public Methods
/// <summary>
/// Verifica necessità creazione utente (locale o in rete)
/// </summary>
/// <param name="username"></param>
/// <param name="pwd"></param>
/// <param name="isNetwork"></param>
/// <returns></returns>
public bool checkCreateUser(string username, string pwd, bool isNetwork)
{
bool answ = false;
string domain = isNetwork ? "%" : "localhost";
answ = doCheckCreate(username, pwd, answ, domain, false);
if (answ)
{
doGrantPriv(username, domain, "ALL ON *.*");
}
return answ;
}
/// <summary>
/// Migrazione esplicita del DB da parte dell'admin controller
/// </summary>
/// <returns></returns>
public bool checkMigrateDb()
{
return adbCtx.SetUpDbConnectionAndDbConfig();
}
public void Dispose()
{
// Clear database context
adbCtx.Dispose();
}
/// <summary>
/// Verifica esistenza views + utente relativo eventualmente ricreandole + fornendo accesso
/// all'utente ReadOnly Essetre
/// </summary>
/// <param name="dbName"></param>
/// <param name="username"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public bool refreshViews(string dbName, string username = "S3_User", string pwd = "S3_P4ssw0rd")
{
bool answ = false;
// in primis refresh delle view
string sqlCommand = @"CREATE OR REPLACE VIEW v_expProdRaw AS
SELECT DbId, AlarmDtEvent AS DtEvent, VarValue,
SUBSTRING_INDEX(VarValue, ';', 1) AS Prod,
SUBSTRING_INDEX(SUBSTRING_INDEX(VarValue, ';', 2), ';', -1) AS MachGroupId,
SUBSTRING_INDEX(SUBSTRING_INDEX(VarValue, ';', -2), ';', 1) AS PartId,
SUBSTRING_INDEX(VarValue, ';', -1) AS Status
FROM logmachine
WHERE ResultType = 1
AND VarAddress = 1;
CREATE OR REPLACE VIEW v_expProd AS
SELECT vp.DtEvent, vp.Prod, mgl.Name AS mgName, pl.PDN, vp.`Status`
FROM v_expProdRaw AS vp
INNER JOIN MachGroupList mgl ON vp.MachGroupId = mgl.Id
INNER JOIN partlist pl ON vp.PartId = pl.Id;";
dbCtx.Database.ExecuteSqlCommand(System.Data.Entity.TransactionalBehavior.DoNotEnsureTransaction, sqlCommand);
Thread.Sleep(100);
// ora setup parametri x utente
string domain = "%";
// ora controllo utente con diritti
answ = doCheckCreate(username, pwd, answ, domain, true);
if (answ)
{
doGrantPriv(username, domain, "USAGE ON *.*");
doGrantPriv(username, domain, $"SELECT ON {dbName}.v_expProd");
}
return answ;
}
/// <summary>
/// ATTENZIONE!!!! Procedura di Reset del DB
/// </summary>
/// <returns></returns>
public bool ResetDb()
{
bool answ = false;
try
{
adbCtx
.Database
.SqlQuery<int>("CALL stp_ResetDb()");
answ = true;
adbCtx.SaveChanges();
}
catch (Exception exc)
{
string errMessage = $"EXCEPTION on DbController.ResetDb: {Environment.NewLine}{exc}";
Console.WriteLine(errMessage);
Log.Error(errMessage);
}
return answ;
}
#endregion Public Methods
#region Private Fields
private AdminContext adbCtx;
private AdminContext dbCtx;
/// <summary>
/// Istanza logger
/// </summary>
private NLog.Logger Log = NLog.LogManager
.Setup()
.LoadConfigurationFromFile(DbConfig.NLOG_PATH + @"\NLog.config")
.GetCurrentClassLogger();
#endregion Private Fields
#region Private Methods
/// <summary>
/// Procedura interna effettiva di check utente ed eventuale creazione + grant level
/// </summary>
/// <param name="username"></param>
/// <param name="pwd"></param>
/// <param name="answ"></param>
/// <param name="domain"></param>
/// <param name="force">Force = esegue un drop prima...</param>
/// <returns></returns>
private bool doCheckCreate(string username, string pwd, bool answ, string domain, bool force)
{
// ricerca utente...
var numUser = adbCtx
.UserList
.Where(x => x.User == username)
.ToList()
.Count;
if (numUser > 0)
{
answ = true;
}
if (!answ)
{
// creo utente
string sqlCommand = $"DROP USER IF EXISTS {username};";
if (force)
{
adbCtx.Database.ExecuteSqlCommand(System.Data.Entity.TransactionalBehavior.DoNotEnsureTransaction, sqlCommand);
Thread.Sleep(100);
}
sqlCommand = "FLUSH PRIVILEGES;";
adbCtx.Database.ExecuteSqlCommand(System.Data.Entity.TransactionalBehavior.DoNotEnsureTransaction, sqlCommand);
Thread.Sleep(100);
sqlCommand = $"CREATE USER '{username}'@'{domain}' IDENTIFIED BY '{pwd}';";
adbCtx.Database.ExecuteSqlCommand(System.Data.Entity.TransactionalBehavior.DoNotEnsureTransaction, sqlCommand);
Thread.Sleep(100);
sqlCommand = "FLUSH PRIVILEGES;";
adbCtx.Database.ExecuteSqlCommand(System.Data.Entity.TransactionalBehavior.DoNotEnsureTransaction, sqlCommand);
Thread.Sleep(100);
answ = true;
}
return answ;
}
/// <summary>
/// Procedura interna effettiva di grant level x utente
/// </summary>
/// <param name="username"></param>
/// <param name="domain"></param>
/// <param name="grantLevel"></param>
/// <returns></returns>
private bool doGrantPriv(string username, string domain, string grantLevel)
{
bool answ = false;
string sqlCommand = "FLUSH PRIVILEGES;";
adbCtx.Database.ExecuteSqlCommand(System.Data.Entity.TransactionalBehavior.DoNotEnsureTransaction, sqlCommand);
Thread.Sleep(100);
sqlCommand = $"GRANT {grantLevel} TO '{username}'@'{domain}';";
adbCtx.Database.ExecuteSqlCommand(System.Data.Entity.TransactionalBehavior.DoNotEnsureTransaction, sqlCommand);
Thread.Sleep(100);
sqlCommand = "FLUSH PRIVILEGES;";
adbCtx.Database.ExecuteSqlCommand(System.Data.Entity.TransactionalBehavior.DoNotEnsureTransaction, sqlCommand);
Thread.Sleep(100);
answ = true;
return answ;
}
#endregion Private Methods
}
}