using System; using System.Diagnostics; using System.IO; namespace SafeMobileLib { public static class DBInteraction { public static string safemobilePath = Utils.GetRegValue("Path", "SafeMobile"); public static string SafeMobilePath { get { return safemobilePath; } set { safemobilePath = value; } } /// /// /// /// ”host = 10.120.1.130 port = 5432 user = postgres dbname = safedispatchdb” public static bool RewindCommand(string connStr) { Process process = new Process(); ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.FileName = "cmd.exe"; startInfo.Verb = "runas"; startInfo.RedirectStandardInput = true; startInfo.RedirectStandardOutput = true; startInfo.UseShellExecute = false; process.StartInfo = startInfo; process.Start(); using (StreamWriter sw = process.StandardInput) { if (sw.BaseStream.CanWrite) { string appPath = safemobilePath + "\\postgresql\\pgsql\\bin"; string dbPath = safemobilePath + "\\postgresql\\SafeDB"; sw.WriteLine("pushd " + appPath); sw.WriteLine($"pg_rewind.exe –-target-pgdata= {dbPath} –-source-server= {connStr}"); } sw.Close(); } using (StreamReader reader = process.StandardOutput) { string output = reader.ReadToEnd(); process.WaitForExit(); if (output.Contains("Done!")) { Utils.WriteLine("RewindCommand: " + output, ConsoleColor.Magenta); return true; } return false; } } public static void ReceiveXlogCommand(string archive_folder, string slot_name, string connStr) { Process process = new Process(); ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.FileName = "cmd.exe"; startInfo.Verb = "runas"; startInfo.RedirectStandardInput = true; startInfo.RedirectStandardOutput = true; startInfo.UseShellExecute = false; process.StartInfo = startInfo; process.Start(); using (StreamWriter sw = process.StandardInput) { if (sw.BaseStream.CanWrite) { string appPath = safemobilePath + "\\postgresql\\pgsql\\bin"; sw.WriteLine("pushd " + appPath); sw.WriteLine($"pg_receivexlog.exe –-D {archive_folder} -v --slot= {slot_name} -d= {connStr} "); } sw.Close(); } using (StreamReader reader = process.StandardOutput) { string output = reader.ReadToEnd(); process.WaitForExit(); Utils.WriteLine("ReceiveXlogCommand: " + output, ConsoleColor.Magenta); } } public static void BaseBackup(string masterIP) { try { string extractPath = $"{safemobilePath}\\postgresql\\pgsql\\bin\\SafeDBMaster"; string SafeDbFolder = $"{safemobilePath}\\postgresql\\SafeDB"; if (Directory.Exists(extractPath)) Directory.Delete(extractPath, true); Process process = new Process(); ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.FileName = "cmd.exe"; startInfo.Verb = "runas"; startInfo.RedirectStandardInput = true; startInfo.RedirectStandardOutput = true; startInfo.UseShellExecute = false; process.StartInfo = startInfo; process.Start(); using (StreamWriter sw = process.StandardInput) { if (sw.BaseStream.CanWrite) { string appPath = safemobilePath + "\\postgresql\\pgsql\\bin"; sw.WriteLine("pushd " + appPath); sw.WriteLine($"pg_basebackup.exe -X stream -P -h {masterIP} -U postgres -D SafeDBMaster"); } sw.Close(); } using (StreamReader reader = process.StandardOutput) { string output = reader.ReadToEnd(); process.WaitForExit(); Utils.WriteLine("BaseBackup completed: " + output, ConsoleColor.Magenta); } // Get our files (recursive and any of them, based on the 2nd param of the Directory.GetFiles() method string[] originalFiles = Directory.GetFiles(extractPath, "*", SearchOption.AllDirectories); // Dealing with a string array, so let's use the actionable Array.ForEach() with a anonymous method Array.ForEach(originalFiles, (originalFileLocation) => { // Get the FileInfo for both of our files FileInfo originalFile = new FileInfo(originalFileLocation); FileInfo destFile = new FileInfo(originalFileLocation.Replace(extractPath, SafeDbFolder)); // ^^ We can fill the FileInfo() constructor with files that don't exist... // ... because we check it here if (destFile.Exists) { originalFile.CopyTo(destFile.FullName, true); } else // ... otherwise create any missing directories and copy the folder over { Directory.CreateDirectory(destFile.DirectoryName); // Does nothing on directories that already exist originalFile.CopyTo(destFile.FullName, true); // Copy but don't over-write } }); Utils.WriteLine("SafeDB folder was successfully updated!!! " + SafeDbFolder, ConsoleColor.DarkGreen); } catch (Exception ex) { Utils.WriteLine("Replication slot ERROR: " + ex.ToString(), ConsoleColor.Red); } } /// /// Creates a replication Slot in the database /// public static void CreateReplicationSlot() { try { Utils.WriteLine("Creating Replication Slot"); Process process = new Process(); ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.FileName = "cmd.exe"; startInfo.Verb = "runas"; startInfo.RedirectStandardInput = true; startInfo.RedirectStandardOutput = true; startInfo.UseShellExecute = false; process.StartInfo = startInfo; process.Start(); using (StreamWriter sw = process.StandardInput) { if (sw.BaseStream.CanWrite) { string appPath = safemobilePath + "\\postgresql\\pgsql\\bin"; sw.WriteLine("pushd " + appPath); sw.WriteLine("psql.exe -U postgres"); sw.WriteLine("SELECT * FROM pg_create_physical_replication_slot('replication_slot_node');"); sw.WriteLine("SELECT * FROM pg_replication_slots;"); } sw.Close(); } using (StreamReader reader = process.StandardOutput) { string output = reader.ReadToEnd(); process.WaitForExit(); Utils.WriteLine("Replication Slot Created " + output, ConsoleColor.Magenta); } } catch (Exception ex) { Utils.WriteLine("Replication slot ERROR: " + ex.ToString(), ConsoleColor.Red); } } public static void DropReplicationSlot() { try { Utils.WriteLine("Dropping Replication Slot"); Process process = new Process(); ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.FileName = "cmd.exe"; startInfo.Verb = "runas"; startInfo.RedirectStandardInput = true; startInfo.RedirectStandardOutput = true; startInfo.UseShellExecute = false; process.StartInfo = startInfo; process.Start(); using (StreamWriter sw = process.StandardInput) { if (sw.BaseStream.CanWrite) { string appPath = safemobilePath + "\\postgresql\\pgsql\\bin"; sw.WriteLine("pushd " + appPath); sw.WriteLine("psql.exe -U postgres"); sw.WriteLine("select pg_drop_replication_slot('replication_slot_node');"); sw.WriteLine("SELECT * FROM pg_replication_slots;"); } sw.Close(); } using (StreamReader reader = process.StandardOutput) { string output = reader.ReadToEnd(); process.WaitForExit(); Utils.WriteLine("Replication Slot Deleted!!!! " + output, ConsoleColor.Magenta); } } catch (Exception ex) { Utils.WriteLine("Replication slot ERROR: " + ex.ToString(), ConsoleColor.Red); } } public static bool CheckExistingReplicationSlot() { try { Process process = new Process(); ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.FileName = "cmd.exe"; startInfo.Verb = "runas"; startInfo.RedirectStandardInput = true; startInfo.RedirectStandardOutput = true; startInfo.UseShellExecute = false; process.StartInfo = startInfo; process.Start(); using (StreamWriter sw = process.StandardInput) { if (sw.BaseStream.CanWrite) { string appPath = safemobilePath + "\\postgresql\\pgsql\\bin"; sw.WriteLine("pushd " + appPath); sw.WriteLine("psql.exe -U postgres"); sw.WriteLine("SELECT * FROM pg_replication_slots;"); } sw.Close(); } using (StreamReader reader = process.StandardOutput) { string output = reader.ReadToEnd(); process.WaitForExit(); //Utils.WriteLine("Replication Slot Created " + output, ConsoleColor.Magenta); if (output.Contains("replication_slot_node") == false) { return false; } else { return true; } } } catch (Exception ex) { Utils.WriteLine("Existing Replication slot ERROR: " + ex.ToString(), ConsoleColor.Red); return false; } } public static bool CheckReplicationIsActive() { try { Process process = new Process(); ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.FileName = "cmd.exe"; startInfo.Verb = "runas"; startInfo.RedirectStandardInput = true; startInfo.RedirectStandardOutput = true; startInfo.UseShellExecute = false; process.StartInfo = startInfo; process.Start(); using (StreamWriter sw = process.StandardInput) { if (sw.BaseStream.CanWrite) { string appPath = safemobilePath + "\\postgresql\\pgsql\\bin"; sw.WriteLine("pushd " + appPath); sw.WriteLine("psql.exe -U postgres"); sw.WriteLine("SELECT * FROM pg_replication_slots;"); } sw.Close(); } using (StreamReader reader = process.StandardOutput) { string output = reader.ReadToEnd(); process.WaitForExit(); if (output.Contains(" | t |") == false) { return false; } else { return true; } } } catch (Exception ex) { Utils.WriteLine("Replication slot ERROR: " + ex.ToString(), ConsoleColor.Red); return false; } } public static void CheckDelay() { try { Process process = new Process(); ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.WindowStyle = ProcessWindowStyle.Maximized; startInfo.FileName = "cmd.exe"; startInfo.Verb = "runas"; startInfo.RedirectStandardInput = true; startInfo.RedirectStandardOutput = true; startInfo.UseShellExecute = false; process.StartInfo = startInfo; process.Start(); using (StreamWriter sw = process.StandardInput) { if (sw.BaseStream.CanWrite) { string appPath = safemobilePath + "\\postgresql\\pgsql\\bin"; sw.WriteLine("pushd " + appPath); sw.WriteLine("psql.exe -U postgres"); sw.WriteLine("select case when pg_last_xlog_receive_location() = pg_last_xlog_replay_location() then 0 else extract (epoch from now() - pg_last_xact_replay_timestamp()) end as log_delay;"); } sw.Close(); } using (StreamReader file = process.StandardOutput) { int counter = 0; bool writeNextLine = false; string line; // Read the file and display it line by line. while ((line = file.ReadLine()) != null) { if (writeNextLine) { Utils.WriteLine(line.Trim().ToString() + " seconds delay from Master server"); } writeNextLine = line.Contains("-----------"); counter++; } file.Close(); } } catch (Exception ex) { Utils.WriteLine("Check Delay ERROR: " + ex.ToString(), ConsoleColor.Red); } } } }