/// /// Copyright (c) 2013-2020 Sensus Slovensko a.s. /// using System; using System.Drawing; using System.IO; using System.Windows.Forms; using log4net; using Common; using TBF.Resources; namespace TBF.UI.Settings { /// /// Dialog to process test bench name and database settings (BenchSettings) /// public partial class DatabaseSettingsDlg : Form { static readonly ILog log = LogManager.GetLogger(typeof(DatabaseSettingsDlg)); const string CredFileName = "tempfile"; // Reference to bench DB settins (not a local copy) DatabaseSettings bench; string currentConfigDBConnStr; /// Initialized in constructor by the parent string currentResultsDBConnStr; /// Initialized in constructor by the parent string currentEventsDBConnStr; /// Initialized in constructor by the parent public bool CurrentDBChanged; /// Set when a current database is modified (erased or imported) /// /// Constructor /// /// Test bench database settings public DatabaseSettingsDlg(DatabaseSettings bench, string currentConfigDBConnStr, string currentResultsDBConnStr, string currentEventsDBConnStr) { this.bench = bench; this.currentConfigDBConnStr = currentConfigDBConnStr; this.currentResultsDBConnStr = currentResultsDBConnStr; this.currentEventsDBConnStr = currentEventsDBConnStr; CurrentDBChanged = false; InitializeComponent(); } void Localize() { Text = Strings.Test_Bench_Databases_Specification; label1.Text = Strings.Test_bench_name; realBenchCheckBox.Text = Strings.Test_bench_is_controlled_by_this_computer; dbTypeLabel.Text = Strings.Database_type; connectionStringLabel.Text = Strings.Connection_string; configLabel.Text = Strings.Configuration; resultsLabel.Text = Strings.Results; usersLabel.Text = Strings.Users; testConnConfigDbBtn.Text = Strings.Test_connection; testConnResultsDbBtn.Text = Strings.Test_connection; testConnEventsDbBtn.Text = Strings.Test_connection; testConnUsersDbBtn.Text = Strings.Test_connection; createConfigDbBtn.Text = Strings.Create_DB; createResultsDbBtn.Text = Strings.Create_DB; createEventsDbBtn.Text = Strings.Create_DB; importConfigDbBtn.Text = Strings.Import_DB; importResultsDbBtn.Text = Strings.Import_DB; importEventsDbBtn.Text = Strings.Import_DB; okButton.Text = Strings.OkBtnText; cancelButton.Text = Strings.CancelBtnText; } private void BenchSettingsDlg_Load(object sender, EventArgs e) { Localize(); benchNameTextBox.Text = bench.BenchName; realBenchCheckBox.Checked = bench.IsRealBench; /// Initialize 'Database type' combo-boxes for (int i = 0; i < (int)DBType.Count; i++) { DBType dbType = (DBType)i; configDbTypeComboBox.Items.Add(dbType); resultsDbTypeComboBox.Items.Add(dbType); eventsDbTypeComboBox.Items.Add(dbType); usersDbTypeComboBox.Items.Add(dbType); } configDbTypeComboBox.SelectedIndex = (int)bench.ProceduresDBSettings.DbType; resultsDbTypeComboBox.SelectedIndex = (int)bench.WaterMetersDBSettings.DbType; eventsDbTypeComboBox.SelectedIndex = (int)bench.EventsDBSettings.DbType; usersDbTypeComboBox.SelectedIndex = (int)bench.UsersDBSettings.DbType; /// Initialize connection strings configDbConnectionStringTextBox.Text = bench.ProceduresDBSettings.ConnectionString; resultsDbConnectionStringTextBox.Text = bench.WaterMetersDBSettings.ConnectionString; eventsDbConnectionStringTextBox.Text = bench.EventsDBSettings.ConnectionString; usersDbConnectionStringTextBox.Text = bench.UsersDBSettings.ConnectionString; } bool UpdateBenchFromUIControls() { /// TODO: The following code doesnot work as expected - error message shown! //for (int i = 0; i < Program.LocalSettings.BenchesCount; i++) //{ // if (bench != Program.LocalSettings.TestBenches[i] && // benchNameTextBox.Text == Program.LocalSettings.TestBenches[i].BenchName) // { // MessageBox.Show(Strings.Bench_name_conflict_Use_another_name_pls, Strings.Error, MessageBoxButtons.OK); // return false; // } //} bench.BenchName = benchNameTextBox.Text; bench.IsRealBench = realBenchCheckBox.Checked; bench.ProceduresDBSettings.ConnectionString = configDbConnectionStringTextBox.Text; bench.WaterMetersDBSettings.ConnectionString = resultsDbConnectionStringTextBox.Text; bench.EventsDBSettings.ConnectionString = eventsDbConnectionStringTextBox.Text; bench.UsersDBSettings.ConnectionString = usersDbConnectionStringTextBox.Text; bench.ProceduresDBSettings.DbType = (DBType)configDbTypeComboBox.SelectedIndex; bench.WaterMetersDBSettings.DbType = (DBType)resultsDbTypeComboBox.SelectedIndex; bench.EventsDBSettings.DbType = (DBType)eventsDbTypeComboBox.SelectedIndex; bench.UsersDBSettings.DbType = (DBType)usersDbTypeComboBox.SelectedIndex; return true; } /// /// Update bench DB setting, return 'OK' /// /// Not used /// Not used private void okButton_Click(object sender, EventArgs e) { if (UpdateBenchFromUIControls()) { DialogResult = DialogResult.OK; Close(); return; } DialogResult = DialogResult.None; } /// /// Throw away changes, return 'Cancel' /// /// Not used /// Not used private void cancelButton_Click(object sender, EventArgs e) { DialogResult = DialogResult.Cancel; Close(); } private void testConnConfigDbBtn_Click(object sender, EventArgs e) { } private void testConnResultsDbBtn_Click(object sender, EventArgs e) { } private void testConnEventsDbBtn_Click(object sender, EventArgs e) { } private void testConnUsersDbBtn_Click(object sender, EventArgs e) { } private void createConfigDbBtn_Click(object sender, EventArgs e) { /// Update database connection strings if (!UpdateBenchFromUIControls()) return; if (DialogResult.OK == MessageBox.Show(Strings.DB_will_be_overwritten + Environment.NewLine + Strings.Do_you_want_to_proceed, Strings.Warning, MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation)) { try { string connectionString = bench.ProceduresDBSettings.ConnectionString; string databaseName = Config.Utils.GetDBName(connectionString); string userName = Config.Utils.GetDBUser(connectionString); string password = Config.Utils.GetDBPassword(connectionString); /// TODO: Use password if (connectionString == currentConfigDBConnStr || connectionString == currentResultsDBConnStr || connectionString == currentEventsDBConnStr) { CurrentDBChanged = true; } Cursor.Current = Cursors.WaitCursor; log.ErrorFormat("Going to create an empty configuration database '{0}'", databaseName); ExecuteMySqlCmd(string.Format("DROP DATABASE `{0}`;", databaseName), userName, password); ExecuteMySqlCmd(string.Format("CREATE DATABASE `{0}` CHARACTER SET utf8 COLLATE utf8_unicode_ci;", databaseName), userName, password); TBF.DB.CreateEmptyConfigDB(bench.ProceduresDBSettings.DbType, connectionString); log.ErrorFormat("An empty configuration database '{0}' was created", databaseName); MessageBox.Show(Strings.DB_was_successfully_created, Strings.Notification); Cursor.Current = Cursors.Default; DialogResult = DialogResult.None; } catch (Exception exception) { if (File.Exists(CredFileName)) File.Delete(CredFileName); Cursor.Current = Cursors.Default; string msg = string.Format("{0}{1}{2}", Strings.Error_while_creating_DB_Reason, Environment.NewLine, exception.Message); if (exception.InnerException != null) { msg += Environment.NewLine + exception.InnerException.Message; } MessageBox.Show(msg, Strings.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); } } } private void createResultsDbBtn_Click(object sender, EventArgs e) { /// Update database connection strings if (!UpdateBenchFromUIControls()) return; if (DialogResult.OK == MessageBox.Show(Strings.DB_will_be_overwritten + Environment.NewLine + Strings.Do_you_want_to_proceed, Strings.Warning, MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation)) { try { string connectionString = bench.WaterMetersDBSettings.ConnectionString; string databaseName = Config.Utils.GetDBName(connectionString); string userName = Config.Utils.GetDBUser(connectionString); string password = Config.Utils.GetDBPassword(connectionString); /// TODO: Use password if (connectionString == currentConfigDBConnStr || connectionString == currentResultsDBConnStr || connectionString == currentEventsDBConnStr) { CurrentDBChanged = true; } Cursor.Current = Cursors.WaitCursor; log.ErrorFormat("Going to create an empty results database '{0}'", databaseName); ExecuteMySqlCmd(string.Format("DROP DATABASE `{0}`;", databaseName), userName, password); ExecuteMySqlCmd(string.Format("CREATE DATABASE `{0}` CHARACTER SET utf8 COLLATE utf8_unicode_ci;", databaseName), userName, password); global::Results.DB.DbType = bench.WaterMetersDBSettings.DbType; global::Results.DB.ConnectionString = connectionString; global::Results.DB.CreateEmptyDB(); log.ErrorFormat("An empty results database '{0}' was created", databaseName); MessageBox.Show(Strings.DB_was_successfully_created, Strings.Notification); Cursor.Current = Cursors.Default; DialogResult = DialogResult.None; } catch (Exception exception) { if (File.Exists(CredFileName)) File.Delete(CredFileName); Cursor.Current = Cursors.Default; string msg = string.Format("{0}{1}{2}", Strings.Error_while_creating_DB_Reason, Environment.NewLine, exception.Message); if (exception.InnerException != null) { msg += Environment.NewLine + exception.InnerException.Message; } MessageBox.Show(msg, Strings.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); } } } private void createEventsDbBtn_Click(object sender, EventArgs e) { /// Update database connection strings if (!UpdateBenchFromUIControls()) return; if (DialogResult.OK == MessageBox.Show(Strings.DB_will_be_overwritten + Environment.NewLine + Strings.Do_you_want_to_proceed, Strings.Warning, MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation)) { try { MessageBox.Show("Not implemented yet"); //string connectionString = bench.EventsDBSettings.ConnectionString; //string databaseName = Config.Utils.GetDBName(connectionString); //string userName = Config.Utils.GetDBUser(connectionString); //string password = Config.Utils.GetDBPassword(connectionString); /// TODO: Use password //if (connectionString == currentConfigDBConnStr || connectionString == currentResultsDBConnStr || connectionString == currentEventsDBConnStr) //{ // CurrentDBChanged = true; //} //Cursor.Current = Cursors.WaitCursor; //log.ErrorFormat("Going to create an empty events database '{0}'", databaseName); //ExecuteMySqlCmd(string.Format("DROP DATABASE `{0}`;", databaseName), userName, password); //ExecuteMySqlCmd(string.Format("CREATE DATABASE `{0}` CHARACTER SET utf8 COLLATE utf8_unicode_ci;", databaseName), userName, password); //global::Events.DB.DbType = (DBType)bench.EventsDBSettings.DbType; //global::Events.DB.ConnectionString = connectionString; //global::Events.DB.CreateEmptyDB(); //log.ErrorFormat("An empty events database '{0}' was created", databaseName); //MessageBox.Show(Strings.DB_was_successfully_created, Strings.Notification); //Cursor.Current = Cursors.Default; //DialogResult = DialogResult.None; } catch (Exception exception) { if (File.Exists(CredFileName)) File.Delete(CredFileName); Cursor.Current = Cursors.Default; string msg = string.Format("{0}{1}{2}", Strings.Error_while_creating_DB_Reason, Environment.NewLine, exception.Message); if (exception.InnerException != null) { msg += Environment.NewLine + exception.InnerException.Message; } MessageBox.Show(msg, Strings.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); } } } /// /// Configuration database import (UI) /// private void importConfigDbBtn_Click(object sender, EventArgs e) { /// Update database connection strings from UI if (!UpdateBenchFromUIControls()) return; string connectionString = bench.ProceduresDBSettings.ConnectionString; string server = Config.Utils.GetDBServer(connectionString); if ((server != "localhost") && (server != "127.0.0.1")) { MessageBox.Show(Strings.Remote_database_cannot_be_imported, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } OpenFileDialog dlg = new OpenFileDialog(); dlg.InitialDirectory = string.Format(@"C:\TBF\DbBackups\"); if (dlg.ShowDialog() == DialogResult.OK) { if (MessageBox.Show(string.Format(Strings.Do_you_want_to_restore_configuration_DB_from_file_0_qm, dlg.FileName), string.Empty, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { DBImportMessageStart("Importing database with configuration"); ImportDatabase(connectionString, dlg.FileName); DBImportMessageEnd(); } } } /// /// Results database import (UI) /// private void importResultsDbBtn_Click(object sender, EventArgs e) { /// Update database connection strings from UI if (!UpdateBenchFromUIControls()) return; string connectionString = bench.WaterMetersDBSettings.ConnectionString; string server = Config.Utils.GetDBServer(connectionString); if ((server != "localhost") && (server != "127.0.0.1")) { MessageBox.Show(Strings.Remote_database_cannot_be_imported, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } OpenFileDialog dlg = new OpenFileDialog(); dlg.InitialDirectory = string.Format(@"C:\TBF\DbBackups\"); if (dlg.ShowDialog() == DialogResult.OK) { if (MessageBox.Show(string.Format(Strings.Do_you_want_to_restore_results_DB_from_file_0_qm, dlg.FileName), string.Empty, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { DBImportMessageStart("Importing DB with Results"); ImportDatabase(connectionString, dlg.FileName); DBImportMessageEnd(); } } } private void importEventsDbBtn_Click(object sender, EventArgs e) { /// Update database connection strings from UI if (!UpdateBenchFromUIControls()) return; string connectionString = bench.EventsDBSettings.ConnectionString; string server = Config.Utils.GetDBServer(connectionString); if ((server != "localhost") && (server != "127.0.0.1")) { MessageBox.Show(Strings.Remote_database_cannot_be_imported, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } OpenFileDialog dlg = new OpenFileDialog(); dlg.InitialDirectory = string.Format(@"C:\TBF\DbBackups\"); if (dlg.ShowDialog() == DialogResult.OK) { if (MessageBox.Show(string.Format(Strings.Do_you_want_to_restore_events_DB_from_file_0_qm, dlg.FileName), string.Empty, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { DBImportMessageStart("Importing DB with Events"); ImportDatabase(connectionString, dlg.FileName); DBImportMessageEnd(); } } } Shared.ModelessActivityForm form; System.Threading.Thread formThread; /// void DBImportMessageStart(string message) { form = new Shared.ModelessActivityForm() { Message = message, FontFamily = "Arial", FontSize = 24, FontStyle = FontStyle.Regular, BackgroundColor = Color.RoyalBlue, }; formThread = new System.Threading.Thread(() => form.ShowDialog()); formThread.Start(); } /// void DBImportMessageEnd() { if (form != null && formThread != null) { form.CloseForm(null, new EventArgs()); formThread.Join(); } form = null; formThread = null; } /// /// Database import (functionality) /// Invokes: /// mysql -u[userName] --default-character-set=utf8 --database [databaseName] /// SOURCE {SQL file name] /// /// DB connection string /// Output file name void ImportDatabase(string connectionString, string inputFileName) { string databaseName = Config.Utils.GetDBName(connectionString); string userName = Config.Utils.GetDBUser(connectionString); string password = Config.Utils.GetDBPassword(connectionString); /// TODO: Use password try { if (connectionString == currentConfigDBConnStr || connectionString == currentResultsDBConnStr || connectionString == currentEventsDBConnStr) { CurrentDBChanged = true; } log.ErrorFormat("Going to import database '{0}' from file {1}", databaseName, inputFileName); ExecuteMySqlCmd(string.Format("DROP DATABASE `{0}`;", databaseName), userName, password); ExecuteMySqlCmd(string.Format("CREATE DATABASE `{0}` CHARACTER SET utf8 COLLATE utf8_unicode_ci;", databaseName), userName, password); ExecuteMySqlCmd(string.Format("SOURCE {0}", inputFileName), userName, password, databaseName); log.ErrorFormat("Database {0} was imported from file {1}", databaseName, inputFileName); } catch (Exception exc) { if (File.Exists(CredFileName)) File.Delete(CredFileName); log.FatalFormat("Failed to import database '{0}' from file {1}: {2}", databaseName, inputFileName, exc.Message); } } /// /// Execute a MySQL command line command without specifying a database /// /// MySQL command /// User name void ExecuteMySqlCmd(string command, string userName, string password) { ExecuteMySqlCmd(command, userName, password, null); } /// /// Execute a MySQL command line command, specify database to be used /// /// MySQL command /// User name /// Database name void ExecuteMySqlCmd(string command, string userName, string password, string databaseToBeUsed) { using (TextWriter writer = new StreamWriter(CredFileName)) { writer.WriteLine("[client]"); writer.WriteLine(string.Format("password=\"{0}\"", password)); } System.Diagnostics.Process proc = new System.Diagnostics.Process(); proc.StartInfo.FileName = @"C:\xampp\mysql\bin\mysql.exe"; if (string.IsNullOrEmpty(databaseToBeUsed)) { proc.StartInfo.Arguments = string.Format("--defaults-file={0} --user={1} --host=localhost --protocol=tcp --port=3306 --default-character-set=utf8", CredFileName, userName); } else { proc.StartInfo.Arguments = string.Format("--defaults-file={0} --user={1} --host=localhost --protocol=tcp --port=3306 --default-character-set=utf8 --database={2}", CredFileName, userName, databaseToBeUsed); } proc.StartInfo.UseShellExecute = false; /// Must be false to redirect standard input or standard output proc.StartInfo.RedirectStandardOutput = false; proc.StartInfo.RedirectStandardInput = true; proc.StartInfo.CreateNoWindow = false; //proc.StartInfo.Verb = "runas"; /// To run mysql.exe as administrator proc.Start(); proc.StandardInput.WriteLine(command); System.Diagnostics.Debug.WriteLine(command); log.Warn(command); proc.StandardInput.WriteLine("exit"); proc.WaitForExit(); File.Delete(CredFileName); } } }