using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Text; using MySql.Data.MySqlClient; namespace BeWoFileExporter { internal class Program { private static MySqlConnection _MySqlConnection; private static string BwpRootFileDirectory { get; set; } /// /// Sucht alle Datenbanken nach Blobs in der Tabelle FileAttachment ab, exportiert diese in das BWP-File-Verzeichnis und löscht den Blob aus der Datenbank. /// /// Enthält Kundennummern. Wenn keine Übergeben wird, werden alle Datenbanken auf dem Server durchgegangen. /// Hat die Position 0 den Wert 'm', wird nach der Kundennummer gefragt. private static void Main(string[] args) { try { var selectedTenants = new List(); BwpRootFileDirectory = Utils.GetFileRootDirectoryPath(); var configPath = Utils.GetMultitenancyDirectoryPath(); //#if DEBUG // BwpRootFileDirectory = @"C:\BWP-Files"; // configPath = @"C:\Users\lyndo\BeWo\Host\Multitenancy"; //#endif // Prüfen, ob die Kundennummer abgefragt werden soll: if(args.Length > 0 && args[0] == "m") { string tenants = null; while(tenants == null) { Console.Write("Kundennummer (mehrere durch Komma trennen): "); tenants = Console.ReadLine(); if(tenants != null) { var tenantList = tenants.Split(','); selectedTenants = tenantList.ToList().Select(s => s.Trim()).ToList(); } } } else { if(args.Length > 0) { // Kann durch Kommata getrennt sein var tenants = args[0]; if(tenants != null) { var tenantList = tenants.Split(','); selectedTenants = tenantList.ToList(); } } } var configFileNames = selectedTenants.Select(tenant => $"{tenant}.config").ToList(); var configFiles = Directory.EnumerateFiles(configPath).Where(filePath => { var fileName = Path.GetFileName(filePath); var isSelected = !configFileNames.Any(); if(configFileNames.Count > 0) { isSelected = configFileNames.Contains(fileName); } return filePath.EndsWith(".config") && isSelected; }).ToList(); var connections = GetConnectionObjects(configFiles).ToList(); var datenbankplural = connections.Count != 1 ? "en" : string.Empty; Console.WriteLine($"Exportiere Dateien aus {connections.Count} Datenbank{datenbankplural}\n"); foreach(var connection in connections) { _MySqlConnection = new MySqlConnection(connection.ToMySqlConnectionString()); ExtractFiles(connection); } } catch(Exception exception) { Console.WriteLine(exception); } finally { if(_MySqlConnection != null) { CloseConnection(); } Console.Read(); } } private static bool OpenConnection() { try { _MySqlConnection.Open(); return true; } catch(MySqlException exception) { Console.WriteLine($"Fehler: {exception}\n"); return false; } } private static IEnumerable GetConnectionObjects(IEnumerable configFiles) { var connections = new List(); foreach(var configFile in configFiles) { var connectionString = Utils.GetConnectionStringFromConfigFile(configFile)?.Trim(); if(connectionString != null && connectionString.Contains("Server=") && connectionString.Contains("Password=") && connectionString.Contains("User ID=") && connectionString.Contains("Initial Catalog=")) { var server = Utils.GetConnectionStringValue("Server", connectionString); var password = Utils.GetConnectionStringValue("Password", connectionString); var uid = Utils.GetConnectionStringValue("User ID", connectionString); var database = Utils.GetConnectionStringValue("Initial Catalog", connectionString); connections.Add(new Connection(server, uid, database, password)); } } return connections; } private static void ExtractFiles(Connection connection) { _MySqlConnection = new MySqlConnection(connection.ToMySqlConnectionString()); try { if(OpenConnection()) { LoadFileAttachmentData(connection.Database); } } catch(Exception exception) { Console.WriteLine(exception+ "\n"); } finally { CloseConnection(); } } private static void LoadFileAttachmentData(string connectionDatabase) { const string queryString = "SELECT Oid, Data FROM fileattachment WHERE Data IS NOT NULL;"; if(_MySqlConnection.State == ConnectionState.Open) { var mySqlCommand = new MySqlCommand(queryString, _MySqlConnection); var reader = mySqlCommand.ExecuteReader(); var fileAttachments = new List(); while(reader.Read()) { var data = reader["Data"]; var oid = reader["Oid"]; if(data == null || oid == null) { continue; } if(data is byte[] byteArray && long.TryParse(oid.ToString(), out var fileAttachmentOid)) { var tenant = connectionDatabase; fileAttachments.Add(new FileAttachment(fileAttachmentOid, tenant, byteArray)); } } reader.Close(); var fileCount = fileAttachments.Count; var word = fileCount > 1 ? $"{fileCount} Dateien werden exportiert" : fileCount == 0 ? "Keine Dateien exportiert" : "Eine Datei wird exportiert"; Console.WriteLine($"{connectionDatabase}: {word}\n"); SaveDataToDirectory(fileAttachments, connectionDatabase); } } private static void SaveDataToDirectory(IReadOnlyCollection fileAttachments, string connectionDatabase) { if(_MySqlConnection.State == ConnectionState.Open && fileAttachments?.Count > 0) { Utils.CheckForFileRootDirectory(connectionDatabase, BwpRootFileDirectory); var updateStringBuilder = new StringBuilder("UPDATE fileattachment SET Data = NULL WHERE Oid IN ("); var oidString = string.Empty; foreach(var fileAttachment in fileAttachments) { File.WriteAllBytes(Utils.GetFilePath(connectionDatabase, fileAttachment.Oid.ToString()), fileAttachment.Data); oidString += fileAttachment.Oid + ","; } updateStringBuilder.Append(oidString.TrimEnd(',')); updateStringBuilder.Append(");"); var updateCommand = new MySqlCommand(updateStringBuilder.ToString()) { Connection = _MySqlConnection }; updateCommand.ExecuteNonQuery(); } } private static void CloseConnection() { try { _MySqlConnection.Close(); } catch(MySqlException exception) { Console.WriteLine(exception+ "\n"); } } } }