using NLog; using System; using System.Linq; using System.Threading; namespace EgtBEAMWALL.DataLayer.Controllers { public class DbController : IDisposable { #region Public Fields /// /// Singleton gestione /// 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 /// /// Verifica necessità creazione utente (locale o in rete) /// /// /// /// /// 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; } /// /// Migrazione esplicita del DB da parte dell'admin controller /// /// public bool checkMigrateDb() { return adbCtx.SetUpDbConnectionAndDbConfig(); } public void Dispose() { // Clear database context adbCtx.Dispose(); } /// /// Verifica esistenza views + utente relativo eventualmente ricreandole + fornendo accesso /// all'utente ReadOnly Essetre /// /// /// /// /// 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; } /// /// ATTENZIONE!!!! Procedura di Reset del DB /// /// public bool ResetDb() { bool answ = false; try { adbCtx .Database .SqlQuery("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; /// /// Istanza logger /// private NLog.Logger Log = NLog.LogManager .Setup() .LoadConfigurationFromFile(DbConfig.NLOG_PATH + @"\NLog.config") .GetCurrentClassLogger(); #endregion Private Fields #region Private Methods /// /// Procedura interna effettiva di check utente ed eventuale creazione + grant level /// /// /// /// /// /// Force = esegue un drop prima... /// 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; } /// /// Procedura interna effettiva di grant level x utente /// /// /// /// /// 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 } }